Compare commits

..
1 Commits
Author SHA1 Message Date
Clifford Yapp 0d8b619114 See if we can use Config.cmake approach to find_package for zlib and png.
Depends on the bext zlib CMake logic being patched to provide the
necessary files.  Once this proves out, we should be able to avoid
patching a lot of bext dependency builds to add custom FindZLIB.cmake
and FindPNG.cmake modules - instead we can just make sure
CMAKE_FIND_PACKAGE_PREFER_CONFIG is set to ON.
2026-07-09 18:39:44 +00:00
2959 changed files with 225784 additions and 689598 deletions
-260
View File
@@ -1,260 +0,0 @@
name: Prepare bext dependencies
description: Restore a compatible bext production artifact or build the pinned revision.
inputs:
platform-channel:
description: Published bext platform channel.
required: true
source-dir:
description: Absolute path to the BRL-CAD source tree.
required: true
output-dir:
description: Absolute path where the bext dependency tree will be prepared.
required: true
build-type:
description: BRL-CAD build configuration that will consume the dependency tree.
required: false
default: Release
artifact-token:
description: Token with Actions read access to BRL-CAD/bext.
required: false
outputs:
bext-sha:
description: The bext revision in the prepared dependency tree.
value: ${{ steps.result.outputs.bext-sha }}
source:
description: Whether preparation used a production artifact, cache, or local build.
value: ${{ steps.result.outputs.source }}
runs:
using: composite
steps:
- name: Resolve bext production artifact
id: resolve
shell: bash
env:
BEXT_BUILD_TYPE: ${{ inputs.build-type }}
BEXT_CHANNEL: ${{ inputs.platform-channel }}
BRLCAD_SOURCE_DIR: ${{ inputs.source-dir }}
GH_TOKEN: ${{ inputs.artifact-token }}
run: |
set -uo pipefail
source_dir="$BRLCAD_SOURCE_DIR"
if command -v cygpath >/dev/null 2>&1; then
source_dir="$(cygpath -u "$source_dir")"
fi
required_sha="$(awk -F'[()]' '/^[[:space:]]*brlcad_bext_init\([0-9a-fA-F]{40}\)/ { print tolower($2) }' "$source_dir/CMakeLists.txt")"
if [[ ! "$required_sha" =~ ^[0-9a-f]{40}$ ]]; then
echo "Expected exactly one brlcad_bext_init(<sha>) call in $source_dir/CMakeLists.txt" >&2
exit 1
fi
repository='BRL-CAD/bext'
marker_name="bext-production-$required_sha"
marker_info="$(gh api "repos/$repository/actions/artifacts?name=$marker_name&per_page=100" \
--jq '[.artifacts[] | select(.expired == false and .name == "'"$marker_name"'")] | sort_by(.created_at) | last | select(. != null) | [.name, .workflow_run.id] | @tsv' 2>/dev/null)" || marker_info=''
selected_sha=''
run_id=''
if [[ -n "$marker_info" ]]; then
selected_sha="$required_sha"
IFS=$'\t' read -r _ run_id <<< "$marker_info"
echo "Found complete bext production artifacts for pinned revision $required_sha."
else
marker_info="$(gh api "repos/$repository/actions/artifacts?per_page=100" \
--jq '[.artifacts[] | select(.expired == false and (.name | test("^bext-production-[0-9a-f]{40}$")))] | sort_by(.created_at) | last | select(. != null) | [.name, .workflow_run.id] | @tsv' 2>/dev/null)" || marker_info=''
if [[ -n "$marker_info" ]]; then
IFS=$'\t' read -r latest_marker run_id <<< "$marker_info"
selected_sha="${latest_marker#bext-production-}"
comparison="$(gh api "repos/$repository/compare/$required_sha...$selected_sha" --jq '.status' 2>/dev/null)" || comparison=''
if [[ "$comparison" == 'ahead' || "$comparison" == 'identical' ]]; then
echo "::warning::Using newer successful bext revision $selected_sha instead of BRL-CAD's pinned revision $required_sha."
else
selected_sha=''
run_id=''
fi
fi
fi
artifact_ready=false
artifact_name=''
if [[ "$RUNNER_OS" == 'Windows' && "$BEXT_BUILD_TYPE" == 'Debug' ]]; then
echo 'Windows Debug requires a Debug bext build; skipping Release production artifacts.'
selected_sha=''
run_id=''
elif [[ -n "$selected_sha" ]]; then
artifact_name="bext-$BEXT_CHANNEL-$selected_sha"
artifact_count="$(gh api "repos/$repository/actions/runs/$run_id/artifacts?name=$artifact_name&per_page=100" \
--jq '[.artifacts[] | select(.expired == false and .name == "'"$artifact_name"'")] | length' 2>/dev/null)" || artifact_count=0
if [[ "$artifact_count" == '1' ]]; then
artifact_ready=true
else
selected_sha=''
run_id=''
artifact_name=''
fi
fi
cache_schema=1
image_version="${ImageVersion:-unknown}"
runner_arch="${RUNNER_ARCH:-unknown}"
fallback_cache_key="bext-$cache_schema-$BEXT_CHANNEL-$BEXT_BUILD_TYPE-$required_sha-$image_version-$runner_arch"
production_cache_key="bext-$cache_schema-$BEXT_CHANNEL-Release-$selected_sha"
if [[ "$artifact_ready" != 'true' ]]; then
echo "No compatible production artifact is available; using the cache/build fallback for $required_sha."
fi
echo "required-sha=$required_sha" >> "$GITHUB_OUTPUT"
echo "selected-sha=$selected_sha" >> "$GITHUB_OUTPUT"
echo "run-id=$run_id" >> "$GITHUB_OUTPUT"
echo "artifact-name=$artifact_name" >> "$GITHUB_OUTPUT"
echo "artifact-ready=$artifact_ready" >> "$GITHUB_OUTPUT"
echo "production-cache-key=$production_cache_key" >> "$GITHUB_OUTPUT"
echo "fallback-cache-key=$fallback_cache_key" >> "$GITHUB_OUTPUT"
- name: Restore production artifact cache
if: steps.resolve.outputs.artifact-ready == 'true'
id: production-cache
uses: actions/cache/restore@v6
with:
path: ${{ inputs.output-dir }}
key: ${{ steps.resolve.outputs.production-cache-key }}
- name: Download bext production artifact
if: steps.resolve.outputs.artifact-ready == 'true' && steps.production-cache.outputs.cache-hit != 'true'
id: download
shell: bash
env:
ARTIFACT_NAME: ${{ steps.resolve.outputs.artifact-name }}
BEXT_CHANNEL: ${{ inputs.platform-channel }}
BEXT_OUTPUT_DIR: ${{ inputs.output-dir }}
BEXT_RUN_ID: ${{ steps.resolve.outputs.run-id }}
GH_TOKEN: ${{ inputs.artifact-token }}
run: |
set -uo pipefail
output_dir="$BEXT_OUTPUT_DIR"
if command -v cygpath >/dev/null 2>&1; then
output_dir="$(cygpath -u "$output_dir")"
fi
download_dir="$RUNNER_TEMP/bext-download-$BEXT_RUN_ID-$BEXT_CHANNEL"
cmake -E rm -rf "$download_dir" "$output_dir"
cmake -E make_directory "$download_dir" "$output_dir"
ready=false
if gh run download "$BEXT_RUN_ID" --repo BRL-CAD/bext --name "$ARTIFACT_NAME" --dir "$download_dir"; then
archive="$download_dir/bext-$BEXT_CHANNEL.tar.gz"
if (cd "$output_dir" && cmake -E tar xzf "$archive") && \
[[ -d "$output_dir/install" && -d "$output_dir/noinstall" && -f "$output_dir/bext-install-manifest.json" ]]; then
ready=true
fi
fi
cmake -E rm -rf "$download_dir"
if [[ "$ready" != 'true' ]]; then
cmake -E rm -rf "$output_dir"
echo '::warning::Unable to download or validate the bext production artifact; using the pinned cache/build fallback.'
fi
echo "ready=$ready" >> "$GITHUB_OUTPUT"
- name: Restore fallback bext cache
if: steps.production-cache.outputs.cache-hit != 'true' && steps.download.outputs.ready != 'true'
id: fallback-cache
uses: actions/cache/restore@v6
with:
path: ${{ inputs.output-dir }}
key: ${{ steps.resolve.outputs.fallback-cache-key }}
- name: Build pinned bext revision
if: steps.production-cache.outputs.cache-hit != 'true' && steps.download.outputs.ready != 'true' && steps.fallback-cache.outputs.cache-hit != 'true'
shell: bash
env:
BEXT_BUILD_TYPE: ${{ inputs.build-type }}
BEXT_OUTPUT_DIR: ${{ inputs.output-dir }}
BEXT_SHA: ${{ steps.resolve.outputs.required-sha }}
run: |
set -euo pipefail
output_dir="$BEXT_OUTPUT_DIR"
if command -v cygpath >/dev/null 2>&1; then
output_dir="$(cygpath -u "$output_dir")"
fi
source_dir="$RUNNER_TEMP/bext-src"
build_dir="$RUNNER_TEMP/bext-build"
cleanup() {
cmake -E rm -rf "$source_dir" "$build_dir"
}
trap cleanup EXIT
cleanup
cmake -E rm -rf "$output_dir"
git clone --filter=blob:none https://github.com/BRL-CAD/bext.git "$source_dir"
git -C "$source_dir" -c advice.detachedHead=false checkout "$BEXT_SHA"
configure_args=(-S "$source_dir" -B "$build_dir" -G Ninja -DENABLE_ALL=ON -DGIT_SHALLOW_CLONE=ON "-DCMAKE_BUILD_TYPE=$BEXT_BUILD_TYPE" "-DCMAKE_INSTALL_PREFIX=$output_dir")
if [[ "$RUNNER_OS" == 'Windows' ]]; then
configure_args+=(-DCMAKE_C_COMPILER=cl.exe -DCMAKE_CXX_COMPILER=cl.exe)
elif [[ "$RUNNER_OS" == 'macOS' ]]; then
export CC=clang
export CXX=clang++
fi
cmake "${configure_args[@]}"
cmake --build "$build_dir" --config "$BEXT_BUILD_TYPE" --parallel 2
- name: Validate bext dependency tree
shell: bash
env:
BEXT_OUTPUT_DIR: ${{ inputs.output-dir }}
run: |
set -euo pipefail
output_dir="$BEXT_OUTPUT_DIR"
if command -v cygpath >/dev/null 2>&1; then
output_dir="$(cygpath -u "$output_dir")"
fi
[[ -d "$output_dir/install" && -d "$output_dir/noinstall" && -f "$output_dir/bext-install-manifest.json" ]]
tool="$output_dir/noinstall/bin/strclear"
if [[ "$RUNNER_OS" == 'Windows' ]]; then
[[ -f "$tool.exe" ]]
else
[[ -x "$tool" ]]
fi
- name: Save production artifact cache
if: steps.download.outputs.ready == 'true'
uses: actions/cache/save@v6
with:
path: ${{ inputs.output-dir }}
key: ${{ steps.resolve.outputs.production-cache-key }}
- name: Save fallback bext cache
if: steps.production-cache.outputs.cache-hit != 'true' && steps.download.outputs.ready != 'true' && steps.fallback-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@v6
with:
path: ${{ inputs.output-dir }}
key: ${{ steps.resolve.outputs.fallback-cache-key }}
- name: Report bext source
id: result
shell: bash
env:
ARTIFACT_READY: ${{ steps.resolve.outputs.artifact-ready }}
ARTIFACT_SHA: ${{ steps.resolve.outputs.selected-sha }}
DOWNLOAD_READY: ${{ steps.download.outputs.ready }}
FALLBACK_CACHE_HIT: ${{ steps.fallback-cache.outputs.cache-hit }}
PRODUCTION_CACHE_HIT: ${{ steps.production-cache.outputs.cache-hit }}
REQUIRED_SHA: ${{ steps.resolve.outputs.required-sha }}
run: |
if [[ "$PRODUCTION_CACHE_HIT" == 'true' ]]; then
source=production-cache
elif [[ "$DOWNLOAD_READY" == 'true' ]]; then
source=production-artifact
elif [[ "$FALLBACK_CACHE_HIT" == 'true' ]]; then
source=fallback-cache
else
source=local-build
fi
if [[ "$ARTIFACT_READY" == 'true' && ( "$PRODUCTION_CACHE_HIT" == 'true' || "$DOWNLOAD_READY" == 'true' ) ]]; then
sha="$ARTIFACT_SHA"
else
sha="$REQUIRED_SHA"
fi
echo "source=$source" >> "$GITHUB_OUTPUT"
echo "bext-sha=$sha" >> "$GITHUB_OUTPUT"
echo "Prepared bext $sha from $source."
+389 -258
View File
@@ -1,8 +1,9 @@
# BRL-CAD's primary distcheck target runs too long and does too much work to
# be suitable as a CI target, even occasionally. To achieve essentially the
# same result, we define individual jobs for each distcheck sub-target and
# distribute them across five serial queues. To avoid the target list going
# stale, this header is followed by jobs generated from the CMake logic.
# run them in singletons. To avoid the list of targets going stale, we
# define this header and then autogenerate the actual build target jobs
# to append to it from the CMake logic.
name: Distcheck
@@ -13,14 +14,21 @@ on:
jobs:
bext:
name: Prepare bext
runs-on: ubuntu-24.04
name: Prepare bext (cached)
runs-on: ubuntu-latest
env:
DEBIAN_FRONTEND: noninteractive
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -37,30 +45,54 @@ jobs:
sudo apt-get install libgl-dev
sudo apt-get install libinput-dev
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Clone bext
run: git clone https://github.com/BRL-CAD/bext.git
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
- name: Get bext commit SHA
id: bext-sha
run: |
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Compute bext cache discriminator
id: cachekey
shell: bash
run: |
info="${{ steps.bext-sha.outputs.sha }}-$(uname -s)-$(uname -r)-$(gcc --version | head -n 1)"
echo "hash=$(echo -n "$info" | sha1sum | awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.cachekey.outputs.hash }}
- name: Build bext (if cache miss)
if: steps.cache-bext.outputs.cache-hit != 'true'
run: |
cmake -E make_directory bext_build
cmake -S bext -B bext_build -DCMAKE_BUILD_TYPE=Release -DENABLE_ALL=ON -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/bext_output
cmake --build bext_build --config Release -j 2
cmake -E rm -rf bext
cmake -E rm -rf bext_build
distcheck-default_build_type:
name: distcheck-default_build_type
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
needs: [bext]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -68,38 +100,52 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-default_build_type
- name: Configure
run: cmake -S brlcad -B build_distcheck-default_build_type -G Ninja -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output
run: cmake -S brlcad -B build_distcheck-default_build_type -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-default_build_type --target distcheck-default_build_type
run: cmake --build build_distcheck-default_build_type --config Release --target distcheck-default_build_type
- name: Log
if: always()
run: cat build_distcheck-default_build_type/distcheck-default_build_type.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
distcheck-debug:
name: distcheck-debug
runs-on: ubuntu-24.04
needs: [bext]
runs-on: ubuntu-latest
needs: [distcheck-default_build_type]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -107,38 +153,52 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-debug
- name: Configure
run: cmake -S brlcad -B build_distcheck-debug -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output
run: cmake -S brlcad -B build_distcheck-debug -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-debug --config Debug --target distcheck-debug
run: cmake --build build_distcheck-debug --config Release --target distcheck-debug
- name: Log
if: always()
run: cat build_distcheck-debug/distcheck-debug.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
distcheck-release:
name: distcheck-release
runs-on: ubuntu-24.04
needs: [bext]
runs-on: ubuntu-latest
needs: [distcheck-debug]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -146,116 +206,52 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-release
- name: Configure
run: cmake -S brlcad -B build_distcheck-release -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output
run: cmake -S brlcad -B build_distcheck-release -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-release --config Release --target distcheck-release
- name: Log
if: always()
run: cat build_distcheck-release/distcheck-release.log
distcheck-no_unity_debug:
name: distcheck-no_unity_debug
runs-on: ubuntu-24.04
needs: [bext]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Install apt dependencies
run: |
sudo apt-get update
sudo apt-get install xserver-xorg-dev libx11-dev libxi-dev libxext-dev libglu1-mesa-dev libfontconfig-dev
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-no_unity_debug
- name: Configure
run: cmake -S brlcad -B build_distcheck-no_unity_debug -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output -DBRLCAD_ENABLE_UNITY_BUILD=OFF
- name: Build
run: cmake --build build_distcheck-no_unity_debug --config Debug --target distcheck-no_unity_debug
- name: Log
if: always()
run: cat build_distcheck-no_unity_debug/distcheck-no_unity_debug.log
distcheck-no_unity_release:
name: distcheck-no_unity_release
runs-on: ubuntu-24.04
needs: [bext]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Install apt dependencies
run: |
sudo apt-get update
sudo apt-get install xserver-xorg-dev libx11-dev libxi-dev libxext-dev libglu1-mesa-dev libfontconfig-dev
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-no_unity_release
- name: Configure
run: cmake -S brlcad -B build_distcheck-no_unity_release -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output -DBRLCAD_ENABLE_UNITY_BUILD=OFF
- name: Build
run: cmake --build build_distcheck-no_unity_release --config Release --target distcheck-no_unity_release
- name: Log
if: always()
run: cat build_distcheck-no_unity_release/distcheck-no_unity_release.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
distcheck-enableall_debug:
name: distcheck-enableall_debug
runs-on: ubuntu-24.04
needs: [distcheck-default_build_type]
runs-on: ubuntu-latest
needs: [distcheck-release]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -263,38 +259,52 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-enableall_debug
- name: Configure
run: cmake -S brlcad -B build_distcheck-enableall_debug -G Ninja -DCMAKE_BUILD_TYPE=Debug -DENABLE_ALL=ON -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output
run: cmake -S brlcad -B build_distcheck-enableall_debug -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-enableall_debug --config Debug --target distcheck-enableall_debug
run: cmake --build build_distcheck-enableall_debug --config Release --target distcheck-enableall_debug
- name: Log
if: always()
run: cat build_distcheck-enableall_debug/distcheck-enableall_debug.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
distcheck-enableall_release:
name: distcheck-enableall_release
runs-on: ubuntu-24.04
needs: [distcheck-debug]
runs-on: ubuntu-latest
needs: [distcheck-enableall_debug]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -302,38 +312,52 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-enableall_release
- name: Configure
run: cmake -S brlcad -B build_distcheck-enableall_release -G Ninja -DCMAKE_BUILD_TYPE=Release -DENABLE_ALL=ON -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output
run: cmake -S brlcad -B build_distcheck-enableall_release -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-enableall_release --config Release --target distcheck-enableall_release
- name: Log
if: always()
run: cat build_distcheck-enableall_release/distcheck-enableall_release.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
distcheck-prepared_debug:
name: distcheck-prepared_debug
runs-on: ubuntu-24.04
needs: [distcheck-release]
runs-on: ubuntu-latest
needs: [distcheck-enableall_release]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -341,38 +365,52 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-prepared_debug
- name: Configure
run: cmake -S brlcad -B build_distcheck-prepared_debug -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output
run: cmake -S brlcad -B build_distcheck-prepared_debug -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-prepared_debug --config Debug --target distcheck-prepared_debug
run: cmake --build build_distcheck-prepared_debug --config Release --target distcheck-prepared_debug
- name: Log
if: always()
run: cat build_distcheck-prepared_debug/distcheck-prepared_debug.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
distcheck-prepared_release:
name: distcheck-prepared_release
runs-on: ubuntu-24.04
needs: [distcheck-no_unity_debug]
runs-on: ubuntu-latest
needs: [distcheck-prepared_debug]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -380,38 +418,52 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-prepared_release
- name: Configure
run: cmake -S brlcad -B build_distcheck-prepared_release -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output
run: cmake -S brlcad -B build_distcheck-prepared_release -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-prepared_release --config Release --target distcheck-prepared_release
- name: Log
if: always()
run: cat build_distcheck-prepared_release/distcheck-prepared_release.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
distcheck-no_tcl:
name: distcheck-no_tcl
runs-on: ubuntu-24.04
needs: [distcheck-no_unity_release]
runs-on: ubuntu-latest
needs: [distcheck-prepared_release]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -419,38 +471,52 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-no_tcl
- name: Configure
run: cmake -S brlcad -B build_distcheck-no_tcl -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output -DBRLCAD_ENABLE_TCL=OFF
run: cmake -S brlcad -B build_distcheck-no_tcl -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-no_tcl --config Debug --target distcheck-no_tcl
run: cmake --build build_distcheck-no_tcl --config Release --target distcheck-no_tcl
- name: Log
if: always()
run: cat build_distcheck-no_tcl/distcheck-no_tcl.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
distcheck-no_tk:
name: distcheck-no_tk
runs-on: ubuntu-24.04
needs: [distcheck-enableall_debug]
runs-on: ubuntu-latest
needs: [distcheck-no_tcl]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -458,38 +524,52 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-no_tk
- name: Configure
run: cmake -S brlcad -B build_distcheck-no_tk -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output -DBRLCAD_ENABLE_TK=OFF
run: cmake -S brlcad -B build_distcheck-no_tk -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-no_tk --config Debug --target distcheck-no_tk
run: cmake --build build_distcheck-no_tk --config Release --target distcheck-no_tk
- name: Log
if: always()
run: cat build_distcheck-no_tk/distcheck-no_tk.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
distcheck-no_strict:
name: distcheck-no_strict
runs-on: ubuntu-24.04
needs: [distcheck-enableall_release]
runs-on: ubuntu-latest
needs: [distcheck-no_tk]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -497,38 +577,52 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-no_strict
- name: Configure
run: cmake -S brlcad -B build_distcheck-no_strict -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output -DBRLCAD_ENABLE_STRICT=OFF
run: cmake -S brlcad -B build_distcheck-no_strict -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-no_strict --config Debug --target distcheck-no_strict
run: cmake --build build_distcheck-no_strict --config Release --target distcheck-no_strict
- name: Log
if: always()
run: cat build_distcheck-no_strict/distcheck-no_strict.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
distcheck-no_object:
name: distcheck-no_object
runs-on: ubuntu-24.04
needs: [distcheck-prepared_debug]
runs-on: ubuntu-latest
needs: [distcheck-no_strict]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -536,38 +630,52 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-no_object
- name: Configure
run: cmake -S brlcad -B build_distcheck-no_object -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output -DUSE_OBJECT_LIBS=OFF
run: cmake -S brlcad -B build_distcheck-no_object -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-no_object --config Debug --target distcheck-no_object
run: cmake --build build_distcheck-no_object --config Release --target distcheck-no_object
- name: Log
if: always()
run: cat build_distcheck-no_object/distcheck-no_object.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
distcheck-odd_pathnames:
name: distcheck-odd_pathnames
runs-on: ubuntu-24.04
needs: [distcheck-prepared_release]
runs-on: ubuntu-latest
needs: [distcheck-no_object]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -575,38 +683,52 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-odd_pathnames
- name: Configure
run: cmake -S brlcad -B build_distcheck-odd_pathnames -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output
run: cmake -S brlcad -B build_distcheck-odd_pathnames -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-odd_pathnames --config Debug --target distcheck-odd_pathnames
run: cmake --build build_distcheck-odd_pathnames --config Release --target distcheck-odd_pathnames
- name: Log
if: always()
run: cat build_distcheck-odd_pathnames/distcheck-odd_pathnames.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
distcheck-in_src_dir:
name: distcheck-in_src_dir
runs-on: ubuntu-24.04
needs: [distcheck-no_tcl]
runs-on: ubuntu-latest
needs: [distcheck-odd_pathnames]
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Install apt dependencies
run: |
sudo apt-get update
@@ -614,24 +736,33 @@ jobs:
sudo apt-get install astyle re2c
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev libgl-dev libinput-dev
- name: Setup - bext
run: |
git clone https://github.com/BRL-CAD/bext.git
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
cd ..
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.bext-sha.outputs.sha }}
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: cmake -E make_directory build_distcheck-in_src_dir
- name: Configure
run: cmake -S brlcad -B build_distcheck-in_src_dir -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output
run: cmake -S brlcad -B build_distcheck-in_src_dir -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
- name: Build
run: cmake --build build_distcheck-in_src_dir --config Debug --target distcheck-in_src_dir
run: cmake --build build_distcheck-in_src_dir --config Release --target distcheck-in_src_dir
- name: Log
if: always()
run: cat build_distcheck-in_src_dir/distcheck-in_src_dir.log
- name: Debug if failure
if: failure()
uses: mxschmitt/action-tmate@v3
+2 -2
View File
@@ -69,12 +69,12 @@ jobs:
- name: Configure
run: |
export PATH=$GITHUB_WORKSPACE:$PATH
export PATH=$ENV{GITHUB_WORKSPACE}:$PATH
cmake -S . -G Ninja -B build_linux -DBRLCAD_EXT_PARALLEL=1 -DBRLCAD_COMPONENTS=libged -DBRLCAD_EXTRADOCS=OFF
- name: Build
run: |
export PATH=$GITHUB_WORKSPACE:$PATH
export PATH=$ENV{GITHUB_WORKSPACE}:$PATH
cmake --build build_linux --config Release --target check
- name: Debugging - tmate session
+233 -163
View File
@@ -23,7 +23,7 @@ jobs:
linux:
name: Ubuntu GCC
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
strategy:
fail-fast: true
env:
@@ -33,6 +33,14 @@ jobs:
- name: Setup - CMake
uses: lukka/get-cmake@latest
# Cache apt package downloads (not installed pkgs)
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/push.yml') }}
# Install system dependencies
- name: Install apt dependencies
run: |
@@ -50,20 +58,44 @@ jobs:
sudo apt-get install libgl-dev
sudo apt-get install libinput-dev
# Prepare bext cache key
- name: Clone bext
run: git clone https://github.com/BRL-CAD/bext.git
- name: Get bext commit SHA
id: bext-sha
run: |
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Compute bext cache discriminator
id: cachekey
shell: bash
run: |
info="${{ steps.bext-sha.outputs.sha }}-$(uname -s)-$(uname -r)-$(gcc --version | head -n 1)"
echo "hash=$(echo -n "$info" | sha1sum | awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.cachekey.outputs.hash }}
- name: Build bext (if cache miss)
if: steps.cache-bext.outputs.cache-hit != 'true'
run: |
cmake -E make_directory bext_build
cmake -S bext -B bext_build -DCMAKE_BUILD_TYPE=Release -DENABLE_ALL=ON -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/bext_output
cmake --build bext_build --config Release -j 2
cmake -E rm -rf bext
cmake -E rm -rf bext_build
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: |
cmake -E make_directory ./build_linux
@@ -73,7 +105,7 @@ jobs:
- name: Configure
run: |
export PATH=$GITHUB_WORKSPACE:$PATH
cmake -S brlcad -B build_linux -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output -DBRLCAD_ENABLE_QT=ON
cmake -S brlcad -B build_linux -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output -DBRLCAD_ENABLE_QT=ON
- name: Build
id: build_parallel
@@ -94,7 +126,7 @@ jobs:
# repository integrity check and make sure we can build source archives.
archives:
name: Source Archives
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
needs: [linux]
strategy:
fail-fast: true
@@ -105,6 +137,13 @@ jobs:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/push.yml') }}
# Install system dependencies - we do the full setup here, even though
# source archives isn't intended to build the main BRL-CAD, in case
# this check is the one where the bext dependency cache check gets a miss.
@@ -126,83 +165,52 @@ jobs:
sudo apt-get install libgl-dev
sudo apt-get install libinput-dev
- name: Clone bext
run: git clone https://github.com/BRL-CAD/bext.git
- name: Get bext commit SHA
id: bext-sha
run: |
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Compute bext cache discriminator
id: cachekey
shell: bash
run: |
info="${{ steps.bext-sha.outputs.sha }}-$(uname -s)-$(uname -r)-$(gcc --version | head -n 1)"
echo "hash=$(echo -n "$info" | sha1sum | awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.cachekey.outputs.hash }}
- name: Build bext (if cache miss)
if: steps.cache-bext.outputs.cache-hit != 'true'
run: |
cmake -E make_directory bext_build
cmake -S bext -B bext_build -DCMAKE_BUILD_TYPE=Release -DENABLE_ALL=ON -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/bext_output
cmake --build bext_build --config Release -j2
rm -rf bext
rm -rf bext_build
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Build
run: |
cmake -E make_directory build_archives
cmake -S brlcad -B build_archives -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_PARALLEL=1 -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output
cmake -S brlcad -B build_archives -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_PARALLEL=1 -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output
cmake --build build_archives --config Release --target distcheck-source_archives
# A full bext build every time we push is too much, but we can exercise the
# basic bext mechanisms and also the BRLCAD_COMPONENTS subbuild at the same
# time if we do a local bext build of *just* the libbg subset of BRL-CAD. If
# the COMPONENTS mechanism works as it should it won't trigger a full bext
# build, and we'll only be compiling what libbg needs.
componentbext:
name: BRLCAD_COMPONENTS
runs-on: ubuntu-latest
strategy:
fail-fast: true
env:
DEBIAN_FRONTEND: noninteractive
if: github.event_name == 'push'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
# Install system dependencies - we do the full setup here, even though
# source archives isn't intended to build the main BRL-CAD, in case
# this check is the one where the bext dependency cache check gets a miss.
# In that case, this check will have to build bext to proceed - and it will
# need the bext environment set up to do so.
- name: Install apt dependencies
run: |
sudo apt-get update
# Install X/OpenGL dev pkgs
sudo apt-get install xserver-xorg-dev libx11-dev libxi-dev libxext-dev libglu1-mesa-dev libfontconfig-dev
# Install tools
sudo apt-get install astyle re2c xsltproc libxml2-utils
# Install dependency dev pkgs
sudo apt-get install zlib1g-dev libpng-dev libjpeg-dev libtiff-dev libeigen3-dev libgdal-dev libassimp-dev libopencv-dev tcl-dev tk-dev
# Install XCB/OpenGL dev pkgs for Qt - see:
# https://wiki.qt.io/Building_Qt_6_from_Git
# https://doc.qt.io/qt-6/linux-requirements.html
sudo apt-get install libfontconfig1-dev libfreetype6-dev libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libxcb-cursor-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxcb-xinput-dev libxcb-xrm-dev libxkbcommon-dev libxkbcommon-x11-dev
sudo apt-get install libgl-dev
sudo apt-get install libinput-dev
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Directory setup
run: |
cmake -E make_directory build_components
cmake -E make_directory $HOME/.cache
cmake -E make_directory $HOME/.cache/BRL-CAD
- name: Build
run: |
cmake -S brlcad -B build_components -DCMAKE_BUILD_TYPE=Release -DBRLCAD_COMPONENTS=libbg
cmake --build build_components --config Release
windows:
name: MSVC - Ninja
runs-on: windows-2025
runs-on: windows-latest
strategy:
fail-fast: true
if: github.event_name == 'push'
@@ -211,7 +219,7 @@ jobs:
uses: lukka/get-cmake@latest
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v3
uses: microsoft/setup-msbuild@v2
- name: Add cl.exe to PATH
uses: ilammy/msvc-dev-cmd@v1
@@ -220,27 +228,66 @@ jobs:
shell: pwsh
run: Add-Content -Path $env:GITHUB_PATH -Value $env:GITHUB_WORKSPACE
- name: Clone bext
# Note - this will not check out any of the submodules unless we need
# them for building, so it should be a very small disk space hit.
# Consequently, we don't worry about deleting it unless we end up
# having to build it. The bext source directory is not one of the
# cached directories, so a straight git clone is fine - no need to
# worry about colliding with a previous clone.
run: git clone https://github.com/BRL-CAD/bext.git
- name: Get bext commit SHA
id: bext-sha
shell: powershell
run: |
cd bext
echo "sha=$(git rev-parse HEAD)" >> $env:GITHUB_OUTPUT
- name: Compute bext cache discriminator
id: cachekey
shell: bash
run: |
clver=""
if command -v cl.exe &> /dev/null; then
clver="$(cl.exe 2>&1 | head -n 1)"
fi
info="${{ steps.bext-sha.outputs.sha }}-$(uname -s)-$(uname -r)-$clver"
echo "hash=$(echo -n "$info" | sha1sum | awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}\bext_output
key: windows-bext-${{ steps.cachekey.outputs.hash }}
- name: Build bext (if cache miss)
if: steps.cache-bext.outputs.cache-hit != 'true'
shell: powershell
run: |
cmake -E make_directory bext_build
cmake -S bext -B bext_build -DCMAKE_BUILD_TYPE=Release -DENABLE_ALL=ON -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}\bext_output
cmake --build bext_build --config Release -j2
# If we have had to build, the submodules are populated and the build
# directory will have a lot in it. We only need the build ouputs
# (bext_output) after this point, so clean up to save space for the
# main BRL-CAD build.
cmake -E rm -rf bext
cmake -E rm -rf bext_build
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: windows-2025-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Build Directory setup
run: cmake -E make_directory ./build_winninja
- name: Configure
shell: powershell
run: |
cmake -S brlcad -B build_winninja -G Ninja -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_CXX_COMPILER="cl.exe" -DBRLCAD_EXT_DIR=${{ runner.temp }}\bext_output -DCMAKE_BUILD_TYPE=Release -DBRLCAD_ENABLE_QT=ON
cmake -S brlcad -B build_winninja -G Ninja -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_CXX_COMPILER="cl.exe" -DBRLCAD_EXT_DIR=${{ github.workspace }}\bext_output -DCMAKE_BUILD_TYPE=Release -DBRLCAD_ENABLE_QT=ON
- name: Build
id: build_parallel
@@ -272,7 +319,7 @@ jobs:
windows_std_tools:
name: MSVC - Standard Tools
needs: [windows]
runs-on: windows-2025
runs-on: windows-latest
strategy:
fail-fast: true
if: github.event_name == 'push'
@@ -280,88 +327,81 @@ jobs:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v3
- name: Clone bext
# Note - this will not check out any of the submodules unless we need
# them for building, so it should be a very small disk space hit.
# Consequently, we don't worry about deleting it unless we end up
# having to build it. The bext source directory is not one of the
# cached directories, so a straight git clone is fine - no need to
# worry about colliding with a previous clone.
#
# In theory we could rely on the windows Ninja test for this, since we
# depend on it, but we define each test to be potentially stand-alone
# in case we end up removing the other windows test(s) for any reason.
run: git clone https://github.com/BRL-CAD/bext.git
- name: Add cl.exe to PATH
uses: ilammy/msvc-dev-cmd@v1
- name: Get bext commit SHA
id: bext-sha
shell: pwsh
run: |
cd bext
echo "sha=$(git rev-parse HEAD)" >> $env:GITHUB_OUTPUT
- name: Compute bext cache discriminator
id: cachekey
shell: bash
run: |
clver=""
if command -v cl.exe &> /dev/null; then
clver="$(cl.exe 2>&1 | head -n 1)"
fi
info="${{ steps.bext-sha.outputs.sha }}-$(uname -s)-$(uname -r)-$clver"
echo "hash=$(echo -n "$info" | sha1sum | awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}\bext_output
key: windows-bext-${{ steps.cachekey.outputs.hash }}
- name: Build bext (if cache miss)
# Note - most of windows_std_tools builds using cmd and avoids ninja,
# but for the bext build if we need to do it) we want to match the
# behavior of the ninja build so we have consistent inputs.
if: steps.cache-bext.outputs.cache-hit != 'true'
shell: powershell
run: |
cmake -E make_directory bext_build
cmake -S bext -B bext_build -DCMAKE_BUILD_TYPE=Release -DENABLE_ALL=ON -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}\bext_output
cmake --build bext_build --config Release -j2
# If we have had to build, the submodules are populated and the build
# directory will have a lot in it. We only need the build ouputs
# (bext_output) after this point, so clean up to save space for the
# main BRL-CAD build.
cmake -E rm -rf bext
cmake -E rm -rf bext_build
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: windows-2025-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Build Directory setup
run: |
cmake -E make_directory ./build_winstd
- name: MSVC and Ninja diagnostics
shell: cmd
run: |
where cmake
where ninja
where cl.exe
where msbuild
cmake --version
cl.exe
set INCLUDE
set LIB
set LIBPATH
- name: Configure
shell: cmd
run: |
cmake -S brlcad -B build_winstd -DBRLCAD_EXT_PARALLEL=1 -DBRLCAD_BUNDLED_LIBS=Bundled -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=%RUNNER_TEMP%\bext_output -DBRLCAD_ENABLE_QT=ON -DBRLCAD_CONFIG_PROBE_DIAGNOSTICS=ON -DBRLCAD_PROBE_SNAPSHOT_FILE=%GITHUB_WORKSPACE%\build_winstd\parallel-probes.txt
- name: Configure probe diagnostics
if: always()
shell: pwsh
run: |
$build = Join-Path $env:GITHUB_WORKSPACE 'build_winstd'
$diagnosticDir = Join-Path $build 'CMakeTmp/probe_diagnostics'
if (Test-Path $diagnosticDir) {
Get-ChildItem -Path $diagnosticDir -File | Sort-Object Name | ForEach-Object {
Write-Host "`n===== $($_.FullName) ====="
Get-Content -Path $_.FullName
}
} else {
Write-Host "No parallel-probe diagnostic directory was created."
}
$cmakeError = Join-Path $build 'CMakeFiles/CMakeError.log'
if (Test-Path $cmakeError) {
Write-Host "`n===== $cmakeError ====="
Get-Content -Path $cmakeError
}
$cache = Join-Path $build 'CMakeCache.txt'
if (Test-Path $cache) {
Write-Host "`n===== selected cache entries ====="
Select-String -Path $cache -Pattern '^(HAVE_CONIO_H|BRLCAD_PROBE_USE_NINJA|BRLCAD_PROBE_NINJA_EXE|BRLCAD_PROBE_VCVARS|BRLCAD_PROBE_VCVARS_ARCH):' | ForEach-Object { $_.Line }
}
- name: Rebuild conio probe verbosely
if: always()
shell: cmd
continue-on-error: true
run: |
if not exist build_winstd\CMakeTmp\INCLUDE_PROBE_build (
echo INCLUDE_PROBE mini-project was not configured.
exit /b 0
)
cmake --build build_winstd\CMakeTmp\INCLUDE_PROBE_build --config Release --target HAVE_CONIO_H --verbose
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
cmake -S brlcad -B build_winstd -DBRLCAD_EXT_PARALLEL=1 -DBRLCAD_BUNDLED_LIBS=Bundled -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=%GITHUB_WORKSPACE%\bext_output -DBRLCAD_ENABLE_QT=ON
- name: Build
id: build_parallel
shell: cmd
run: |
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
cmake --build build_winstd --config Release -j2
continue-on-error: true
@@ -369,16 +409,18 @@ jobs:
if: steps.build_parallel.outcome == 'failure'
shell: cmd
run: |
cmake --build build_winstd --config Release --target mged
cmake --build build_winstd --config Release mged
- name: Check
shell: cmd
run: |
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
cmake --build build_winstd --config Release --target check -j2
- name: Package
shell: cmd
run: |
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
cmake --build build_winstd --config Release --target package -j2
osx:
@@ -395,20 +437,48 @@ jobs:
run: |
brew install xquartz --cask
- name: Clone bext
run: git clone https://github.com/BRL-CAD/bext.git
- name: Get bext commit SHA
id: bext-sha
run: |
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Compute bext cache discriminator
id: cachekey
shell: bash
run: |
xcodever="$(xcodebuild -version | head -n 1 | awk '{print $2}')"
clangver="$(clang --version | head -n 1)"
info="${{ steps.bext-sha.outputs.sha }}-$(uname -s)-$(uname -r)-$xcodever-$clangver"
echo "hash=$(echo -n "$info" | sha1sum | awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: macos-bext-${{ steps.cachekey.outputs.hash }}
- name: Build bext (if cache miss)
if: steps.cache-bext.outputs.cache-hit != 'true'
run: |
cmake -E make_directory bext_build
export CC=clang
export CXX=clang++
# Right now on OSX we need ENABLE_ALL, because Mac system Tcl/Tk won't work
cmake -S bext -B bext_build -DENABLE_ALL=ON -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/bext_output -DCMAKE_BUILD_TYPE=Release
cmake --build bext_build -j 2
cmake -E rm -rf bext
cmake -E rm -rf bext_build
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: macos-14-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Build Directory setup
run: |
cmake -E make_directory build_osx
@@ -420,7 +490,7 @@ jobs:
export PATH=$GITHUB_WORKSPACE:$PATH
export CC=clang
export CXX=clang++
cmake -S brlcad -B build_osx -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output -DBRLCAD_ENABLE_QT=ON
cmake -S brlcad -B build_osx -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output -DBRLCAD_ENABLE_QT=ON
- name: Build
id: build_parallel
+105 -66
View File
@@ -25,10 +25,19 @@ jobs:
fail-fast: true
env:
DEBIAN_FRONTEND: noninteractive
if: github.event_name == 'schedule'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
# Cache apt package downloads (not installed pkgs)
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
# Install system dependencies
- name: Install apt dependencies
run: |
@@ -74,13 +83,13 @@ jobs:
runs-on: windows-latest
strategy:
fail-fast: true
if: ${{ !cancelled() }}
if: github.event_name == 'schedule'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v3
uses: microsoft/setup-msbuild@v2
- name: Add cl.exe to PATH
uses: ilammy/msvc-dev-cmd@v1
@@ -126,17 +135,11 @@ jobs:
runs-on: windows-latest
strategy:
fail-fast: true
if: ${{ !cancelled() }}
if: github.event_name == 'schedule'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v3
- name: Add cl.exe to PATH
uses: ilammy/msvc-dev-cmd@v1
- name: Add github workspace to path
shell: cmd
run: echo %GITHUB_WORKSPACE%>>"%GITHUB_PATH%"
@@ -153,25 +156,25 @@ jobs:
- name: Configure
shell: cmd
run: |
where cmake
where ninja
where cl.exe
where msbuild
cmake -S brlcad -B build_winstd -DBRLCAD_EXT_PARALLEL=1 -DBRLCAD_BUNDLED_LIBS=Bundled -DCMAKE_BUILD_TYPE=Release -DBRLCAD_BEXT_CLEANUP=ON -DBRLCAD_ENABLE_QT=ON
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
cmake -S brlcad -B build_winstd -DBRLCAD_EXT_PARALLEL=1 -DBRLCAD_BUNDLED_LIBS=Bundled -DBRLCAD_EXT_PARALLEL=1 -DCMAKE_BUILD_TYPE=Release -DBRLCAD_BEXT_CLEANUP=ON -DBRLCAD_ENABLE_QT=ON
- name: Build
shell: cmd
run: |
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
cmake --build build_winstd --config Release --target mged
- name: Check
shell: cmd
run: |
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
cmake --build build_winstd --config Release --target check
- name: Package
shell: cmd
run: |
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
cmake --build build_winstd --config Release --target package
osx_bext:
@@ -180,7 +183,7 @@ jobs:
runs-on: macos-14
strategy:
fail-fast: true
if: ${{ !cancelled() }}
if: github.event_name == 'schedule'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
@@ -225,16 +228,23 @@ jobs:
linux_static:
name: Clang Static Analyser
needs: [linux_bext]
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
strategy:
fail-fast: true
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.event_name == 'schedule' && github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
# Setup hint from https://github.com/darktable-org/rawspeed/blob/develop/.github/workflows/ci-static-analysis.yml
- name: Clang Static Analyzer Setup
run: |
@@ -253,20 +263,43 @@ jobs:
sudo apt-get install libgl-dev
sudo apt-get install libinput-dev # Cleanup
- name: Clone bext
run: git clone https://github.com/BRL-CAD/bext.git
- name: Get bext commit SHA
id: bext-sha
run: |
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Compute bext cache discriminator
id: cachekey
shell: bash
run: |
info="${{ steps.bext-sha.outputs.sha }}-$(uname -s)-$(uname -r)-$(gcc --version | head -n 1)"
echo "hash=$(echo -n "$info" | sha1sum | awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.cachekey.outputs.hash }}
- name: Build bext (if cache miss)
if: steps.cache-bext.outputs.cache-hit != 'true'
run: |
cmake -E make_directory bext_build
cmake -S bext -B bext_build -DCMAKE_BUILD_TYPE=Release -DENABLE_ALL=ON -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/bext_output
cmake --build bext_build --config Release -j 2
cmake -E rm -rf bext
cmake -E rm -rf bext_build
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: |
cmake -E make_directory build_clangstatic
@@ -275,8 +308,6 @@ jobs:
working-directory: ${{ github.workspace }}/brlcad
- name: Run Analyzer
env:
BRLCAD_EXT_DIR: ${{ runner.temp }}/bext_output
run: |
export PATH=$GITHUB_WORKSPACE:/usr/share/clang/scan-build-18/bin:/usr/share/clang/scan-build-18/libexec:$PATH
cp $GITHUB_WORKSPACE/brlcad/misc/clang-static-analyzer-run.sh .
@@ -295,21 +326,28 @@ jobs:
linux_cov:
name: LCOV Coverage testing
needs: [linux_bext]
runs-on: ubuntu-24.04
runs-on: ubuntu-latest
strategy:
fail-fast: true
env:
DEBIAN_FRONTEND: noninteractive
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
if: github.event_name == 'schedule' && github.ref == 'refs/heads/main'
steps:
- name: Setup - CMake
uses: lukka/get-cmake@latest
- name: Cache apt packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('.github/workflows/check.yml') }}
- name: Setup - System
run: |
sudo apt-get update
# Get the lcov tool and its dependencies
sudo apt-get install lcov gdb
sudo apt-get install lcov
# Install X/OpenGL dev pkgs
sudo apt-get install xserver-xorg-dev libx11-dev libxi-dev libxext-dev libglu1-mesa-dev libfontconfig-dev
# Install tools
@@ -323,20 +361,43 @@ jobs:
sudo apt-get install libgl-dev
sudo apt-get install libinput-dev
- name: Clone bext
run: git clone https://github.com/BRL-CAD/bext.git
- name: Get bext commit SHA
id: bext-sha
run: |
cd bext
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
- name: Compute bext cache discriminator
id: cachekey
shell: bash
run: |
info="${{ steps.bext-sha.outputs.sha }}-$(uname -s)-$(uname -r)-$(gcc --version | head -n 1)"
echo "hash=$(echo -n "$info" | sha1sum | awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Cache bext build outputs
id: cache-bext
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/bext_output
key: ${{ runner.os }}-bext-${{ steps.cachekey.outputs.hash }}
- name: Build bext (if cache miss)
if: steps.cache-bext.outputs.cache-hit != 'true'
run: |
cmake -E make_directory bext_build
cmake -S bext -B bext_build -DCMAKE_BUILD_TYPE=Release -DENABLE_ALL=ON -DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/bext_output
cmake --build bext_build --config Release -j 2
cmake -E rm -rf bext
cmake -E rm -rf bext_build
- name: Checkout
uses: actions/checkout@v6
with:
path: brlcad
- name: Prepare bext dependencies
uses: ./brlcad/.github/actions/prepare-bext
with:
platform-channel: ubuntu-24.04-${{ runner.arch }}-release
source-dir: ${{ github.workspace }}/brlcad
output-dir: ${{ runner.temp }}/bext_output
build-type: Release
artifact-token: ${{ secrets.BEXT_ARTIFACT_TOKEN }}
- name: Directory setup
run: |
cmake -E make_directory build_lcov
@@ -346,46 +407,24 @@ jobs:
- name: Configure
run: |
export PATH=$GITHUB_WORKSPACE:$PATH
cmake -S brlcad -B build_lcov -DBRLCAD_ENABLE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output -DBRLCAD_ENABLE_QT=ON
cmake -S brlcad -B build_lcov -DBRLCAD_ENABLE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug -DBRLCAD_EXT_DIR=${{ github.workspace }}/bext_output -DBRLCAD_ENABLE_QT=ON
- name: Build
id: build_parallel
run: |
export PATH=$GITHUB_WORKSPACE:$PATH
cmake --build build_lcov -j2
continue-on-error: true
- name: Build (serial for diagnostics)
if: steps.build_parallel.outcome == 'failure'
run: |
export PATH=$GITHUB_WORKSPACE:$PATH
cmake --build build_lcov -j1
continue-on-error: true
- name: Run Tests
id: coverage_tests
- name: Run Coverage Test
run: |
find . -name '*.gcda' -exec rm {} \;
cmake --build . --target check
working-directory: ${{ github.workspace }}/build_lcov
- name: Diagnose failed annotation test
if: failure() && steps.coverage_tests.outcome == 'failure'
continue-on-error: true
run: |
set +e
ctest -R '^rt_datum_annot_semantics$' -VV
cat Testing/Temporary/LastTest.log
if command -v gdb >/dev/null 2>&1; then
gdb --quiet --batch \
-ex 'set pagination off' \
-ex run \
-ex 'thread apply all bt full' \
--args ./src/librt/tests/rt_datum_annot_semantics
fi
working-directory: ${{ github.workspace }}/build_lcov
- name: Capture Coverage
run: |
make check
lcov --capture --directory . --output-file coverage.info
lcov -r coverage.info \*\/bext_output\/\* > coverage-2.info
lcov -r coverage-2.info \/usr\/\* > coverage_cad.info
-1
View File
@@ -36,6 +36,5 @@ CMakeLists.txt.user
# Misc
.clang-format
*__pycache__*
-32
View File
@@ -1,32 +0,0 @@
# Code Quality Standards
Write code as a senior engineer would for long-term maintenance. These are non-negotiable defaults, not suggestions to apply when asked.
## Principles
- **DRY.** Extract duplicate logic. Refactor. Once and only once.
- **Minimize surprises.** Preserve existing style and conventions. Test when you can.
- **No magic values.** Use named constants, enums, or configuration. Every literal needs justification.
- **Minimize scope.** Prefer tightest scope that works - local variables, parameters, encapsulation. Broader scope needs justification.
- **No dead code.** Delete commented-out code, unused variables, unreachable branches. Version control remembers.
- **Comments explain why.** Document intent, constraints, and non-obvious decisions. Use "what" summaries only for complex or non-obvious algorithms. If routine code needs a comment to explain it, the code should be clearer.
- **Clean up what you touch.** Improve code you are changing: rename unclear variables, extract functions, simplify conditionals. Do not mix unrelated cleanup with logic changes - separate concerns, separate commits.
- **Handle errors deliberately.** Whether failing loudly or quietly, make it an intentional choice. No accidental swallowing.
- **YAGNI.** Do not add speculative abstractions, unused parameters, or unplanned extension points. Build what is needed now. Refactor when requirements actually change.
- **Perfection is when there is nothing left to take away.** Prefer reduction over addition, simpler is better. Too clever to debug easily is too clever.
## Before Finishing
Review your changes for code smells, duplicated logic, hardcoded values, overly broad scope, unclear names, missing error handling, unnecessary complexity, etc. Fix issues in the same pass - do not defer cleanup.
## Git
Never commit without permission (ask every time). Never push to remote. Never use `codex`, `chatgpt`, `openai`, `gemini`, `antigravity`, `copilot`, `claude`, `llm`, `ai`, or similar terms in branch names, tag names, commits, PRs, comments, and other metadata. Do not add generated-by notices or otherwise indicate authorship unless user explicitly requests. Do not include specific machine information - full file system paths, machine names, IP addresses, or other identifiable information in commit messages, code, comments or documentation.
## Repository Coding Conventions
The HACKING file in the root of the source tree defines coding conventions specific to BRL-CAD, including versions of common functions that are used in our code base instead of raw standard functions. Review this file before writing code so your changes and additions adhere to BRL-CAD standards.
BRL-CAD code should typically use our ZERO and EQUAL macros rather than raw floating-point equality comparisons to avoid Werror=float-equal compilation failures on expressions such as a == 0.0 (should be ZERO(a)) or b != c (should be !EQUAL(b, c)).
When completing a code change (not for intermediate iterations, but when preparing to hand back a finalized change) use our regress-repository and regress-licenses build targets to check that the result satisfies our internal checkers.
-18
View File
@@ -393,11 +393,6 @@ Sieu, Jeff
2017 December
Open Source (GCI)
Baker, Josh
nicknames joshbaker22
2023 August
U.S. Army Research Laboratory
CODE CONTRIBUTIONS
------------------
@@ -1090,15 +1085,6 @@ Reel, Samuel (Sammy)
2024 March
Texas A&M University
Rupesh
nicknames rupes, rupeshca007
2026 March
Open Source
nicknames laithaldaeef
2026 March
Open Source
SPECIAL THANKS
--------------
@@ -1421,10 +1407,6 @@ nicknames r-ricci
2022 January
Open Source
nicknames Meghna45-code
2026 July
Open Source
CORPORATE AND ORGANIZATION SUPPORT
----------------------------------
+179
View File
@@ -21,9 +21,25 @@ Recent Bugs
Something is concatenating EXEPATH and/or fbserv silently fails with
return codes (e.g., when not specifying -F, only giving the port.)
* rt -H hypersample, -J jitter, and -j# for sub-grid-mode assumes a
framebuffer, causing pix data to get written to the -o file (e.g.,
even with -o file.png). See view_pixel() near src/rt/view.c:472 for
problem area with -j but there are likely call sites.. Need to
scrub all fb_write() and ideally make this a non-issue via icv API.
* obj-g and gcv converters choke and crash on obj with unnamed g line.
spec wording on whether that's valid is unclear, but encountered in
wild.
* recursive bu_parallel() failure, tbd whether cpp11 or pthread impl,
likely because IDs are exceeding MAX_PSW, causing mayhem and chaos.
* Archer was observed to mangle the structure of a comb tree when assigning
a color from the dialog panel. MGED is able to assign the color fine,
so there appears to be something specific to Archer's comb tree handling
that is flawed. Not all combs are handled incorrectly. Issue appears to
be long standing - observed as far back as at least version 7.28.
* rtcheck_handler_cleanup() throws 'invalid handle specified' on Windows
in closing of STDOUT (see FIXME comment). Does not affect normal running,
but a debug build complains.
@@ -52,12 +68,20 @@ Recent Bugs
Backtrace indicates write buffer is full, likely because no output
is going to terminal. (Observed on Mac)
* gcv on a glTF file (at least a binary .glb) crashes hard with a NULL
pointer bomb (workaround: gltf-g succeeds albeit incomplete
conversion). Takes out the entire Terminal app on Mac for some
reason (consistently).
* Running"mged -c test.g" exits automatically on default prompt:
...
Create new database (y|n)[n]?
Warning: no database is currently open!
morrison@Miniagua .build %
* TGC tess fails when we have a near-zero c axis and a larger d
axis, or vice versa.
* MGED crashes trying to open the repository file
doc/docbook/resources/other/standard/xsl/images/important.tif
It is mis-identified as a v4 .g file due to the file header's
@@ -78,6 +102,16 @@ Recent Bugs
> e -S -m1 boxes.r
box1 is not drawn
* When run inside mged, invalid syntax reported on "gqa -p prefix"
despite it being documented as the correct form (and working outside
mged). specifying gqa -pprefix appears to be workaround, though
unintuitive. specifying gqa -p"" annoyingly outputs ""exp_air.plot3
with quotes embedded in the name.
* rtweight/gqa volumes seem wrong with simple sphere test case, with
values consistently and quickly converging less than the actual
volume regardless of the grid size.
* raytracing a revolved sketch seems to work fine, but rtarea and gqa
seem to be crashing on that same revolve. curiously, the brep
revolve from the csgbrep proc-db has the same failure as well as the
@@ -88,12 +122,20 @@ Recent Bugs
* running archer "" at least on windows results in a file type dialog
and errors with "can't read "_conv_log": no such variable
* opening a database in archer with the same name as a command doesn't
work.
* in mged, running the 'attach' command (confirmed issues with X and
ogl), closing the window, and then issuing a 'draw' results in mged
crashing.
* killtree / crashes
* killtree reports spurious db_lookup failures saying object does not
exist as it previously deleted it. should keep track of what it
deletes to not output spuriously, or (better) delete transactionally
so it only attempts to lookup and delete once per object.
* object names with a / or \ in them make ls or underlying directory
parsing logic display them incorrectly.
@@ -109,9 +151,18 @@ Recent Bugs
* fbclear -c appears to hang indefinitely inside pkg_bwaitfor,
possible protocol mismatch or capability removed/changed in fbserv.
* dbupgrade -r produces an invalid rhc with the default v5 rhc produced
by MGED with "make rhc rhc"
* apparently all four BRL-CAD Tutorial Series volumes are missing from
our bibliography...
* Tessellating an ETO with a normal tolerance results in stack
smashing due to bad logic in recursive algorithm: set norm 2;
facetize my.eto my.bot;. Observed infinite recursion in both
make_ellipse4() in eto.c and (after adding max recursion test) in
paint_face() in manif.c:190
* mater -d information stored in the .g file doesn't survive a
garbage collection operation.
@@ -127,10 +178,36 @@ Recent Bugs
still being displayed. this causes 'rt' to fly into an infinite
loop, presumably trying to increment rays from the eye position.
* icv dpix support is not cross-platform (it writes out native, reads
in assuming same encoding). regression tests fail on big endian.
* creating an object with a slashes in the name (e.g., cp foo foo/R)
results in an object that cannot be deleted/renamed. bad behavior
presumably extends to any name with path separators.
* mirror command rejects brep solids and turns faces inside-out when
mirroring a comb with brep solids below it.
* rtsil command works if do what usage says and redirect output to
file, but mentions .pix when data is actually .bw; and using the -o
option results in a black image. it is also inconsistent, writing a
black silhouette on a white background, instead of black on white
and missing background color options.
* make sph sph
clone -i 1 -t 1000 0 0 -n 100 sph
kill sph
g line sph*
clone -i 1 -t 0 1000 0 -n 100 line
kill line
g square line*
clone -i 1 -t 0 0 1000 -n 100 square
... never returns ...
This should be merely 1M spheres, but something chokes. Could be
somewhere in the Tk layer. Maybe somewhere in the db layer. Maybe
something is corrupted by clone when it
* If we draw any form, then trace it using rt, then change of database
(by clicking file>open and selecting another database), badness
ensues. One report has quitting the rt window causing a segfault.
@@ -144,12 +221,31 @@ Recent Bugs
in ann3.s annot 0 0 0 1 10 10 3 1
# using numbers for a label results in no label
* make eto eto
tol norm 1
facetize eto.bot eto
[crashes due to excessive recursion]
* crash in rt_bot_xform() due to a bot being marked as having face
normals, but didn't. bot probably written wrong via conversion
to/from obj or asc. found importing teapot.
* rtedge with perspective is wrong. it fills in nearly entire faces,
vertically in particular. it's worse on small sized renders, and
gets better the larger the render size (indicating there's some
neighbor distance coming into play that is not affected by
max_dist). eoes not happen in non-perspective ray-traces.
* a character is (still) sometimes captured by the cursor box. steps
to reproduce:
1) write a word on the mged command prompt ("e.g. hello")
2) select the word to end of line with mouse
3) paste the word (e.g., middle mouse) and press enter
4) type "hello" again and press enter
you should now see an "o" in the yellow cursor box. sometimes
you'll see the "o" after step 3. running "clear" resets the cursor.
* get_regions tcl command doesn't respond well to situations where
child object names in combs have dashes (the "-" character) in
names. It tries to interpret the dash as an argument delimiter.
@@ -171,6 +267,13 @@ Recent Bugs
* Recursive submodel predictably goes infinite, need stack-based
db_walk_tree(): mged> in submodel submodel submodel grid test.g
* running rt -s20 -F file.pix ... does not result in an 20x20 image
being written out. it ends up being 512x512.
* running rt -C255/0/0 -o file.pix ... does not result in the
background color getting used. It does work with -F file.pix, going
through libfb instead of libicv.
* ogl display manager and framebuffer are creating windows with
transparent backgrounds (the glClear color is not being drawn) on
Linux. Presumably a driver-related issue, alpha channel, or expose
@@ -179,6 +282,9 @@ Recent Bugs
private memory -- looks like private memory is not initialized
(observed on Mac 10.6, Windows, and Ubuntu Linux using 7.26).
* pixdiff on Windows is reporting no differences with a pair of files
that pixcmp can see differences in.
* fblabel seems quite busted, at least talking to a /dev/X fbserv, in
that it only draws the first character and eventually displays
rem_read() failures when run in -d debug mode.
@@ -187,6 +293,12 @@ Recent Bugs
after doing an overlay render. it does draw, though, as confirmed
by a forced fb-fb refresh.
* pixborder doesn't account for an edge case where the right edge of
an image is expected to be colored (except for one pixel on the top
edge). Example:
pixborder -b "255 0 0" -t "255 255 255" < pix/moss.pix | pix-fb
* typing 'comb -f -r assembly_name' shuts down mged with the error:
ERROR: bad pointer 0000000000B4CA50: s/b bu_external(x768dbbd0), was bu_vls(x89333bbb), file ..\..\..\brlcad_src\src\libbu\parse.c, line 2443"
And on the mged command line:
@@ -200,6 +312,11 @@ Recent Bugs
* wgl framebuffer is not lingering on windows (regardless of using
wgll or default) when it should
* calling "attr set obj key value" should always result in key getting
set to value, no matter what, as it is the lowest-level attribute
management interface and what the command (correctly) documents.
example demonstrated to not work was: attr set obj rgb 123/123/123
* report of LIBBU not working when accessed by a multithreaded
application on Windows. reportedly due to some problem with the
debug memory queue.
@@ -247,6 +364,12 @@ Recent Bugs
book-keeping is fuxored or the db_lookup is returning NULL (or isn't
yet performed).
* src/librt/primitives/bot/g_bot_include.c:rt_bot_bbox() routine isn't
calculating the bbox correctly
* rtxray crashes if you specify a -o *.bw output file due to
assumptions in the rt front-end that all output files are .pix
* encountered a crash during rtarea on a (default) facetized version
of the hyp from the proc-db csgbrep tool.
@@ -261,6 +384,9 @@ Recent Bugs
* torus with a near zero inner diameter results in zero-length edges
during tessellation.
* bu_log() with a width specifier does not align like printf().
Example: bu_log("%24s", str);
* report that "keep" sometimes results in a .g file with unknown units;
dbconcat also is reported to set the units to unknown if concatting
a file with unknown units.
@@ -288,6 +414,10 @@ Recent Bugs
* rt -i -s4096 -H16 -F/dev/null boolean-ops.g all
* asc2g of a .asc file containing the first line as a "#" comment
results in a bu_malloc(0) bomb. comment lines should be valid in
.asc files.
* compilation reportedly fails when building Tcl if the path to the
source directory includes a space.
@@ -412,6 +542,11 @@ Recent Bugs
* running 'keep' on too many objects (hundreds is causing a usage
statement (and not doing the keep)
* rtwizard won't display a line overlay if you line object is obscured
by another. Example being to display a vehicle as ghost, crew as
solid, and crew as line. confirmed even when using the other line
occlusion settings.
* fbserv is receiving image data very slowly if the framebuffer is a
remote X24 interface. could reproduce on mac with the following:
@@ -471,6 +606,9 @@ Recent Bugs
ubuntu linux. key events go to the command window even with the
graphics window has focus.
* MGED File->Preferences->Fonts results in error "named font "button
_font" doesn't exist on Linux.
* mged tab-completion doesn't work if the object names have spaces
* Open dialog in MGED seems rather busted for scrolling and selection
@@ -508,6 +646,13 @@ Recent Bugs
* dsp primitive is going into what seems to be an unbounded memory
allocation loop during prep, inside dsp_layers().
* libfb cannot utilize standard output/error "device" files without
path trickery. it recognizes the /dev/ prefix and presumes it's a
libfb device instead of a filesystem device.
OK: rt -F/./dev/stdout
BAD: rt -F/dev/stdout
* libfb cannot open a file descriptor when piping/redirecting output.
OK: rt -F/./dev/stdout moss.g all.g
@@ -530,6 +675,8 @@ Recent Bugs
* triangulation of some pipe in toyjeep.g fails (rather reliably) on
some given bend. fails in nmg_triangulate model().
* fbhelp sends some of the output to stdout and some to stderr...
* debugbu 2 immediately reports a bu_vls_free() error.. apparently
been a problem since 4.5 days. this occurs because
bu_memdebug_add() is not called unless memory checking is enabled
@@ -546,6 +693,9 @@ Recent Bugs
* Create menu.. create "part" boo hiss..
* wavelet isn't working correctly on a simple image decomposition &
reconstruction.
* fbed is looking for /usr/lib/vfont/nonie.r.12
* mged doesn't check if html_dir does not exist when searching for
@@ -565,6 +715,11 @@ Recent Bugs
* concave arbs give correct wireframe but do not raytrace correctly.
* rtwizard/rtedge creates incorrect "fuzzy" edge overlay when creating
a "Ghost Image with Insert and Lines" that includes a light source
and object close to surface (e.g. moss.g; select plane, light, and
cone for ghost; select cone for insert and lines.)
* mged's solid illuminate doesn't work when Lighting is turned on
* raytrace of zoomed images (e.g., -s64) doesn't work for if_X24
@@ -606,9 +761,33 @@ Recent Bugs
* sketches extruded with non-square AB vectors results in inner sketch
components not getting scaled properly.
* rtcheck is ignoring fastgen tagged geometry since no multioverlap
handler is set.
* bot-bldxf fails in db_walk_tree(), interface may have changed
Older Bugs
----------
* X11 framebuffer often fails to display on certain middle bit depth
displays. (e.g. 15 or 16 bit depth)
* mk_lcomb fails on large combinations due to mk_tree_pure() building
a left-heavy tree and wdb_put_internal() then recursively performing
lookup and put calls.
Annoyances
----------
* matrix edits on objects in mged require you to select a primitive
for a coordinate system reference. this can be counterintuitive and
confusing.
* there are frequently modality errors when entering edit mode as
control and middle mouse rebind to model edit instead of view edit.
---
Bugs should be reported to the bug tracker on the project website at
http://sourceforge.net/tracker/?atid=640802&group_id=105292
+410 -1083
View File
File diff suppressed because it is too large Load Diff
+519 -10804
View File
File diff suppressed because it is too large Load Diff
+1 -30
View File
@@ -1263,17 +1263,6 @@ Release steps are as follows:
#####################################################################
# 01: Sync main to RELEASE branch.
TODO - we probably need to do a re-look at the RELEASE and STABLE setup.
With Git and modern workflows, I'm leaning more towards a temporary
working branch where we shake down for release, then tagging from that
working branch and merging that back into main once complete. For
minor releases we should create a X-XX branch from the X-XX-0 tag, and
any patch releases on that minor series will be handled in and tagged
from the branch. With AI driven change rates, it's unrealistic to
try and put main back into a state where we can call a tag off of it
a patch on an older minor. Needs more thought - should try to hash out
before the next minor release and update the workflow.
git clone git@github.com:BRL-CAD/brlcad.git
cd brlcad
git checkout RELEASE
@@ -1540,27 +1529,9 @@ before the next minor release and update the workflow.
# 18: Upload the source distributions and release notes. Use source
# tarballs to create binaries.
# NON-AUTO: Select the new tag at https://github.com/BRL-CAD/brlcad/releases/new
#
# Upload the NEWS entries and description for the web page's
# release notes. Attach the tar.gz, tar.bz2 and .zip files as
# the initial archives. Releases may be edited to add new files,
# so go ahead and publish the release to have our default webpage
# correctly reflect the most recent release.
------------- TODO - need new procedures for GitHub... ------------
TODO - It would be nice to have some curated scripts for binary creation.
For Linux I usually set up a fresh Rocky Linux image with a clean environment
and install just what is needed to try and get a "this will probably run
anywhere" binary, but as a manual process that's a pain - maybe there's a way
to script qemu to do the job for us...
Windows is still completely manual. The .msi installer depends on an older
version of WiX, and I don't know of another good solution there - we probably need
to investigate whether we could produce MSIX packages instead.
Mac - TODO.
#####################################################################
# 19: Notify binary platform maintainers:
+11 -37
View File
@@ -39,7 +39,7 @@ including instructions for building on Windows.
Required tools:
- Git must be 2.17 or later
- CMake must be 3.26 or later
- CMake must be 3.20 or later
- Compiler must be C++17-compliant
- If using Visual Studio, version 2019 (16.8+) or later
- If using GCC/G++, version 7 or later
@@ -111,8 +111,8 @@ path) as described in the Quick Installation section.
Validating checksums:
The integrity of distributed files can be verified using checksums that are
published with released files. Released files and their checksums are
available from the GitHub releases page (https://github.com/BRL-CAD/brlcad/releases). If you
published with released files. Files on SourceForge's file release system can
be found by clicking the 'i' button at the end of each file's name. If you
re-distribute BRL-CAD, checksums should be retained with the files so others
can validate origination.
@@ -350,35 +350,6 @@ if it is, default is to enable.
Aliases: ENABLE_OPENGL
--- BRLCAD_X11_PROVIDER ---
Selects the X11 implementation used by BRL-CAD, Tk, Qt, and OpenGL. Accepted
values are AUTO, SYSTEM, and XMIN. AUTO is the default and deliberately
resolves to SYSTEM so installing Xmin cannot change an existing build.
XMIN selects an installed Xmin client SDK for deterministic GUI testing
without a host X server. The SDK must provide Xmin::ToolkitX11; OpenGL builds
also need Xmin::GL. Set Xmin_ROOT to the SDK installation prefix. Tk and Qt
must be built for the same provider because their public X11 APIs conceal
provider-private state; mixing Xmin and system client libraries is not ABI
safe and is rejected during configuration.
When BRL-CAD manages bext, it derives the matching bext SDK prefix from the
selected Xmin package. Bext then applies its version-matched Tk and Qt patches
automatically to whichever bundled toolkits are selected. No external patch
paths are needed.
A typical Xmin configuration is:
cmake .. -DBRLCAD_X11_PROVIDER=XMIN \
-DXmin_ROOT=/path/to/xmin-prefix
Bext retains advanced TK_EXTRA_PATCHES, TK_CONFIGURE_ARGS, QT_EXTRA_PATCHES,
and QT_XMIN_ROOT controls for custom profiles. The standard BRL-CAD Xmin
configuration does not need them. Refer to bext's Xmin profile documentation
before changing the bundled Tk or Qt revision.
--- BRLCAD_COMPONENTS ---
Semicolon separated list of components to enable for building - see
@@ -467,10 +438,13 @@ Aliases: ENABLE_ALL_CXX
--- BRLCAD_EXTRADOCS ---
The core option that enables and disables building of BRL-CAD's
AsciiDoc based documentation (includes manuals and man pages for
commands, among other things). It is built with BRL-CAD's bundled
asciiquack processor into HTML and man-page (troff) formats. Defaults
to ON for a full build and OFF for reduced target sets.
DocBook based documentation (includes manuals and man pages for
commands, among other things). Defaults to ON, but only HTML and MAN
formats are enabled by default - PDF must be enabled separately by use
of this option or one of its aliases. Note that you may set
environment variable APACHE_FOP to point to your locally installed fop
executable file (which on Linux is usually a shell script with 0755
permissions).
Aliases: ENABLE_DOCS, ENABLE_EXTRA_DOCS
Aliases: ENABLE_DOCS, ENABLE_EXTRA_DOCS, ENABLE_DOCBOOK
+4 -231
View File
@@ -10,217 +10,12 @@ descriptive text that emphasizes or further describes significant
changes made. See document footer for additional details.
----------------------------------------------------------------------
--- 20XX-XX-XX Release 7.46.0 ---
--- 20XX-XX-XX Release 7.44.0 ---
----------------------------------------------------------------------
* improved pixscale & bwscale scaling and image piping - Sean Morrison
* restored pixdiff behavior on .pix, added -b for .bw - Sean Morrison
* updated MGED and Archer for Tcl 8.6.18 and Itcl/Itk 4 - Cliff Yapp
* fixed writes to fileless geometry databases - Cliff Yapp
* fixed nastran-g handling of large property IDs - Rupesh, Cliff Yapp
* fixed dxf-g invalid polyface index crashes - Meghna45-code, Cliff Yapp
* fixed Archer primitive editors under Itcl 4 - Cliff Yapp
* fixed Archer shutdown menu cleanup errors - Cliff Yapp
* fixed MGED Build Pattern dialog under Itcl 4 - Cliff Yapp
* fixed TclCAD framebuffer listing and deletion - Cliff Yapp
* fixed MGED Build Pattern progress updates - Cliff Yapp
* fixed MGED search -exec reentry and Ctrl-C crashes - Cliff Yapp
* fixed MGED asynchronous commands and clone progress - Cliff Yapp
* accelerated large and repeated MGED path drawing - Cliff Yapp
* fixed ARB7 inside solid construction - Cliff Yapp
* fixed direct ARB face and edge-direction editing - Cliff Yapp
* fixed rtwizard startup with framebuffer contention - Cliff Yapp
* fixed Archer annotation line display updates - Cliff Yapp
* fixed Archer sketch scale drift in non-mm databases - Cliff Yapp
* fixed toggle arrow callbacks during setup - Cliff Yapp
* fixed Tcl dialogs with multi-word titles and messages - Cliff Yapp
* fixed Archer Tank Wizard gun generation - Cliff Yapp
* fixed MGED and Archer sketch arc tangency editing - Cliff Yapp
* fixed Archer ARB4 point 3 editing - Cliff Yapp
* fixed ARB4 storage from make and mk_arb4 - Cliff Yapp
* fixed ARB4 and ARB6 center point calculations - Cliff Yapp
* fixed concurrent MGED and rtwizard framebuffer use - Cliff Yapp
* fixed MGED ShotVis editing and reload failures - Cliff Yapp
* fixed Tcl widget geometry and selection defects - Cliff Yapp
* fixed MGED BoT editor property handling - Cliff Yapp
* fixed MGED LOD dialog and adaptive BoT wireframes - Cliff Yapp
* fixed MGED Plot, PostScript, and manual launch tools - Cliff Yapp
* fixed MGED Overlap Tool multi-object result handling - Cliff Yapp
* eliminated 16-fold redundant gchecker grid analysis - Cliff Yapp
* fixed Archer tree handling for object names with spaces - Cliff Yapp
* fixed RtWizard multi-object edge occlusion handling - Cliff Yapp
* fixed RtWizard title, About, and preference handling - Cliff Yapp
* fixed MGED startup file false legacy-syntax warnings - Cliff Yapp
* fixed MGED saved-view deletion and collaboration sync - Cliff Yapp
* fixed MGED font preferences apply and persistence - Cliff Yapp
* fixed Archer combination edits changing Boolean trees - Cliff Yapp
* fixed Archer command-line help startup crash - Cliff Yapp
* fixed MGED Geometry Browser menu and close behavior - Cliff Yapp
* fixed MGED collaboration view unshare crash - Cliff Yapp
* added an override for Archer's preference file location - Cliff Yapp
* fixed embedded Archer display and mode menus - Cliff Yapp
* added Archer -h and --help command-line options - Cliff Yapp
* fixed Archer Help opening the documentation menu - Sean Morrison
* added arrange nest command for packing database objects - Sean Morrison
* new mkbuilding tool for parametric/OSM/CityJSON models - Sean Morrison
* cross-platform BINUNIF and DSP byte-order handling - Sean Morrison
* improved several cv default behaviors (s, 32, 64, n) - Sean Morrison
* fixed invalid bot handling bug applying matrices - Sean Morrison
* improved glTF import robustness via gcv - Sean Morrison
* fixed bot dump glTF/GLB export; -F is now rejected - Cliff Yapp
* faster NMG solid ray tracing (10-20x faster) - Sean Morrison
* preserved primitive colors in shaded BoT and B-Rep drawing - Cliff Yapp
* preserved B-Rep attributes through in-place geometry edits - Cliff Yapp
* fixed gcv filter arguments containing one-character values - Cliff Yapp
* improved iges-g importer robustness - Cliff Yapp
* expanded g-iges native CSG and B-Rep export support - Cliff Yapp
* added IGES import and export support to gcv - Cliff Yapp
* rt -b query option now supports a single value index - Sean Morrison
* fixed .dpix file format portability and icv support - Sean Morrison
* expanded pixscale support for piped image data - Sean Morrison
* fixed HYP volume and ARBN totals reported by analyze - Cliff Yapp
* corrected rtarea sampling and exposed-area calculations - Cliff Yapp
* bot split now groups results and preserves mesh data - Cliff Yapp
* bot decimate now preserves normals, UVs, and plate data - Cliff Yapp
* added raytracing support for annotation objects - Cliff Yapp
* fixed MGED X embedded framebuffer display manager crash - Cliff Yapp
* added annotate command for managing annotation objects - Cliff Yapp
* added repair command for supported invalid primitives - Cliff Yapp
* changed default new-region material code from 1 to 0 - Keith Bowman
* added comb support to bb -o oriented bounding boxes - Cliff Yapp
* added -t tight bounding box option to bb command - Cliff Yapp
* added az (-a) and el (-e) option implementations to gqa - Cliff Yapp
* added center command support for centering on an object - Cliff Yapp
* greatly expanded JT import and added basic JT export - Sean Morrison
* added csg-g/g-scad OpenSCAD CSG importer/exporter - Erik Greenwald
* improved art light, color, output, & region handling - Sean Morrison
* added preliminary OpenSCAD import support - Sean Morrison
* expanded IGES BREP/NURBS import and export support - Sean Morrison
* expanded STEP AP203 import support with faceted BREP - Sean Morrison
* added STEP AP203e2, AP214, and AP242 import/export - Cliff Yapp
* added STEP CSG round trips and AP242 PMI import - Cliff Yapp
* improved STEP assembly, topology repair, and reporting - Cliff Yapp
* new adrt CLI utility with path, spall, and cut modes - Sean Morrison
* new CLI+GUI prototype BRL-CAD application launcher - Sean Morrison
* added option validation to image & framebuffer tools - Sean Morrison
* added contributor, API, command, & raytracing guides - Sean Morrison
* added and updated command and library manual pages - Sean Morrison
* added parashot gravity trajectory path generator - Sean Morrison
* added metaball point scaling (via metaball_move_pnt) - Sean Morrison
* all raytracing apps now report object prep failures - Sean Morrison
* improved fast4-g robustness and error reporting - Cliff Yapp
* improved robustness of g-vrml plate mode handling - Cliff Yapp
* fixed MGED ARB5 point, pipe, and sketch editing - Cliff Yapp
* added pnts write -f xyz export option - Chris McGregor
* added support for tick drawing on MGED model axis - Cliff Yapp
* added naca456 left and paired wing generation - Cliff Yapp
* added patch-g -j option, specify object thicknesses - Sean Morrison
* fixed fbcolor color ramp bug drawing the last color - Sean Morrison
* fixed gist -Q quick preview option - Sean Morrison
* rt preserves eye_pt setting in command scripts - Sean Morrison
* rt -l8 heat graphs now measure CPU time - Sean Morrison
* documented gqa centroid & moments of inertia options - Sean Morrison
* pixdiff now calculates pixel differences on bw files - Sean Morrison
* fixed bwcrop single-axis crops and pixembed edge fill - Sean Morrison
* fixed isize in non-mm databases - Josh Baker
* fixed metaball adjust clearing points on errors - Sean Morrison
* fixed benchmark+pixcmp correctness validation bug - Sean Morrison
* fbhelp writes help to stdout and rest to stderr - Sean Morrison
* FB now supports /dev/stdout and /dev/stderr devices - Sean Morrison
* fixed mged rt -C + -o background color to file bug - Sean Morrison
* fixed rt -C255/0/0 -o file.pix background color bug - Sean Morrison
* added rtsil foreground & background -c set options - Sean Morrison
* added rtsil -o support for bw output - Sean Morrison
* added cutting plane animation generation to rtwizard - Cliff Yapp
* fixed pixdiff bug on Windows - Sean Morrison
* fixed MGED startup window placement on Windows - Chris McGregor
* fixed pixborder utility right-side edge bug - Sean Morrison
* fixed 'wavelet' image processing tool on Windows - Sean Morrison
* quieted mged killtree spurious lookup failure output - Sean Morrison
* fixed ray tracing small images to disk framebuffers - Sean Morrison
* improved raytracing performance of CSG-heavy regions - Sean Morrison
* fixed OBJ conversion bug importing unnamed groups - Sean Morrison
* fixed k-g conversion of BoT vertex normals - laithaldaeef
* new doc guide, a visual overview of BRL-CAD objects - Sean Morrison
* improved triangle quality produced by bot remesh - Cliff Yapp
* updated numerous manpage command references - Josh Baker
* fixed submodel paths relative to parent databases - Sean Morrison
* improved performance making huge combinations - Sean Morrison
* added make -t primitive type listing - Chris McGregor
* added gcv import conversion support for vrml/wrl 1.0 - Sean Morrison
* fixed gcv appending to existing geometry databases - Sean Morrison
* added CSS names, hex, HSL/HSV to libbu color parsing - Sean Morrison
* improved OpenNURBS B-Rep import and adjustment safety - Cliff Yapp
* improved Debian application menus and MIME associations - Jordi Sayol
* updated Clipper2 dependency to v1.5.4 - Cliff Yapp
* updated Eigen dependency to v5.0.1 - Cliff Yapp
* updated GDAL dependency to v3.13.3 - Cliff Yapp
* updated GeometricTools dependency to v8.2 - Cliff Yapp
* updated Itk dependency to v4.2.7 - Cliff Yapp
* updated LMDB dependency to v1.0.1 - Cliff Yapp
* updated Manifold dependency to v3.5.3 - Cliff Yapp
* updated OpenCV dependency to v5.0.0 - Cliff Yapp
* updated OpenNURBS dependency to v8.34.26223.11001 - Cliff Yapp
* updated PROJ dependency to v9.8.1 - Cliff Yapp
* updated PoissonRecon dependency to v18.75 - Cliff Yapp
* updated Tcl/Tk dependency to v8.6.18, using bundled Itcl - Cliff Yapp
* updated libjpeg-turbo dependency to v3.2.0 - Cliff Yapp
* updated libosmesa dependency to SHA1 bfa90de - Cliff Yapp
* updated libpng dependency to v1.6.58 - Cliff Yapp
* updated libtiff dependency to v4.7.2 - Cliff Yapp
* updated netpbm dependency to v10.86.50 - Cliff Yapp
* updated oneTBB dependency to v2023.1.0 - Cliff Yapp
* updated pugixml dependency to v1.16 - Cliff Yapp
* updated sqlite3 dependency to v3.53.4 - Cliff Yapp
* updated stepcode dependency to SHA1 ed686ee1d - Cliff Yapp
* updated tinygltf dependency to v3.0.1 - Cliff Yapp
* updated zlib dependency to v1.3.2 - Cliff Yapp
----------------------------------------------------------------------
--- 2026-07-23 Release 7.44.0 ---
----------------------------------------------------------------------
This release expands geometry processing, conversion, and rendering
capabilities including a new proximity search 'near' command, ARB
repair, BoT exterior extraction, Cauchy-Crofton validation in lint,
and more reliable facetization pipeline. Ray tracers now auto-select
a default object or report available top-levels when none is named.
Rendering advancements include perspective edge rendering, timing heat
maps, PNTS ray tracing, and faster opaque and lighting-heavy renders.
GCV adds preliminary import support for VTK ASCII, X3D BREP/NURBS, and
JT import support, while OBJ preserves material colors. Procedural
tools now generate shells, gears, lattices, terrain, propellers,
wings, trees, and parameterized tires with tread presets.
MGED gains full-text doc searching and more robust command I/O; gist
1-page reports are more informative; and ICV adds richer reporting,
animation, comparison, and image metadata features. DocBook
documentation was converted to AsciiDoc, adding over 220 manual pages
and extensively improving existing docs.
* fixed search -exec infinite looping with creations - Chris McGregor
* fixed NOCOS mode plate mode bot creation - Meghna45-code
* fixed search -exec multithreaded output - Cliff Yapp, Chris McGregor
* improved as2g importing speed for large inputs - Cliff Yapp
* gist pages now include file size in header - Sean Morrison
* added preliminary support for mirroring brep objects - Sean Morrison
* fixed dbupgrade corruption of RHC entities - Sean Morrison
* fixed archer bug opening database named same as cmd - Sean Morrison
* fixed mged bug where pasted text captured by prompt - Sean Morrison
* added -k/-K manpage full text keyword search options - Sean Morrison
* rm ged command now behaves like the system rm, kills objects&paths
- Cliff Yapp, Sean Morrison
* fixed gqa exactly symmetric volumetric estimates - Sean Morrison
* added support to rtedge for perspective renderings - Sean Morrison
* added bu_cmd_schema for full command grammars, completion, and validation;
bu_opt remains the concise supported option-only API over the same engine
- BRL-CAD
* rt -l8 rendering time heat graphs - Stephen Kennedy, Sean Morrison
* added 'icv anim' for APNG and MJPEG animation files - Clifford Yapp
* added BREP/NURBS import support to gcv x3d importer - Sean Morrison
* added BRL-CAD Taxonomy article on naming conventions - Sean Morrison
* added new documentation on adrt rendering - Sean Morrison
* added snail & seashell procedural geometry generator - Sean Morrison
* additional 3D geometry model examples - Csanyi Pal, Lee Butler
@@ -265,41 +60,19 @@ and extensively improving existing docs.
* corrected the exposed region count report in rtarea - Cliff Yapp
* fixed icv support for RLE image format - Cliff Yapp
* added similarity grouping identification mode to gdiff - Cliff Yapp
* added preliminary JT mesh import support to gcv - Sean Morrison
* improved gcv asc v5 reader to handle brep input - Cliff Yapp
* improved DSP primitive's default facetize behavior - Cliff Yapp
* fixed gcv appending to existing databases - Sean Morrison
* improved NMG->bot conv speed for all triangle case - Cliff Yapp
* added SPSR meshing support to the pnts command - Cliff Yapp
* rt tools auto-select an object when none is given - Sean Morrison
* added metadata-aware image diff & nirt analysis - Cliff Yapp
* added basic PNTS point-cloud ray tracing - Sean Morrison
* improved nirt behavior in Windows bash consoles - Cliff Yapp
* added g2asc/asc2g support for PNTS, DSP, and EBM - Sean Morrison
* updated geogram dependency to v1.9.6 - Cliff Yapp
* updated gct mesh decimation dependency to mmesh - Cliff Yapp
* added procedural wing, propeller & tree generators - Cliff Yapp
* added ISO tire dimensions & named tread presets - Cliff Yapp
* added specimen, terrain, & voxelize proc-db tools - Sean Morrison
* added gear, helicoil, lattice, loftwing proc-db - Sean Morrison
* added authenticated IPC/TLS to fbserv & remrt/rtsrv - Cliff Yapp
* improved rtwizard concurrency & remrt on Windows - Cliff Yapp
* added simplification control options to bot extrude - Cliff Yapp
* added bot exterior subcommand - Cliff Yapp
* updated Manifold dependency to v3.2.1 - Cliff Yapp
* updated SPSR dependency to v18.74 - Cliff Yapp
* fixed 'search -type sph' not returning sph's - Chris McGregor
* fixed gist crashing with bad/unknown units - Chris McGregor
* add gist '-d' to allow user-specified density file - Chris McGregor
* added Cauchy-Crofton area/volume & lint validation - Cliff Yapp
* updated geogram dependency from v1.9.0 to v1.9.6 - Cliff Yapp
* updated Manifold dependency from v2.5.1 to v3.2.1 - Cliff Yapp
* updated SPSR dependency from v16.10 to v18.74 - Cliff Yapp
* updated Embree dependency from v4.3.2 to v4.4.1 - Sean Morrison
* updated ISPC dependency from v1.24.0 to v1.30.0 - Sean Morrison
* updated oneTBB dependency from v2021.12.0 to v2023.0.0 - Sean Morrison
* updated OSPRay dependency from v3.1.0 to v3.2.0 - Sean Morrison
* updated rkcommon dependency from v1.13.0 to v1.15.2 - Sean Morrison
* updated LIEF dependency from v0.15.1 to v0.17.6 - Cliff Yapp
* updated Qt dependency from v6.10.2 to v6.11.1 - Cliff Yapp
* added Bullet dependency v3.27 - Cliff Yapp
----------------------------------------------------------------------
+1 -1
View File
@@ -1,5 +1,5 @@
BRL-CAD
Release 7.44.2
Release 7.42.2
http://brlcad.org/
BRL-CAD is a powerful cross-platform open source combinatorial
+88 -35
View File
@@ -18,53 +18,39 @@ tasks as they are completed.
THESE TASKS SHOULD HAPPEN BEFORE THE NEXT RELEASE
-------------------------------------------------
* revert the pixdiff/pixcmp change back to grayscale
* rm foo bar vs rm -C foo bar and a safety guard that prevents
deleting foo accidentially.
* coordinate with bext to have it produce a manifest of what files
need strclear/plief processing of various types so we don't need to
redo the characterization pass every time we configure. We have
strclear and plief in bext, so that repo should be capable of doing
the work for us as a post build step whenever bext changes.
* verify MGED exit behavior on Windows - reports of non-zero exit
being returned.
* fix ARB5 move point 5 to actually move the point.
* need extensive testing of MGED CSG editing with the shift to librt
based editing logic.
* investigate gqa plotting display in MGED
* update change policy to 1) expand definition of minimally impacting
to allow an assuption of non-embedding in function calls (i.e., no
function or macro calls as function arguments), 2) migrate change
tracking to a doc subfolder, 3) split deprecation from minimally
impacting to separate docs, 4) invert minimally impacting list to be
a functional description of the change (e.g., "rename A -> B", "drop
arg 3 C", etc), 5) auto-generate and publish robust regular
expressions from the functional descriptions, 6) publish an
auto-update script that warns about deprecated use and/or applies
minimally impacting changes to a given file.
THESE TASKS SHOULD HAPPEN WITHIN TWO RELEASE ITERATIONS
-------------------------------------------------------
* DEFERRED mouse sweep rect
* DEFERRED apropos (view command
* fix ARB8 promotion to BoT, so calls between prep and shot don't get
inconsistent data (soltab needs to match).
* verify arb6 editing in cheese wedge tutorial
* rtarea is sometimes missing regions on summary reporting, at least
on Windows, possibly a threading issue setting up the results
container.
THESE ARE UNSCHEDULED BACKLOG TASKS
-----------------------------------
* reconcile VCOMB2, VBLEND2, and VADD2SCALE along with corresponding
3d/4d api consistency in vmath.h
* make sph sph
clone -i 1 -t 1000 0 0 -n 100 sph
kill sph
g line sph*
clone -i 1 -t 0 1000 0 -n 100 line
kill line
g square line*
clone -i 1 -t 0 0 1000 -n 100 square
... takes a crazy long time ...
This should be merely 1M spheres, but it chokes with non-linear time
increase. Appears to be excessively reading/writing objects and
getting slower as it progresses. Needs to be optimized.
* Add two-tiered option handling to tire, propeller and naca456
For most uses we'll want a few pre-baked high level settings -
those can be command line flags. For full control of the complex
@@ -80,6 +66,10 @@ THESE ARE UNSCHEDULED BACKLOG TASKS
binary interface to analytic routines. notable outliers include
nirt_* (including CLI handling..), voxelize*, rt_gen*, rectangular*
* ensure datum objects convert out via g2asc and back (currently
writes "a Tcl output routine for this type of object has not yet
been implemented")
* fix recursive bu_parallel() to not have a hard-coded limit on the
number of threads or to more aggressively abort when more that
supported are dispatched. currently supporting 64x64 threads and
@@ -343,6 +333,17 @@ lookup check to ensure none are missing.
error. code appears to be assuming both /dev/X framebuffer and uses
/dev/null redirect to sink output.
* rtwizard greys out the File->New and Open menu items when run with a
filename, which is very confusing. Either menu should remain usable
or there should be some other indication that a file was specified
and is open.
* the mged tutorials apparently do not mention the tops command (even
once), but really should as it's the starting point for discovering
what is in databases that are opened or imported.
* add metaball scaling feature (presently in a tclscript)
* ability to visualize metaball centerpoints and with/without
translucency.
@@ -353,8 +354,6 @@ lookup check to ensure none are missing.
* add script/command for changing metaball weights in masse
* add a proper 'metaball' command with subcommands
* gdiff in mged appears to be broken? get "no primitives found" on
second comb when specifying two combs (gdiff comb1 comb2). UPDATE -
this appears to be a consequence of how gdiff internally implements
@@ -364,6 +363,9 @@ lookup check to ensure none are missing.
comb2 is shared with comb1. A workaround is to keep out comb2 and
dbconcat it back in, then gdiff comb1 with the imported tree.
* pixscale doesn't seem to handle stdin (due to bu_seek) for very
long
* The embedded framebuffer for the X display manager is not working
with Tcl/Tk 8.6 - it brings down mged with an Xerror when it tries
to XFlush after X24_blit. Better solution is to replace the X dm/fb
@@ -488,6 +490,10 @@ lookup check to ensure none are missing.
* add unit tests for primitive callback routines (e.g., bbox).
* put bu_num_print() to use
* use bu_gettime() in rt -l8 heatgraph visualization mode
* fully implement analyze for all geometry objects
* move analyze logic into libanalyze (with respective primitive logic
@@ -588,6 +594,10 @@ lookup check to ensure none are missing.
libged command wrapper so it's consistent and available to any
command.
* mater command does not validate its arguments - fix that. Also
properly document using "." to skip specifying something - not in
the man page currently.
* bullet integration - need to expose restitution as an
object parameter so we can configure behavior:
http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?p=&f=&t=3248
@@ -621,6 +631,8 @@ lookup check to ensure none are missing.
* closing the graphics window brings down X11 on Mac due to a bad
context. fix or revert recent close window behavior.
* V&V bwcrop, pixembed are behaving correctly, as documented
* implement unit tests for bu dirent / stat API
* convert src/util/terrain.c to src/shapes/terrain.c writing out the
@@ -636,6 +648,8 @@ lookup check to ensure none are missing.
get_eyemodel to eye_pt to result in no change, modulo unit
conversions.
* make rt -b accept a pixel index in addition to x,y pixel coordinates
* teach pixdiff and other tools that can/should support the capability
to read/write (as appropriate) pixel index values or x,y coordinates
and reproduce the ray fired to create that pixel. currently does -l
@@ -952,6 +966,11 @@ lookup check to ensure none are missing.
* test tgf-g conversion with "ring-mode" geometry
* fix metaball/adjust.. wipes out all metaball values with:
adjust metaball 1 1 1
just gives usage with:
adjust metaball 1 1
* test for -msse3 requirement for __SSE.*__ definition
* improve sse run-time detection so illegal instruction crashes are
@@ -970,6 +989,11 @@ lookup check to ensure none are missing.
[FAN-OUT: yes -- per-file/per-converter sweep with a verification
pass.]
* pixdiff reports bytes, but reports incorrect (off-by-one) bytes for
.bw input files. cause is due to tool assuming input is rgb
triplets (even though output is bytes, wtf?). should probably
report pixels and/or have a -b option for handling byte/bw input.
* investigate why epa primitive is so sensitive to coarse absolute
value changes (run csgbrep, tol abs=1, facetize and get 321k poly)
@@ -1070,6 +1094,12 @@ lookup check to ensure none are missing.
intersected with them) since, while bad practice, are valid
geometrically.
* make sure there are no getenv() non-NULL assumptions within the
code. might want to see if there's a pattern of variables being
checked such that a libbu interface would be warranted (e.g.,
instead of checking HOME, having a bu_find_directory(BU_USER_HOME)
routine or similar facility) for finding common resource locations.
* make db_open modes behave the same as the fopen() modes (i.e.,
create the .g if one doesn't exist when write mode)
@@ -1722,6 +1752,12 @@ ATTRIBUTES
* implement an option to "attr upgrade" for reading upgrade/downgrade
plugins/instructions from an external file for 3rd party use.
* prevent nirt from outputting a trailing space after values when
there are no attributes to be displayed. the problem is in the nirt
format strings where they use " %s" for displaying any attributes.
need to left-pad a space conditionally, perhaps by supporting %*s
and sizeof(var).
* add additional support for user-specified sorting for the attr
command when new attribute attributes are added (e.g., creation
date)
@@ -2540,6 +2576,8 @@ DOCUMENTATION
* Need ability to search manual pages
* rename MGED Help->Apropos to Help->Search Commands (apropos)
* BRL-CAD Primitives
An overview of the various primitive object types in BRL-CAD,
their range of features, and a description of their input
@@ -2556,6 +2594,10 @@ DOCUMENTATION
various image formats like png just by specifying an output file
extension.
* document gqa centroid and moments of inertia options
* document the new NURBS/BREP primitive, capabilities and limitations
Need to revisit utility of spherical mapping, used by sh_spm and
sh_points, used for environment mapping (e.g., stars):
@@ -2595,6 +2637,13 @@ DOCUMENTATION
tgf-g
* write up some documentation on other build tools besides make -
CMake supports other generators, wouldn't hurt to detail how to
trigger builds in them (MSVC is partially covered, make sure to
coverage is complete - others include Eclipse, XCode once we get the
kinks ironed out there, CodeBlocks. Ninja build tool and its
CMake support are worth documenting too.
* all of the rt* tracers share common code and common options, but do
not share common documentation. refactor documentation to use
include directives so that there is one place where all of the
@@ -2694,6 +2743,10 @@ DOCUMENTATION
* BRL-CAD Manifesto
Vision & Scope
* BRL-CAD Taxonomy
Description of the common terminology used throughout BRL-CAD,
conventions employed, and tool categorization.
* Implementing a BRL-CAD Primitive
How-To for creating a new primitive in BRL-CAD that can be
ray-traced, tessellated, plotted, and transformed seamlessly.
-7
View File
@@ -3,12 +3,6 @@ add_subdirectory(ref)
add_definitions(-DCONSOLE)
brlcad_addexec(pixcmp pixcmp.c libbu)
brlcad_add_test(
NAME bench_pixcmp_tolerance
COMMAND
${CMAKE_COMMAND} "-DPIXCMP=$<TARGET_FILE:pixcmp>" "-DTEST_DIR=${CMAKE_CURRENT_BINARY_DIR}"
-P "${CMAKE_CURRENT_SOURCE_DIR}/pixcmp_test.cmake"
)
set(BARK_SOURCES benchmark.c compute.c run.c clean.c)
brlcad_addexec(bark "${BARK_SOURCES}" "libbu;${M_LIBRARY}" NO_STRICT NO_INSTALL TEST_USESDATA)
@@ -44,7 +38,6 @@ file(
cmakefiles(
CMakeLists.txt
pixcmp_test.cmake
run.sh
try.sh
viewdiff.sh
+3 -5
View File
@@ -237,7 +237,7 @@ set_if_unset(void (*echo)(const char *, ...), void (*verbose)(const char *, ...)
}
setval = getenv(var);
echo("Using [%s] for %s\n", setval ? setval : "", var);
echo("Using [%s] for %s\n", setval, var);
}
@@ -589,7 +589,6 @@ main(int ac, char *av[])
{
struct bu_vls v = BU_VLS_INIT_ZERO;
char rfc2822[1024] = {0};
const char *logfile = getenv("LOGFILE");
#ifdef HAVE_SYS_UTSNAME_H
struct utsname n;
time_t t = time(NULL);
@@ -605,7 +604,7 @@ main(int ac, char *av[])
echo("B R L - C A D B E N C H M A R K\n");
echo("=================================\n");
echo("Running %s on %s\n", av[0], rfc2822);
echo("Logging output to %s\n", logfile ? logfile : "disabled");
echo("Logging output to %s\n", getenv("LOGFILE"));
echo("%s\n\n", bu_vls_addr(&v));
}
@@ -654,7 +653,6 @@ main(int ac, char *av[])
bu_setenv("PIX", bu_path_dirname(getenv("PIX")), 1);
}
const char *pix_env = getenv("PIX");
bu_vls_printf(&vp,
"%s "
"%s "
@@ -663,7 +661,7 @@ main(int ac, char *av[])
"%s/../../pix "
"%s/../../../pix "
"./pix",
pix_env ? pix_env : "", pix, thisp, thisp, thisp, thisp);
getenv("PIX"), pix, thisp, thisp, thisp, thisp);
bu_argv_from_string(argv, 32, bu_vls_addr(&vp));
look_for(verbose_echo, directory, "a benchmark reference log directory", "LOG", (const char **)argv);
bu_vls_trunc(&vp, 0);
+24 -18
View File
@@ -160,38 +160,44 @@ compare_rgb(int r1, int g1, int b1, int r2, int g2, int b2, size_t *matching, si
&& (b1 == b2 && b1 != -1))
{
result = MATCHING;
(*matching)++;
} else if (r1 == -1 || r2 == -1 || g1 == -1 || g2 == -1 || b1 == -1 || b2 == -1) {
/* image sizes don't match (or other I/O error) */
result = MISSING;
} else {
/* at least this */
result = OFF_BY_ONE;
/* but maybe more */
(*missing)++;
} else if (((r1 != r2) && (g1 == g2) && (b1 == b2))
|| ((r1 == r2) && (g1 != g2) && (b1 == b2))
|| ((r1 == r2) && (g1 == g2) && (b1 != b2)))
{
/* off by one channel */
if (r1 != r2) {
if ((r1 > r2 ? r1 - r2 : r2 - r1) > 1) {
result = OFF_BY_MANY;
(*offmany)++;
} else {
result = OFF_BY_ONE;
(*off1)++;
}
}
if (g1 != g2) {
} else if (g1 != g2) {
if ((g1 > g2 ? g1 - g2 : g2 - g1) > 1) {
result = OFF_BY_MANY;
(*offmany)++;
} else {
result = OFF_BY_ONE;
(*off1)++;
}
}
if (b1 != b2) {
} else if (b1 != b2) {
if ((b1 > b2 ? b1 - b2 : b2 - b1) > 1) {
result = OFF_BY_MANY;
(*offmany)++;
} else {
result = OFF_BY_ONE;
(*off1)++;
}
}
}
if (result == OFF_BY_ONE) {
(*off1)++;
} else if (result == OFF_BY_MANY) {
(*offmany)++;
} else if (result == MATCHING) {
(*matching)++;
} else {
(*missing)++;
result = OFF_BY_MANY;
(*offmany)++;
}
return result;
@@ -340,7 +346,7 @@ main(int argc, char *argv[])
bu_log("Warning - f2 fstat failed: %s\n", strerror(errno));
}
/* bu_log("FILE1_size(%zu) FILE1_skip(%zu) FILE2_size(%zu) FILE2_skip(%zu)\n", (size_t)sf1.st_size, f1_skip, (size_t)sf2.st_size, f2_skip); */
bu_log("FILE1_size(%zu) FILE1_skip(%zu) FILE2_size(%zu) FILE2_skip(%zu)\n", (size_t)sf1.st_size, f1_skip, (size_t)sf2.st_size, f2_skip);
if (!quiet && ((sf1.st_size - f1_skip) != (sf2.st_size - f2_skip))) {
bu_log("WARNING: Different image sizes detected\n");
-80
View File
@@ -1,80 +0,0 @@
# Exercise pixcmp's pixel tolerance and exit-status contract with small,
# deliberately readable byte streams.
if(NOT PIXCMP OR NOT TEST_DIR)
message(FATAL_ERROR "PIXCMP and TEST_DIR are required")
endif()
function(check_pixcmp name input1 input2 expected_status expected_summary)
set(file1 "${TEST_DIR}/pixcmp_${name}_1.pix")
set(file2 "${TEST_DIR}/pixcmp_${name}_2.pix")
file(WRITE "${file1}" "${input1}")
file(WRITE "${file2}" "${input2}")
execute_process(
COMMAND "${PIXCMP}" ${ARGN} "${file1}" "${file2}"
OUTPUT_VARIABLE output
ERROR_VARIABLE errors
RESULT_VARIABLE status
)
file(REMOVE "${file1}" "${file2}")
if(NOT "${status}" STREQUAL "${expected_status}")
message(
FATAL_ERROR
"${name}: pixcmp returned ${status}, expected ${expected_status}\nstdout: ${output}\nstderr: ${errors}"
)
endif()
string(REGEX REPLACE "[ \t\r\n]+" " " normalized_output "${output}")
string(STRIP "${normalized_output}" normalized_output)
string(FIND "${normalized_output}" "${expected_summary}" summary_position)
if(summary_position EQUAL -1)
message(
FATAL_ERROR
"${name}: expected summary '${expected_summary}'\nactual stdout: ${output}\nstderr: ${errors}"
)
endif()
endfunction()
set(exact_pixel "pixcmp pixels: 1 matching, 0 off by 1, 0 off by many")
set(tolerated_pixel "pixcmp pixels: 0 matching, 1 off by 1, 0 off by many")
set(rejected_pixel "pixcmp pixels: 0 matching, 0 off by 1, 1 off by many")
check_pixcmp(exact "ABC" "ABC" 0 "${exact_pixel}")
check_pixcmp(one_channel_within_tolerance "ABC" "BBC" 1 "${tolerated_pixel}")
check_pixcmp(two_channels_within_tolerance "ABC" "BCC" 1 "${tolerated_pixel}")
check_pixcmp(three_channels_within_tolerance "ABC" "@CB" 1 "${tolerated_pixel}")
# Keep the tolerated channel first in two cases to catch short-circuiting that
# would fail to inspect a later channel outside the tolerance.
check_pixcmp(red_outside_tolerance "ABC" "CCD" 2 "${rejected_pixel}")
check_pixcmp(green_outside_tolerance "ABC" "BDD" 2 "${rejected_pixel}")
check_pixcmp(blue_outside_tolerance "ABC" "BCE" 2 "${rejected_pixel}")
check_pixcmp(
missing_pixel
"ABC"
"ABCDEF"
2
"pixcmp pixels: 1 matching, 0 off by 1, 0 off by many, 1 missing"
)
check_pixcmp(
byte_within_tolerance
"A"
"B"
1
"pixcmp bytes: 0 matching, 1 off by 1, 0 off by many"
-b
)
check_pixcmp(
byte_outside_tolerance
"A"
"C"
2
"pixcmp bytes: 0 matching, 0 off by 1, 1 off by many"
-b
)
+20 -31
View File
@@ -750,9 +750,9 @@ run ( ) {
\"${DB}/${run_geomname}.g\" ${run_geometry} 1>&2 <<EOF
$run_view
EOF
run_retval=$?
$VERBOSE_ECHO "DEBUG: Running $RT returned $run_retval"
return $run_retval
retval=$?
$VERBOSE_ECHO "DEBUG: Running $RT returned $retval"
return $retval
}
@@ -986,7 +986,6 @@ bench ( ) {
bench_frame=0
bench_rtfms=""
bench_percent=100
bench_retval=0
bench_start_time="`date '+%H %M %S'`"
bench_overall_elapsed=-1
@@ -1010,10 +1009,7 @@ $bench_view
start $bench_frame;
end;
EOF
bench_raytrace_retval=$?
if test $bench_raytrace_retval != 0 ; then
bench_retval=$bench_raytrace_retval
fi
retval=$?
if test $bench_frame -ne 0 ; then
if test -f ${bench_testname}.pix.$bench_frame ; then
@@ -1087,7 +1083,7 @@ EOF
fi
# did we fail?
if test $bench_raytrace_retval != 0 ; then
if test $retval != 0 ; then
$ECHO "RAYTRACE ERROR"
break
fi
@@ -1152,34 +1148,27 @@ EOF
ls -la *.pix*
fi
$VERBOSE_ECHO "DEBUG: $CMP $PIX/${bench_testname}.pix ${bench_testname}.pix"
cmp_result="`eval \\\"${CMP}\\\" \\\"${PIX}/${bench_testname}.pix\\\" ${bench_testname}.pix 2>&1`"
bench_cmp_retval=$?
cmp_result="`eval \\\"${CMP}\\\" \\\"${PIX}/${bench_testname}.pix\\\" ${bench_testname}.pix 2>&1 | grep pixels`"
ret=$?
pixels_result="`echo \\\"$cmp_result\\\" | grep pixels`"
if test "x$pixels_result" = "x" ; then
$ECHO "$cmp_result"
else
$ECHO "$pixels_result"
fi
$ECHO "$cmp_result"
if test $bench_cmp_retval = 0 ; then
if test $ret = 0 ; then
# perfect match
$ECHO ${bench_testname}.pix: answers are RIGHT
elif test $bench_cmp_retval = 1 ; then
elif test $ret = 1 ; then
# off by one, acceptable
$ECHO ${bench_testname}.pix: answers are RIGHT
elif test $bench_cmp_retval = 2 ; then
elif test $ret = 2 ; then
# off by many, unacceptable
$ECHO ${bench_testname}.pix: WRONG WRONG WRONG WRONG WRONG WRONG
bench_retval=$bench_cmp_retval
else
# some other failure
$ECHO ${bench_testname}.pix: BENCHMARK COMPARISON FAILURE
bench_retval=$bench_cmp_retval
fi
$VERBOSE_ECHO "DEBUG: Done benchmark testing on $bench_testname"
return $bench_retval
return $retval
}
@@ -1327,7 +1316,7 @@ perf ( ) {
start="`date '+%H %M %S'`"
$ECHO "Running the BRL-CAD Benchmark tests... please wait ..."
$ECHO
benchmark_retval=0
ret=0
bench moss all.g $RTARGS << EOF
viewsize 1.572026215e+02;
@@ -1337,7 +1326,7 @@ viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00 0.000000000e+00
7.424039245e-01 5.198368430e-01 4.226182699e-01 0.000000000e+00
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00 ;
EOF
benchmark_retval=`expr $benchmark_retval + $?`
ret=`expr $ret + $?`
bench world all.g $RTARGS << EOF
viewsize 1.572026215e+02;
@@ -1347,7 +1336,7 @@ viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00 0.000000000e+00
7.424039245e-01 5.198368430e-01 4.226182699e-01 0.000000000e+00
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00 ;
EOF
benchmark_retval=`expr $benchmark_retval + $?`
ret=`expr $ret + $?`
bench star all $RTARGS << EOF
viewsize 2.500000000e+05;
@@ -1357,7 +1346,7 @@ viewrot -6.733560560e-01 6.130643360e-01 4.132114880e-01 0.000000000e+00
4.896120540e-01 7.885590550e-01 -3.720948210e-01 0.000000000e+00
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00 ;
EOF
benchmark_retval=`expr $benchmark_retval + $?`
ret=`expr $ret + $?`
bench bldg391 all.g $RTARGS << EOF
viewsize 1.800000000e+03;
@@ -1367,7 +1356,7 @@ viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00 0.000000000e+00
7.424039245e-01 5.198368430e-01 4.226182699e-01 0.000000000e+00
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00;
EOF
benchmark_retval=`expr $benchmark_retval + $?`
ret=`expr $ret + $?`
bench m35 all.g $RTARGS <<EOF
viewsize 6.787387985e+03;
@@ -1377,14 +1366,14 @@ viewrot -5.527838919e-01 8.332423558e-01 1.171090926e-02 0.000000000e+00
6.800964482e-01 4.429747496e-01 5.841593895e-01 0.000000000e+00
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00 ;
EOF
benchmark_retval=`expr $benchmark_retval + $?`
ret=`expr $ret + $?`
bench sphflake scene.r $RTARGS <<EOF
viewsize 2.556283261452611e+04;
orientation 4.406810841785839e-01 4.005093234738861e-01 5.226451688385938e-01 6.101102288499644e-01;
eye_pt 2.418500583758302e+04 -3.328563644344796e+03 8.489926952850350e+03;
EOF
benchmark_retval=`expr $benchmark_retval + $?`
ret=`expr $ret + $?`
$ECHO
$ECHO "... Done."
@@ -1392,7 +1381,7 @@ $ECHO
$ECHO "Total testing time elapsed: `eval \\\"$ELP\\\" $start`"
# see if we fail
if test ! "x$benchmark_retval" = "x0" ; then
if test ! "x$ret" = "x0" ; then
$ECHO
$ECHO "THE BENCHMARK ANALYSIS DID NOT COMPLETE SUCCESSFULLY."
$ECHO
-630
View File
@@ -1,630 +0,0 @@
buopt production-readiness checklist
====================================
This checklist records the issues found during the post-rebase review of the
buopt branch. An item is complete only when the implementation and relevant
tests are both in place.
[x] Make libged command schema/grammar registries safe during static
initialization and concurrent registration/lookup.
[x] Make semantic-provider initialization and access thread-safe.
[x] Separate semantic candidate values from command-line insertion encoding
and transient-display escaping. Cover whitespace, quoting characters,
Tcl metacharacters, newlines, and terminal control bytes.
[x] Add schema-selectable database-object completion filters. Ordinary
geometry roles should exclude _GLOBAL; metadata-aware and binary-object
commands should explicitly request the broader or specialized sets they
support.
[x] Make a bare Escape cancel gsh completion without blocking for subsequent
input bytes.
[x] Honor the completion layout API's character-cell contract for UTF-8,
including wide and combining characters.
[x] Make MGED terminal cursor positioning safe for wrapped input, and account
for wrapped input rows in the Tk one-third-prior-output policy.
[x] Repaint gsh transient completion displays when a Windows console resize
event is received.
[x] Define and enforce safe initialization/lifetime contracts for public
completion and validation result objects.
[x] Allow qged/libqtcad command completion at an empty prompt.
[x] Reject negative argc in bu_cmd_schema_parse_complete before size_t casts.
[x] Audit and either eliminate or explicitly constrain libged unbound schema
rows so execution and completion grammars cannot silently drift.
[x] Pass BRL-CAD's repository regression: portable string/file APIs,
bu_setprogname in test mains, required source headers, and editor footers.
[x] Keep public libbu schema declarations C-only; do not expose C++
constructors in public C data structures.
[x] Preserve attached short-option arguments (for example, draw -m3) across
native parsing, validation, option-presence checks, operand counting, and
option-span analysis.
[x] Preserve draw's established transparency and line-width defaults when
native options are absent.
[x] Update the GQA plotting test for canonical encoded display-list paths.
[x] Keep non-command database-attribute readers on the supported bu_opt API
and limit the native-schema source audit to actual command parsers.
[x] Keep independently launched fbserv stress suites from racing for
overlapping ports while preserving simultaneous worker/server startup;
report closed-peer writes as failures instead of terminating on SIGPIPE.
[x] Correct MGED's appended Configure binding so GUI initialization does not
execute a stray closing brace, and exercise GUI binding installation in a
display-independent Tcl regression test.
[x] Remove the quadratic candidate-validation path from empty database-object
completion, keep option spellings out of object listings, recognize an
editable `--` as a long-option prefix, and avoid sorting every possible
summary refinement during large completion layouts.
[x] Add regression coverage for all corrected behavior and run the full build,
bu_opt compatibility tests, schema/completion tests, frontend PTY tests,
available Qt tests, and regress-repository.
[x] Keep bu_opt as the approachable option-authoring API while exposing
side-effect-free completion and validation inferred from every standard
bu_opt reader.
[x] Add an ABI-safe per-option sidecar for aliases, custom value types,
candidates, hints, variable token counts, and context-aware validators.
[x] Add a reentrant builder macro so commands declare familiar option rows
once and use them for parsing, help, completion, and schema publication.
[x] Add a compact GED option specification for positional roles and command
constraints, retaining full native schemas and parser-owned grammars only
for cases that need their additional expressiveness.
[x] Convert representative ordinary, constrained, and context-sensitive GED
commands (bb, kill, and ls) to the compact facade and preserve hidden,
type-filtered, alias, and _GLOBAL completion behavior.
[x] Add and registration-time lint a compact positional DSL for ordinary
option specifications. Cover cardinalities, GED semantic providers,
inline keyword vocabularies, inclusive numeric domains, common positive
and nonnegative domains, and standard color/vector/pattern token shapes.
[x] Survey the remaining full schemas for repeated declarative patterns.
Keep keyword metadata with aliases/descriptions, command-specific
validation, heterogeneous repeated groups, subcommand trees, and
parser-owned languages in native C definitions rather than growing the
textual facade into a second programming language.
[x] Preserve and test punctuation short options used by legacy commands, and
make runtime-generated compact schemas own their command names rather than
relying on registration-call pointer lifetimes.
[x] Identify custom multi-token option values from the parser's structural
result rather than a fixed backward-search window; cover values wider than
the built-in color/vector forms.
[x] Reject overflowing option-builder row counts before allocating the
required terminal descriptor.
Deep tab-completion API and scaling review (2026-08-13)
-------------------------------------------------------
[x] Separate syntax/semantic validation from candidate generation. A
validation-only query must not enumerate candidates, and one completion
request must invoke its selected semantic completer at most once. The
public `ged_cmd_validate` API now has that direct behavior; the redundant
completion-free validation alias was removed.
[x] Remove generic per-candidate reconstruction and whole-command validation.
Select context-dependent providers once from parsed command state; expose
an explicit lightweight candidate predicate only for the rare rules whose
legality actually depends on the proposed value.
[x] Make cursor handling correct in the middle of command, option, quoted,
escaped, UTF-8, object, and database-path tokens. Track the full token,
decoded prefix through the cursor, raw prefix/suffix spans, and the exact
replacement range separately.
[x] Add deterministic provider-call-count and mid-line replacement tests, plus
scaling tests which prevent broad object/path completion from regressing
to quadratic behavior.
[x] Filter database directory entries by type and prefix before sorting,
encode each matching name once, and avoid a second whole-database search
for ordinary unescaped hierarchy paths.
[x] Add a database completion index with reliable mutation invalidation so
root-object prefixes are O(log N + matches), while retaining command-
selected hidden, _GLOBAL, binary, primitive, combination, and region
policies.
[x] Add a request-oriented completion API with a candidate budget, total and
returned counts, truncation state, and independently computed common
prefix. Keep a compatibility wrapper for existing callers.
[x] Bound transient-layout work independently of terminal dimensions. Limit
materialized candidates and summary-frontier size, precompute UTF-8 widths
within each layout, retain the candidate set for resize-only repaints, and
debounce Qt resize rendering. A 10,000-candidate/100-row regression test
guards the layout path.
[x] Reuse the cursor parse throughout one completion request, avoid growing-
prefix revalidation in native schema analysis, and replace recursive
"copy schema and clear custom_validate" patterns with the explicit
bu_cmd_schema_validate_syntax API.
[x] Improve experimental API ownership and clarity: const provider data,
status separate from count, explicit byte-offset terminology, documented
token-grammar candidate ownership, and removal of result fields duplicated
by `expected` or `hint`.
[x] Convert the last potentially large composite database provider
(geometry-or-primitive) and filesystem provider to bounded query
interfaces, including full-set total/common-prefix metadata. File
completion now scans a directory once and retains O(K) rather than O(N)
candidate storage for a K-entry request.
[x] Keep parser-owned grammar adapters on the same classify-then-enumerate
path as flat schemas. Native tree/form adapters and delegated commands
now use syntax-only validation, search publishes its context-selected
object provider instead of scanning directly, and custom BREP component
indices honor the caller's materialization budget while reporting
full-set count, truncation, and common-prefix metadata.
[x] Keep the compatibility fallback for metadata-free commands on that same
path: syntax-only validation classifies the object/path role without a
database scan, and the outer request performs one bounded query.
[x] Keep custom final-value predicates from breaking filesystem navigation or
bounded extension filtering. Directory candidates remain available as
intermediate paths, while graph's SVG role selects an extension-aware
provider before applying its final-value validator.
[x] Release the allocated NULL-only argv returned by empty command and
database queries; repeated no-match completion must not leak.
[x] Re-run the full targeted completion/schema/frontend suite, repository
regression, and measured large-database/layout benchmarks before declaring
this section complete.
Post-squash review and follow-up (2026-08-13)
---------------------------------------------
[x] Preserve bu_opt callback parsing without speculative NULL-storage calls.
Standard flags are classified from descriptor metadata, opaque callbacks
are invoked exactly once with their actual storage, and partially known
compact flag words remain untouched pass-through operands.
[x] Apply command candidate predicates inside bounded semantic providers before
the materialization limit. Report total, truncation, and common prefix for
the full valid set rather than for a filtered prefix of that set.
[x] Keep hierarchical completion proportional to the selected subtree. Slash
paths query only direct children of the decoded parent, and pathsum, paths,
and listeval now combine their space-separated path components before
selecting that parent.
[x] Reduce completion-index memory by storing stable directory-entry iterators
in the reverse map instead of a second copy of every database object name.
[x] Generate standard command help from schema data. libbu now emits a
POSIX-style synopsis plus description, options (including aliases),
operands, repeated groups, and constraint hints; libged exposes the same
output by registered command name. rm, list/l, and the straightforward BoT
command family now use generated help rather than duplicated option text.
[x] Remove rm's growing-prefix custom-validator cost. Its force-sensitive
hidden/global completion policy is selected once by a request-aware
semantic provider, keeping analysis of arbitrarily long rm commands linear.
[x] Replace the gsh, MGED, and QgConsole fixed candidate limits with a shared
viewport-derived budget. Truncated MGED and QgConsole displays requery
after resize so a larger console can expose more candidates; all frontends
retain the one-third-prior-output/two-thirds-completion policy.
[x] Rename private "legacy" parser symbols that actually implement the
supported bu_opt descriptor callback contract. Genuine compatibility
aliases remain documented as such, but bu_opt is no longer described as a
retirement shim.
[x] Compile and run qgconsole_completion_modes in the shared Qt-enabled build
after the viewport-budget API change. The test now declares its ProFont
data dependency and tells Qt's offscreen backend where build-tree fonts
are staged.
[x] Restore qged's intended Inconsolata console font. The font survived the
earlier console/resource refactors in the source tree, but its resource
entry and selection logic did not; qged once again embeds and selects it.
Standard help and documentation audit (2026-08-13)
--------------------------------------------------
[x] Add standard synopsis/help builders for bu_opt descriptors, native flat
schemas, native trees, and registered GED commands. Generated schema help
now includes aliases, operands, repeated groups, constraints, keyword
values (with aliases and descriptions), and numeric domains.
[x] Make a shaped multi-token operand appear once in a synopsis. For example,
a packed point or three XYZ words is one semantic `point`, not three
independently optional point values.
[x] Audit production bu_opt users which printed a literal Usage string. Every
such command/program now obtains its option list from bu_opt_help or
bu_opt_usage; the only metadata-free match left by the source audit is an
internal libbv test program.
[x] Convert schema-backed help sites to the standard generators wherever the
metadata describes the executable syntax. The pass touched 197 libged
implementation modules (229 help-producing source sites) and 22 executable
entry points, in addition to shared frontend support modules.
[x] Correct option-definition styling in 35 AsciiDoc man pages. Short and long
spellings are separate bold spans, argument metavariables are italic rather
than part of the option name, and definition-list punctuation is uniform.
All changed pages convert successfully with asciiquack's manpage backend.
[x] Correct the metaball point metadata uncovered by the help audit. Its
execution parser once again accepts both the packed and three-coordinate
forms, including the relative move option, and completion does not
revalidate an individual coordinate as a complete vector.
[x] Add a first-class alternative-form abstraction to libbu. A form should
have a label/description and a complete schema or tree; one form set must
drive validation, parsing, help, JSON, lint, and completion. The private
libged native-form adapter used by who and zap is a useful prototype, but
keeping this concept outside the common metadata leaves commands such as
make_name unable to publish `template` versus `-s [number]` as exclusive
standard synopses. Public form sets now drive selection, validation,
parsing/dispatch, help, JSON, lint, and GED completion adapters; ambiguous
partial forms remain incomplete and merge compatible candidates rather
than becoming prematurely invalid.
[x] Add a declarative grouped-value/form facility for non-vector alternatives,
notably orient's packed quaternion versus four scalar components. The
vector3 shape now documents ordinary packed-or-XYZ points correctly, but a
command-specific count validator remains opaque to help and JSON. Named
argument variants now publish each accepted spelling and token width, and
the standard color, RGB, vector, counted-vector, optional-scalar, orient,
edit, faceplate, and other custom shapes use them.
[x] Complete metadata for parser-owned and dynamically assembled command
families. Search needs human descriptions on its shared term vocabulary;
edit, joint, faceplate, and vdraw need inspectable command/form records;
env needs its list/get/set forms represented rather than a raw root tail.
Search terms now carry shared descriptions; edit publishes its generic
operation tree; joint, faceplate, and vdraw expose their command records;
and env publishes distinct list/get/set forms.
[x] Replace the remaining exact syntax prose in 20 production schema-bearing
libged modules. Most are incomplete nested leaves or mode-dependent
grammars (db, comb, arb/edbot, view objects/polygons, nmg, pnts, qray,
facetize, and related helpers), not simple missed calls to the generator.
Do not delete these strings until their schemas can generate equivalent
output; doing so would make help less correct while concealing missing
specifications. The nested db, comb, arb/BoT, view object/polygon/
faceplate, NMG, pnts, qray, analyze, and facetize paths now generate their
structural help from schemas or form/tree metadata.
[x] Correct executor/metadata mismatches found while replacing the remaining
faceplate help. Rectangle backgrounds are colors, the executable axes
spelling is `axes_color`, Boolean values are limited to zero or one,
positive/nonnegative numeric domains are shared by validation and help,
parameter setters read the supplied value rather than the subcommand name,
and invalid colors/font sizes no longer use uninitialized storage.
[x] Add concise one-sided integer and number range initializers and option/
operand macros so common positive, nonnegative, ceiling, and floor domains
do not need artificial maximum values or custom validators.
[x] Treat generated help metadata as the executable contract rather than
reproducing known defects in historical prose. Correct stale MGED help
exit-status expectations and make invalid hierarchical completion parents
return zero candidates instead of a positive error code that could be
mistaken for a materialized result.
Lower-priority follow-up opportunities
---------------------------------------
These are not recommended as merge blockers. They are deliberately deferred
because the current measured paths are bounded and the additional abstraction
would be a substantially larger API change without a demonstrated caller need.
* Continue opportunistically migrating schema-backed commands that still
assemble usage/options prose by hand. The generator is now the normative
path; command-specific examples, caveats, and extended explanations should
be appended after its output rather than restating syntax. This is ongoing
maintenance rather than a finite merge-readiness defect.
* A public parsed-command/scan object could share work across separate calls to
analysis, validation, option-presence, and completion. Within an individual
completion request the parse is already shared; most callers make only one of
these queries, so a public lifetime-bearing object would currently add more
ownership complexity than saved work.
* Structured candidate records could carry distinct insertion and display
strings. Providers currently return values in their declared token grammar
and frontends own shell/Tcl display encoding. Introduce records only if a
provider needs genuinely different insertion and display values; doing it
speculatively would make every simple provider more verbose.
* Parser-owned languages such as search may eventually expose one inspect tree
for execution, validation, completion, and JSON. They are intentionally
retained as parser-owned grammars today: forcing them into the ordinary
option schema would duplicate their language or turn the compact schema DSL
into a general parser generator.
Deep post-rebase review follow-up (2026-08-14)
----------------------------------------------
[x] Make every BU_CMD_VALUE_CUSTOM parser honor NULL storage as a
side-effect-free validation request. Correct the pnts radius, radii, and
thread-count consumers and test all three through schema validation.
[x] Fully initialize transient bu_cmd_schema records built by the bu_opt
adapters, including cases and terminal-action metadata. Exercise them
with poisoned stack storage in parsing and validation tests.
[x] Release ged_cmd_analysis storage on every completion path, including the
public context result, and add a repeated completion ownership regression.
[x] Make QgConsole completion rows genuinely transient: displaying, resizing,
and removing candidates must never evict or alter permanent console
history, even when the document is at its maximum block count.
[x] Pass QgConsole's complete editable command and cursor byte offset to GED
completion so mid-token and mid-line replacement preserves the suffix.
Apply the same rule to preview filtering.
[x] Recompute MGED wrapped-input erase geometry using the current terminal
width after resize. Cover both narrowing and widening long input.
[x] Separate executable form selection from interactive continuation so a
valid short form does not hide candidates from a viable longer form.
[x] Make command-tree/form dispatch honor the root schema and all child-phase
policies, including root options, fixed operands, aliases, and nesting.
[x] Replace the O(candidate_count * row_count) full-layout search with a
bounded or incremental algorithm and test the narrow/tall maximum-budget
case.
[x] Replace compact bu_opt's repeated prefix validations with one structural
analysis and one custom validation per actual option value.
[x] Bound the database completion cache by retained bytes/candidates, use a
useful eviction policy, and avoid retaining very large materialized query
vectors.
[x] Apply filesystem candidate predicates during the directory scan rather
than materializing an unbounded pre-filter result.
[x] On gsh resize, rebuild both the displayed and selectable completion state
while preserving the selected value when possible.
[x] Avoid repeated DSR timeout delays and preserve non-DSR input bytes when a
terminal does not answer cursor-position queries.
[x] Add one authoritative completion-result merger which preserves limits,
full-set totals, truncation, common prefixes, and deduplication when static
and semantic candidates are combined.
[x] Unify libbu and GED schema linting and run it transactionally on the exact
schema being registered. Diagnose unknown semantic providers without
emitting pre-main log output.
[x] Make rich keyword linting reject every canonical/alias collision,
including a later canonical matching an earlier alias and duplicate
aliases within one row.
[x] Use the shared Boolean reader for syntax validation so validation and
execution agree for empty and malformed attached values.
[x] Define a portable C++ binding policy for schema storage. Keep byte-offset
bindings limited to standard-layout records and provide an explicit
alternative for non-standard-layout command state.
[x] Reuse QgConsole's completion model rather than accumulating parented
QStringListModel objects over repeated updates.
[x] Extend the focused and stress suites to cover every defect above, then run
the all-target Ninja build, completion/schema/frontend suites, repository
regression, and git diff checks.
Post-squash deep review follow-up (2026-08-14)
-----------------------------------------------
[x] Preserve an explicit decoded-byte-to-raw-byte boundary map while MGED
normalizes Tcl words for completion. Use that map for replacement and
cursor offsets so quoting and backslash substitution cannot corrupt the
original command. Cover quoted words, escaped spaces, escaped slashes and
backslashes, UTF-8, and mid-token suffixes; the current m35.g reproducer
turns `draw component\/suspension/r2` into
`draw component\/suspensionr22`.
[x] Make dynamic command and schema loading one retained, transactional
operation. Never register schema pointers from the temporary inspection
handle when the generalized plugin load failed, and do not publish an
executable command if its metadata is malformed. Add a plugin fixture
with a rejected generic manifest and an otherwise readable schema
manifest to guard against dangling registry pointers.
[x] Publish each command implementation, compatibility alias, and exactly one
metadata kind atomically. Treat duplicate metadata as part of the same
first-wins decision, roll back on failure, serialize initialization
diagnostics, and stress simultaneous duplicate registration to prove that
an implementation cannot be paired with another declaration's schema.
[x] Make built-in semantic-provider ownership independent of call order.
Install built-ins before accepting public registrations, reserve the
`ged.*` namespace (or require an explicit override policy), and test an
attempted built-in-name registration before the first lookup.
[x] Give semantic providers a complete C-facing contract. Publish their
result value type and capability flags in the provider record rather than
classifying built-ins with string comparisons, document candidate/result
ownership, and keep the implementation free to own registration records
with C++17 RAII. Ensure shutdown removes custom provider data before its
documented lifetime ends.
[x] Define and test libged lifecycle semantics. Either make shutdown a
synchronized terminal state which rejects every later registry operation,
or make initialization and teardown repeatable; do not leave command,
schema, or semantic-provider registries in different generations. Clear
metadata before unloading the modules which own its callback and string
pointers.
[x] Compute every full-set common prefix on a valid UTF-8 boundary in the
shared completion layer rather than repairing it in individual
frontends. Make QgConsole's command, candidate, and source-offset
conversions explicitly UTF-8 instead of locale-dependent local-8-bit
conversions, and cover candidates whose first differing code points share
an initial UTF-8 byte.
[x] At an empty search path/expression position, merge bounded database-path
candidates with the valid static search options and expression terms.
Preserve hidden-object policy and exact total/truncation/common-prefix
metadata while ensuring `_GLOBAL` remains excluded from ordinary search
path completion.
[x] Validate and normalize semantic-provider output at the registry boundary:
candidate pointer/count consistency, total count no smaller than the
materialized count, truncation consistency, bounded materialization, and a
valid full-set common prefix. Clamp frontend summary arithmetic as a
defensive fallback and add malformed-provider tests.
[x] Reduce compact GED declaration boilerplate without inferring semantic
aliases from storage or help text. One typed GED_RULE_* table now holds
aliases, forms, database roles/type cases, semantic refinements,
constraints, and validators and is normalized into owned schema storage
once at registration. All 17 production sources which formerly needed
compact metadata sidecars use the table, identical metadata can name
multiple options in one row, and all 40 BU_OPT_DESC_BUILDER definitions
use the concise BU_OPT_* field-binding rows wherever the callback binds an
ordinary argument field. The remaining raw rows intentionally pass the
whole argument record to custom readers. Explicit compatibility aliases
are covered by registry JSON tests rather than guessed from shared
storage; the source audit prevents a return to per-kind sidecars or raw
conditional field bindings.
[x] Consolidate the duplicated bu_opt-to-native-schema adapter logic in libbu
and libged so type, arity, optional-value, shaped-value, alias, validator,
and standard-candidate inference have one implementation. Likewise share
and cache search's immutable type vocabulary instead of rebuilding and
maintaining it in both the generic provider and parser-owned grammar.
[x] Resolve aliases during the shared adapter build. An alias inherits the
canonical option's type, shape, cardinality, candidates, validator,
semantic role, and argument requirement unless it explicitly overrides
presentation metadata. Reject unknown targets and cycles, remove the
typed-alias workaround, and verify parse/help/JSON/completion equivalence
for standard and opaque option readers.
[x] Make flat-rule declarations counted. Add a rule count to ged_opt_spec,
derive it in declaration macros, and stop reading caller memory in search
of a missing sentinel. Preserve GED_RULE_NULL as an optional readability
marker only if doing so cannot conceal an incorrect count.
[x] Make the first broad root completion scale as well as repeated queries.
Add a genuinely cold 100k-object test, then replace the per-entry map build
and full matching-range scan for built-in policies with a prefix-oriented
index carrying aggregate count/common-prefix metadata and bounded ordered
materialization. Retain a scan fallback for arbitrary candidate filters
and verify database mutation invalidation.
[x] Debounce QgConsole semantic highlighting so ordinary edits do not
synchronously reparse the entire command on every keystroke. Split the
largest new implementation and test files by responsibility after the API
behavior is settled, preserving the existing focused and scaling
coverage.
[x] Modularize the corrected implementation along useful ownership boundaries.
Database completion generations and command-input parsing now have focused
C++17 modules; the immutable search vocabulary belongs to librt; registry
lifecycle/plugin transactions and scaling have independent tests; MGED and
QgConsole retain their frontend-offset suites. Keep the public libbu and
libged boundaries C-only and document the new public adapter functions.
Steady-state review follow-up (2026-08-14)
------------------------------------------
[x] Extend the libged activity lease beyond command execution. Help, JSON,
lint, validation, analysis, completion, form/tree adapters, and semantic
provider callbacks must remain valid while shutdown waits; registrations
attempted during teardown must be rejected deterministically.
[x] Enforce one metadata representation across every registration entry point,
reject malformed or reserved command names before normalization can split
implementation and metadata keys, and cover direct-API collisions.
[x] Preserve natural candidate ordering for bounded broad-prefix index queries.
Replace the lexical fast-path with a range-minimum natural-rank index so a
100,000-match query remains O(log N + K log N) without changing behavior.
[x] Reject truncated semantic-provider results that cannot prove a valid UTF-8
common prefix for the complete filtered set, and add a malformed bounded
provider regression.
[x] Give ged_cmd_lookup a stable documented result lifetime and omit synthetic
`_mged_` aliases; its current pointer refers to a destroyed foreach
snapshot as soon as the function returns.
[x] Propagate parser, grammar, and semantic-provider failures through the
bounded completion API; reject inconsistent truncated materializations,
distinguish a valid empty common prefix from missing metadata, and remove
the arbitrary 65,536-entry ceiling from explicitly unbounded queries.
[x] Make outward-facing validation, analysis, and completion metadata strings
result-owned before releasing the registry lease. Fix the command-name
completion snapshot leak, retain repeated analysis strings in one
deduplicated allocation instead of two allocations per token, and verify
retained results remain valid across shutdown and repeated clear
operations.
[x] Remove quadratic compact-schema highlighting. Resolve option-selected DB
providers once per complete argv with a private analysis plan, apply later
context options consistently to earlier operands, and cover a 5,000-value
`ls ... -a` analysis workload.
[x] Finish the completion-index and metadata ownership cleanup. Build policy,
natural-order, and range-minimum views only when requested; share the DB
path encoder and object-policy predicate rather than maintaining parallel
copies; make command-list snapshots explicitly owned/NULL-terminated; and
require every parser-owned grammar to provide generated help. Give the
analysis result the same explicit initializer/reusable-result contract as
validation and completion results.
[x] Release the temporary argv used by filtered bu_opt help generation; the
richer standard-help path makes repeated filtered descriptions a normal
API use rather than a one-shot process-lifetime allocation.
[x] Release gsh's owned command-list snapshot after `--command-schema all`;
the newly explicit ged_cmd_list ownership contract applies to early-exit
introspection paths as well as interactive completion. Update the schema
round-trip and plugin-enumeration tests to follow the same contract.
[x] Make natural completion ordering a total order. Numerically equivalent
spellings such as `1` and `01` must have a deterministic lexical tiebreak
so bounded index queries, heaps, and full-result normalization agree; use
relational comparison rather than overflowing unsigned subtraction for
maximum-width numeric suffixes.
[x] Enforce exact truncated-result metadata at the final completion boundary,
not only for named semantic providers. Parser-owned grammar callbacks
must supply a full-set total and allocated (possibly empty) common prefix;
never derive insertion text from an arbitrary displayed subset. Apply
the same UTF-8, prefix, uniqueness, filter, budget, and natural-order
normalization to grammar materializations as to named providers.
[x] Make every reusable public validation, analysis, and completion result
transactional on failure. Clear old contents before argument/lifecycle
checks and clear partially populated grammar/tree/form callback output on
error, so frontends never retain stale metadata or need callback-specific
failure cleanup. Exercise deliberately failing grammar callbacks and an
invalid bounded-completion request with previously populated results.
[x] Clamp cursor offsets once at the shared command-input parser boundary so
validation adapters cannot publish source spans beyond the supplied input
when an editor reports a stale or oversized cursor position.
[x] Make natural ordering independent of machine integer width and C numeric
syntax. Compare arbitrary-length decimal digit runs directly, retain a
deterministic lexical tiebreak for equivalent zero-padded spellings, and
cover values beyond ULONG_MAX in bounded and unbounded indexed queries.
[x] Enforce the counted flat-rule contract. A retained GED_RULE_NULL visual
terminator is valid only as the final counted row; reject a premature END
rather than silently hiding subsequent author declarations.
[x] Apply the reusable-result transaction contract uniformly at the libbu
boundary. Descriptor, builder, schema, shaped-value, tree, and form
validation now release stale and partially callback-populated candidates
on every failure. An empty command-schema result reports an unknown role
rather than misleadingly defaulting to string; focused tests reuse seeded
results across invalid arguments, builder failures, and failing callbacks.
[x] Bound the database index's policy-view cache, not only its returned
candidate vectors. Ignore unsupported flag bits when selecting a view
and evict least-recently-used O(database-size) policy arrays after a fixed
limit; exercise normalization and eviction against the 100,000-object
database.
[x] Document borrowed registration lifetimes consistently for command,
native-schema, compact-schema, grammar, and semantic-provider metadata,
including the transactional failure rule for parser-owned callbacks.
[x] Re-run the all-target build, focused 100,000-object and lifecycle races,
exhaustive completion corpus, frontend tests, repository/license checks,
and final diff audit after these fixes.
Verification notes
------------------
* The final steady-state pass completes warnings-as-errors all-target rebuilds
after the result-ownership and bounded policy-cache fixes (1,168 actions for
the consistent rebuild and 154 actions after the last source audit). All
126 selected libbu, schema, lifecycle, 100,000-object, exhaustive corpus,
Qt, gsh, MGED GUI/PTY, native-source, repository, license, and change-policy
tests pass in 14.19 seconds. The cold scale test, including 64 policy-cache
probes, finishes in 6.90 seconds. Focused Memcheck runs report no definite
leaks or invalid accesses for command schemas, failing bu_opt callbacks, or
registry/plugin shutdown. git diff --check is clean.
* The final post-squash implementation completes a 1,607-action all-target
Ninja rebuild. The 125-test focused selection passes in full after the new
lifecycle test was brought into repository-policy compliance: all bu_opt
and command-schema tests, both command-analysis datasets, the exhaustive
completion corpus, the cold 100,000-object scale test, registry/plugin
lifecycle transactions, Qt console behavior, gsh and MGED terminal/GUI
paths, native-schema source audit, license and change-policy checks, and
regress-repository. The scale test takes 5.12 seconds including database
construction, and the completion corpus takes 11.88 seconds.
* The post-squash follow-up adds a cold 100,000-object root benchmark, a
rejected-manifest plugin fixture, concurrent command/schema publication,
repeatable shutdown/provider cleanup, counted-rule, alias-chain, malformed
provider, UTF-8, Tcl quoting/backslash, Qt debounce, and search-union
regressions. The focused completion-scale test finishes in under four
seconds in the unoptimized warnings-as-errors build; warm broad-prefix
materialization is required to remain below 250 ms.
* The compact-rule and option-row cleanup completes an all-target Ninja build
and passes all 135 focused libbu option/schema/help, GED command/completion,
Qt console, gsh, MGED, source-audit, repository, license, and change-policy
tests. Runtime schema checks cover every compact command alias declaration,
and git diff --check is clean.
* The 2026-08-14 post-rebase follow-up completes an all-target Ninja build and
passes all 118 focused bu_opt, schema, file, line-editor, command-analysis,
completion-corpus, Qt console, gsh, MGED, and source-audit tests. The
repository and license regressions pass, and git diff --check is clean.
* The post-review all-target Ninja rebuild completes successfully. The final
focused pass covers all 100 libbu schema/bu_opt/line-editor tests, both
libged command-analysis suites, seven gsh/MGED terminal completion tests,
the MGED completion bridge, and the repository and license regressions.
git diff --check is clean.
* The final help/form follow-up completes a 1,762-action all-target Ninja
rebuild and passes 118 focused schema, bu_opt, completion-corpus, Qt console,
gsh, MGED, and license tests, plus regress-repository.
* The Ninja build completes successfully.
* The schema, command-analysis, completion-corpus, gsh PTY, MGED PTY/bridge,
bu_opt compatibility, BoT, license, and repository regression tests pass.
* The gsh resize/cursor PTY test passes repeatedly to exercise its timing path.
* The shared Qt-enabled Debug build compiles qged and libqtcad with warnings as
errors and passes qgconsole_completion_modes using its declared build-tree
font dependency.
* A post-rebase full 1,277-test CTest run completed with 1,274 passes. One
failure is the intentional test-target sentinel. The native-schema source
audit exposed an over-broad policy check and now passes after limiting the
bu_opt exemption to a non-command scalar-reader source. slow-bigdb_5gb was
killed under the eight-way full-suite memory load and passed alone in 70.6
seconds. All other tests, including bu_process_all, both fbserv stress
tests, changes-rules, GQA, and all drawing tests, passed in the full run.
* The fbserv quick and heavy stress suites pass ten consecutive runs with both
suites launched concurrently after assigning automatic invocations disjoint
bounded port slots.
* The MGED GUI binding test and all MGED CLI/completion tests pass after the
Configure binding correction; repository and license regressions also pass.
* All 97 bu_opt tests and both command-analysis suites, including the m35.g
completion corpus, pass with the compact positional DSL enabled.
* On m35.g in the Debug build, `ls ` completion generation drops from about
5.15 seconds to 11 milliseconds. A 100-column, 30-row summary drops from
about 486 to 315 milliseconds; the normal two-row GUI budget takes about 14
milliseconds. Empty `ls ` completion contains objects only, while `ls --`
offers all ten long options.
* The deep-review final tree completes the all-target Ninja build, passes
git diff --check and regress-repository, and passes all 118 targeted libbu,
schema, command-analysis, completion-corpus, gsh, and MGED tests. The
100,000-object analysis/scaling test, including the broad empty-prefix
`ls /` case, `draw /`, composite geometry-or-primitive queries, and cache
mutation checks, finishes in about 2.9 seconds. The 10,000-candidate/100-row
layout test finishes as part of a 0.27-second line-editor test.
* A focused Memcheck replay of the delegated `blast` grammar passes after
correcting its transferred common-prefix ownership. The exhaustive native
completion corpus passes in 11.4 seconds; its optional whole-corpus Memcheck
run was stopped after more than twelve CPU-bound minutes with stable memory
and no diagnostics.
-7
View File
@@ -1,7 +1,6 @@
function(G_TARGET in_model folder)
# Initialize
set(MODEL_TYPE "UNKNOWN")
set(CONV_SUCCESS_CODES 0)
# Regardless of what we decide, let CMake know about the file
cmakefiles(${CMAKE_CURRENT_SOURCE_DIR}/${in_model})
@@ -26,7 +25,6 @@ function(G_TARGET in_model folder)
# Find our output file and path
string(REPLACE "${CMAKE_SOURCE_DIR}/" "" rel_dir "${CMAKE_CURRENT_SOURCE_DIR}")
set(output_file ${DATA_DIR}/${rel_dir}/${in_model_root}.g)
set(CONV_OUTPUT_PATH "${CMAKE_BINARY_DIR}/${output_file}")
set(log_file ${CMAKE_CURRENT_BINARY_DIR}/${in_model_root}.log)
# Make sure the output db target directory is there
@@ -118,10 +116,6 @@ function(G_TARGET in_model folder)
return()
endif(NOT TARGET step-g)
set(CONV_ARGS "-O \"${CMAKE_BINARY_DIR}/${output_file}\" \"${CMAKE_CURRENT_SOURCE_DIR}/${in_model}\"")
# step-g uses status 1 for useful, deliberately published partial output.
# Installed sample databases should retain that geometry; statuses 2 and
# above, or a missing output file, remain build failures.
set(CONV_SUCCESS_CODES "0;1")
configure_file("${CMAKE_SOURCE_DIR}/db/to_g.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/${in_model_root}.cmake" @ONLY)
distclean("${CMAKE_CURRENT_BINARY_DIR}/${in_model_root}.cmake")
# Custom command to generate the output
@@ -209,7 +203,6 @@ set(
demo.asc
die.asc
earth.asc
gaia.asc
galileo.asc
goliath.asc
havoc.asc
-78680
View File
File diff suppressed because it is too large Load Diff
+119 -358
View File
File diff suppressed because one or more lines are too long
+2 -4
View File
@@ -35,12 +35,10 @@ execute_process(
ERROR_VARIABLE conv_log
)
set(conv_success_codes "@CONV_SUCCESS_CODES@")
list(FIND conv_success_codes "${conv_result}" conv_result_index)
if(conv_result_index EQUAL -1 OR NOT EXISTS "@CONV_OUTPUT_PATH@")
if(conv_result)
set(CARGS @CONV_ARGS@)
message(FATAL_ERROR "[@in_model_root@] Failure: ${conv_result}\n${CONV_EXEC} ${CARGS}\"\n\n${conv_log}")
endif()
endif(conv_result)
# Cleanup
execute_process(
+2 -3
View File
@@ -13,6 +13,8 @@ set(
README.MacOSX
README.Windows
README.BSD
README.Solaris
README.VAX
checklist.txt
description.txt
optimization_ideas.adoc
@@ -27,7 +29,6 @@ set(
notes/editors.txt
notes/history.txt
notes/hypot.txt
notes/itcl4_migration.txt
notes/mater.txt
notes/matrix.txt
pre_BRL-CAD.bib
@@ -216,8 +217,6 @@ endif(TARGET mged)
cmakefiles(
CMakeLists.txt
README.Solaris
README.VAX
README.adoc
STARTERS
STRATEGY
-4
View File
@@ -1,7 +1,3 @@
*** ARCHIVED -- legacy platform, no longer supported (retained for
*** historical reference). This document is not installed and is kept
*** only to preserve the historical record.
BRL-CAD on Solaris README
=========================
There have been a variety of Solaris-style operating systems that appeared
-4
View File
@@ -1,7 +1,3 @@
*** ARCHIVED -- legacy platform, no longer supported (retained for
*** historical reference). This document is not installed and is kept
*** only to preserve the historical record.
BRL-CAD on VAX README
=====================
+2 -2
View File
@@ -33,7 +33,7 @@ toc::[]
=== Prerequisites
To build BRL-CAD from source, you will need:
* **CMake** (3.26+)
* **CMake** (3.14+)
* **C/C++ Compiler** (GCC, Clang, or MSVC)
* **Build Tools** (Make, Ninja, or Visual Studio)
@@ -53,7 +53,7 @@ For detailed installation instructions across different platforms, please refer
== Documentation
We have consolidated our extensive documentation (formerly a mix of DocBook/XML, MediaWiki, troff, plain text, and more) onto **AsciiDoc**, with the authoritative sources under `doc/asciidoc/`.
We are currently transitioning our extensive documentation (Docbook/XML + MediaWiki + troff + text + ...) to an **Antora-powered ecosystem**.
* **Tutorials:** link:{docs-url}/tutorials[Browse the Manuals]
* **Developer Guides:** link:{docs-url}/hacking and link:{repo-url}/blob/main/HACKING
-1
View File
@@ -1,6 +1,5 @@
include(${BRLCAD_CMAKE_DIR}/AsciiDoc.cmake)
verbose_add_subdirectory(asciidoc toplevel)
verbose_add_subdirectory(asciidoc system)
verbose_add_subdirectory(asciidoc articles)
verbose_add_subdirectory(asciidoc books)
+31 -19
View File
@@ -4,14 +4,15 @@
== Overview
This directory contains BRL-CAD documentation in AsciiDoc format. The `.adoc`
files here are the authoritative documentation sources and are committed to
version control. The one-time conversion from the original DocBook 5 XML
sources is complete, and those legacy XML sources have been removed; edit the
`.adoc` files directly.
This directory contains BRL-CAD documentation in AsciiDoc format, converted
from the original DocBook 5 XML sources in `../docbook/`. The conversion was
performed once using
link:../../misc/tools/db2adoc/db2adoc.xsl[db2adoc.xsl] (an XSLT stylesheet)
applied via `xsltproc`.
The `.adoc` files are built into HTML and man-page outputs at compile time
using **asciiquack**, BRL-CAD's self-contained AsciiDoc processor.
The `.adoc` files here are committed to version control as authoritative
sources. They are built into HTML and man-page outputs at compile time using
**asciiquack**, BRL-CAD's self-contained AsciiDoc processor.
== Directory Structure
@@ -42,17 +43,28 @@ When `BRLCAD_EXTRADOCS=ON` is set at CMake configuration time:
The build logic is in `brlcad/misc/CMake/AsciiDoc.cmake`.
== Authoritative Sources
== Re-running the Conversion
The `.adoc` files in this directory are the authoritative documentation
sources. The one-time conversion from the retired DocBook 5 XML sources is
complete, so there is no conversion step to re-run: make all documentation
changes by editing the `.adoc` files directly.
If the upstream DocBook sources change and you need to re-generate the AsciiDoc
files, run the XSLT stylesheet from the repository root:
[NOTE]
====
Documentation is built only when CMake is configured with
`BRLCAD_EXTRADOCS=ON`. With the default configuration the documentation
targets are skipped, so remember to enable this option when working on or
verifying documentation.
====
[source,bash]
----
BEXT=/path/to/bext_output
for f in $(find doc/docbook -name "*.xml" -not -path "*/resources/*"); do
rel=${f#doc/docbook/}
out=doc/asciidoc/${rel%.xml}.adoc
mkdir -p "$(dirname "$out")"
$BEXT/noinstall/bin/xsltproc -xinclude \
misc/tools/db2adoc/db2adoc.xsl "$f" > "$out"
done
----
Alternatively, use `db2adoc.py` (requires pandoc ≥ 2.0) for a Python-driven
approach with better round-trip fidelity for complex markup:
[source,bash]
----
python3 misc/tools/db2adoc/db2adoc.py
----
+9 -66
View File
@@ -13,14 +13,12 @@ set(
mged.adoc
mgedrc.adoc
nirt.adoc
object_types.adoc
oed.adoc
overlap_tool.adoc
pipes.adoc
procedural_geometry.adoc
projection_shader.adoc
renderer_showcase.adoc
taxonomy.adoc
tire.adoc
)
@@ -227,72 +225,20 @@ set(
images/renderer_gallery_rthide.png
images/renderer_gallery_rtdepth.png
images/renderer_gallery_rtxray.png
images/adrt_castle_path.png
images/adrt_castle_rt.png
images/adrt_castle_rt_ao.png
images/adrt_toyjeep_path.png
images/adrt_toyjeep_rt.png
images/adrt_toyjeep_rt_ao.png
images/adrt_toyjeep_phong.png
images/adrt_toyjeep_normal.png
images/adrt_toyjeep_depth.png
images/adrt_chess_path.png
images/adrt_chess_rt.png
images/adrt_chess_rt_ao.png
images/adrt_castle_path.png
images/adrt_castle_rt.png
images/adrt_castle_rt_ao.png
images/adrt_cornell_path.png
images/adrt_cornell_phong.png
images/adrt_toyjeep_depth.png
images/adrt_toyjeep_normal.png
images/adrt_toyjeep_path.png
images/adrt_toyjeep_phong.png
images/adrt_toyjeep_rt.png
images/adrt_toyjeep_rt_ao.png
images/adrt_toyjeep_spall.png
images/objtype_arb8.png
images/objtype_arb8_variety.png
images/objtype_arbn.png
images/objtype_arbn_variety.png
images/objtype_ars.png
images/objtype_bot.png
images/objtype_bot_variety.png
images/objtype_brep.png
images/objtype_cline.png
images/objtype_comb_variety.png
images/objtype_dsp.png
images/objtype_ebm.png
images/objtype_ehy.png
images/objtype_ehy_variety.png
images/objtype_ell.png
images/objtype_ell_variety.png
images/objtype_epa.png
images/objtype_epa_variety.png
images/objtype_eto.png
images/objtype_eto_variety.png
images/objtype_extrude.png
images/objtype_half.png
images/objtype_hrt.png
images/objtype_hrt_variety.png
images/objtype_hyp.png
images/objtype_hyp_variety.png
images/objtype_metaball.png
images/objtype_metaball_variety.png
images/objtype_nmg.png
images/objtype_part.png
images/objtype_part_variety.png
images/objtype_pipe.png
images/objtype_pipe_variety.png
images/objtype_pnts.png
images/objtype_rcc.png
images/objtype_rec.png
images/objtype_revolve.png
images/objtype_rhc.png
images/objtype_rhc_variety.png
images/objtype_rpc.png
images/objtype_rpc_variety.png
images/objtype_sph.png
images/objtype_submodel.png
images/objtype_superell.png
images/objtype_superell_variety.png
images/objtype_tgc.png
images/objtype_tgc_variety.png
images/objtype_tor.png
images/objtype_tor_variety.png
images/objtype_trc.png
images/objtype_vol.png
)
if(TARGET mged OR TARGET qged OR TARGET archer)
if(BRLCAD_EXTRADOCS)
@@ -471,9 +417,6 @@ cmakefiles(
gallery/inputs/moss64.pix
gallery/inputs/caffeine.pdb
gallery/inputs/mol-cube.dat
images/objtype_src/README.adoc
images/objtype_src/objtype_lib.py
images/objtype_src/gen_object_types.py
)
add_subdirectory(hy)
+3 -3
View File
@@ -71,11 +71,11 @@ More paragraphs...
[CAUTION]
====
There's a lot more you can do with AsciiDoc. Consult the reference documentation for syntax and examples:
There's a lot more you can do with Docbook/XML. Search the web for references and examples:
* https://docs.asciidoctor.org/asciidoc/latest/[AsciiDoc Language Documentation]
* https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/[AsciiDoc Syntax Quick Reference]
* http://www.docbook.org/tdg5/en/html/article.html[http://www.docbook.org/tdg5/en/html/article.html]
* http://www.openoffice.org/xml/xmerge/docbook/UserGuide.html[http://www.openoffice.org/xml/xmerge/docbook/UserGuide.html]
====
+1 -1
View File
@@ -43,7 +43,7 @@ part.s22 part.s22-1 part.s23 part.s24 part.s24+1 part.s24-1 part.s25,
....
one needs to determine the span. Note that the leftmost numbers in these primitives range from 22 to 25. The span is the count of distinct leftmost numbers taken inclusively, from the lowest through the highest: 22, 23, 24, and 25 -- four values in all. It is computed as (highest - lowest) + 1, that is, (25 - 22) + 1 = 4. If we use an increment of four, each leftmost number is shifted up by four (22 becomes 26, 23 becomes 27, and so on), and we will get the following set of primitives.
one needs to determine the span. Note that the leftmost numbers in these primitives range from 22–25.Thus, as shown in the following expression, the span is four (inclusively). *******NEED FIGURE HERE***** If we use an increment of four, we will get the following set of primitives.
....
+1 -1
View File
@@ -55,7 +55,7 @@ u wgn.s2 + wgn.s2+1 - wgn.s2-1
....
If we wanted to make a second subtraction from wgn.s2--say, for a drain hole in the corner of the wagon--we would name that primitive wgn.s2-2, as shown in <<build_region9>>. We can break this name down as follows: the root name `wgn` identifies the region; `.s2` is the base solid the operation applies to; and the trailing `-2` marks this as the second subtraction from that solid (the first having been `wgn.s2-1`).
If we wanted to make a second subtraction from wgn.s2--say, for a drain hole in the corner of the wagon--we would name that primitive wgn.s2-2 (see Figure F-3). We can break this name down as follows: *****NEED IMAGE HERE*****
[[build_region9]]
.The region and the subtraction primitives.
@@ -49,7 +49,7 @@ set(GALLERY_DEMO_14 [=[masonry_sheetrock|Architecture & structural|exec|masonry|
set(GALLERY_DEMO_15 [=[masonry_brick|Architecture & structural|exec|masonry|-t brick -u in -w 96,48 -n wall|@GLOB@|r.wall.b||ao|masonry wall generator, brick wall type (prototype brick).]=])
set(GALLERY_DEMO_16 [=[masonry_bm|Architecture & structural|exec|masonry|-t bm -u in -w 96,48 -m 0.25 -n wall|@GLOB@|r.wall.b||ao|masonry wall generator, mortar-brick wall type: brick with horizontal and vertical mortar joints.]=])
set(GALLERY_DEMO_17 [=[brickwall|Architecture & structural|tomged|brickwall||@OUT@|g.brick||ao|Builds a brick wall: emits mged commands that create RPP brick solids arranged in rows (with optional mortar slabs between them) to fill a specified wall width and height. Output is a stream of mged commands on stdout, not a .g directly.]=])
set(GALLERY_DEMO_18 [=[mkbuilding|Architecture & structural|exec|mkbuilding|@OUT@|@OUT@|house||ao|Generates a physically dimensioned building with material-separated walls, slabs, framed openings, roof, and optional structural members; JSON, OSM, and CityJSON specifications can produce full building catalogs.]=])
set(GALLERY_DEMO_18 [=[mkbuilding|Architecture & structural|exec|mkbuilding|@OUT@|@OUT@|all||ao|Procedurally builds a small building: a floor slab, four framed walls with openings, and an overhanging roof.]=])
set(GALLERY_DEMO_19 [=[cchannel|Architecture & structural|exec|cchannel|-f @OUT@ -H 0.2|@OUT@|channel.r||ao|Creates a section of fully configurable C-channel (structural metal beam). Default is a 1" diameter by 12" long section of American standard C-channel, here generated with a row of drilled holes.]=])
set(GALLERY_DEMO_20 [=[ringworld|Architecture & structural|exec|ringworld|-o @OUT@|@OUT@|all.g||ao|Generates a "ringworld" as imagined by Larry Niven: a central sun sphere and a large CSG ring (built from three RCCs) orbiting it, combined into a top-level group all.g.]=])
+7 -254
View File
@@ -49,66 +49,7 @@ The following code illustrates a basic use of GCV from within an application. No
.gcv_app.c
[example]
====
[source,c]
----
#include "common.h"
#include "bu/log.h"
#include "bu/mime.h"
#include "gcv.h"
/* Convert the file at 'in_path' to the file at 'out_path', selecting the
* first registered reader and writer filter that match the file types
* inferred from the two path extensions. Returns 0 on success. */
int
convert(const char *in_path, const char *out_path)
{
struct gcv_context context;
const struct gcv_filter *in_filter, *out_filter;
bu_mime_model_t in_type, out_type;
/* Infer the model file types from the filename extensions. */
in_type = (bu_mime_model_t)bu_file_mime(in_path, BU_MIME_MODEL);
out_type = (bu_mime_model_t)bu_file_mime(out_path, BU_MIME_MODEL);
/* A context holds the conversion state, including an in-memory
* database used for the intermediate representation. */
gcv_context_init(&context);
/* Look up a reader for the input type and a writer for the output
* type. find_filter() returns the first matching registered filter,
* or NULL if none is available. */
in_filter = find_filter(GCV_FILTER_READ, in_type, in_path, &context);
out_filter = find_filter(GCV_FILTER_WRITE, out_type, NULL, &context);
if (!in_filter || !out_filter) {
bu_log("No filter available for the requested conversion\n");
gcv_context_destroy(&context);
return 1;
}
/* Read the input into the context's in-memory database. Passing NULL
* for the options selects the defaults from gcv_opts_default(). The
* argc/argv pair would carry any filter-specific option strings.
* gcv_execute() returns 1 on success and 0 on failure. */
if (!gcv_execute(&context, in_filter, NULL, 0, NULL, in_path)) {
bu_log("Read filter '%s' failed for '%s'\n", in_filter->name, in_path);
gcv_context_destroy(&context);
return 1;
}
/* Write the in-memory database out through the selected writer. */
if (!gcv_execute(&context, out_filter, NULL, 0, NULL, out_path)) {
bu_log("Write filter '%s' failed for '%s'\n", out_filter->name, out_path);
gcv_context_destroy(&context);
return 1;
}
gcv_context_destroy(&context);
return 0;
}
----
TODO: embedded code
====
@@ -224,57 +165,7 @@ LIBGCV_ADD_PLUGIN(foo "foo_read.c" "librt;libbu")
.foo_read.c
[example]
====
[source,c]
----
#include "common.h"
#include "bu/log.h"
#include "bu/mime.h"
#include "gcv/api.h"
#include "wdb.h"
/* The reader callback. For a GCV_FILTER_READ filter, 'target' is the
* path of the input file, and geometry should be written into the
* in-memory database reachable through context->dbip. Return 1 on
* success and 0 on failure. */
static int
foo_read(struct gcv_context *context, const struct gcv_opts *gcv_options,
const void *UNUSED(options_data), const char *target)
{
struct rt_wdb *wdbp;
if (gcv_options->verbosity_level)
bu_log("Reading foo file: %s\n", target);
/* Open the context's in-memory database for writing. */
wdbp = wdb_dbopen(context->dbip, RT_WDB_TYPE_DB_INMEM);
mk_id_units(wdbp, "Converted from foo format", "mm");
/* ... parse 'target' and create objects with the wdb (mk_*) API,
* e.g. mk_sph(), mk_bot(), mk_lcomb() ... */
return 1;
}
/* Describe the filter: a unique name, its type, the model type it
* handles, and the callbacks. This reader defines no filter-specific
* options, so the create/free option hooks and data_supported are NULL. */
static const struct gcv_filter gcv_conv_foo_read = {
"FOO Reader", GCV_FILTER_READ, BU_MIME_MODEL_FOO, NULL,
NULL, NULL, foo_read
};
/* A plugin exports a NULL-terminated array of its filters ... */
static const struct gcv_filter * const filters[] = {&gcv_conv_foo_read, NULL};
/* ... referenced by a struct gcv_plugin ... */
static const struct gcv_plugin gcv_plugin_info_s = { filters };
/* ... which libgcv discovers by dlsym()-ing this exported entry point. */
COMPILER_DLLEXPORT const struct gcv_plugin *
gcv_plugin_info(void) { return &gcv_plugin_info_s; }
----
TODO: embedded code
====
@@ -301,89 +192,7 @@ The following example implements a filter that tessellates all geometry into BoT
.tessellation_statistics.c
[example]
====
[source,c]
----
#include "common.h"
#include "bu/log.h"
#include "bu/mime.h"
#include "nmg.h"
#include "rt/geom.h"
#include "raytrace.h"
#include "gcv/api.h"
#include "gcv/util.h"
/* State shared with the region-end callback. */
struct tess_stats {
size_t face_count;
};
/* Invoked once per region by gcv_region_end() after the region's leaf
* meshes have been Boolean-evaluated into a single NMG region 'r'. Here
* we simply tally the outward-facing (OT_SAME) faces. This routine must
* be prepared to run in parallel. */
static void
count_region_faces(struct nmgregion *r, const struct db_full_path *UNUSED(pathp),
struct db_tree_state *UNUSED(tsp), void *client_data)
{
struct tess_stats *stats = (struct tess_stats *)client_data;
struct shell *s;
NMG_CK_REGION(r);
for (BU_LIST_FOR(s, shell, &r->s_hd)) {
struct faceuse *fu;
for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) {
if (fu->orientation != OT_SAME)
continue;
bu_semaphore_acquire(BU_SEM_GENERAL);
stats->face_count++;
bu_semaphore_release(BU_SEM_GENERAL);
}
}
}
/* A GCV_FILTER_FILTER receives a NULL target and operates on the geometry
* already present in context->dbip. Return 1 on success, 0 on failure. */
static int
tessellation_statistics(struct gcv_context *context, const struct gcv_opts *gcv_options,
const void *UNUSED(options_data), const char *UNUSED(target))
{
struct tess_stats stats = {0};
struct gcv_region_end_data end_data;
struct db_tree_state tree_state;
struct model *the_model = nmg_mm();
/* Configure the tree-walk state: tolerances come from the conversion
* options, and ts_m provides the NMG model used during tessellation. */
RT_DBTS_INIT(&tree_state);
tree_state.ts_tol = &gcv_options->calculational_tolerance;
tree_state.ts_ttol = &gcv_options->tessellation_tolerance;
tree_state.ts_m = &the_model;
/* gcv_region_end() expects its client_data to point at this struct. */
end_data.write_region = count_region_faces;
end_data.vlfree = &rt_vlfree;
end_data.client_data = &stats;
/* Walk every top-level object. Leaves are tessellated to BoTs by
* rt_booltree_leaf_tess(); gcv_region_end() then Boolean-evaluates
* each region and invokes our callback with the result. */
(void)db_walk_tree(context->dbip, (int)gcv_options->num_objects,
(const char **)gcv_options->object_names, 1, &tree_state,
NULL, gcv_region_end, rt_booltree_leaf_tess, &end_data);
bu_log("Total faces after tessellation: %zu\n", stats.face_count);
return 1;
}
static const struct gcv_filter gcv_conv_tess_stats = {
"Tessellation Statistics", GCV_FILTER_FILTER, BU_MIME_MODEL_AUTO, NULL,
NULL, NULL, tessellation_statistics
};
----
TODO: embedded code
====
@@ -441,51 +250,7 @@ The following example will leverage the filter in the above plugin example, `tes
.gcv_embedded.c
[example]
====
[source,c]
----
#include "common.h"
#include "bu/log.h"
#include "bu/mime.h"
#include "gcv.h"
/* Defined in tessellation_statistics.c, above. */
extern const struct gcv_filter gcv_conv_tess_stats;
/* Load the geometry file at 'in_path' into a fresh context, then run the
* tessellation-statistics filter over it. A GCV_FILTER_FILTER operates
* on the geometry already in the context, so its target is NULL.
* Returns 0 on success. */
int
report_tessellation_stats(const char *in_path)
{
struct gcv_context context;
const struct gcv_filter *in_filter;
bu_mime_model_t in_type;
gcv_context_init(&context);
/* Import the input model into the context's in-memory database. */
in_type = (bu_mime_model_t)bu_file_mime(in_path, BU_MIME_MODEL);
in_filter = find_filter(GCV_FILTER_READ, in_type, in_path, &context);
if (!in_filter || !gcv_execute(&context, in_filter, NULL, 0, NULL, in_path)) {
bu_log("Failed to read '%s'\n", in_path);
gcv_context_destroy(&context);
return 1;
}
/* Run the filter; it tallies the faces and reports via bu_log(). */
if (!gcv_execute(&context, &gcv_conv_tess_stats, NULL, 0, NULL, NULL)) {
bu_log("Tessellation-statistics filter failed\n");
gcv_context_destroy(&context);
return 1;
}
gcv_context_destroy(&context);
return 0;
}
----
TODO: embedded code
====
@@ -703,7 +468,7 @@ At this time, the FASTGEN4 writer plugin does not make use of any filter-specifi
|`--constant-ident`
|Specify that the starting ident should remain constant.
|`--material=_code_`
|Specify the material code that will be assigned to all created regions (the default is `0`).
|Specify the material code that will be assigned to all created regions (the default is `1`).
|===
@@ -722,19 +487,7 @@ At this time, the FASTGEN4 writer plugin does not make use of any filter-specifi
=== VRML Reader
The native VRML reader accepts both VRML 1.0 and VRML97/2.0 files. VRML 1.0
imports preserve ordered property state, separator scoping, `DEF`/`USE`
instances, transformations, material colors, analytic cube, cone, cylinder,
and sphere geometry, and indexed polygon meshes. Concave polygons are
triangulated, and per-face material bindings are emitted as separate colored
regions.
VRML constructs that do not have a BRL-CAD equivalent or are not
implemented yet, including cameras, lights, textures, text, line sets,
and point sets, are accepted but do not produce objects. External
content referenced by `WWWInline` is not fetched during conversion.
The VRML reader plugin does not make use of any filter-specific options.
At this time, the VRML reader plugin does not make use of any filter-specific options.
=== VRML Writer
@@ -814,7 +567,7 @@ The Open Asset Import Library (assimp) is an open source library integrated into
|`--constant-ident`
|Specify that the starting ident should remain constant.
|`--material=_code_`
|Specify the material code that will be assigned to all created regions (the default is `0`).
|Specify the material code that will be assigned to all created regions (the default is `1`).
|`--format=_file_fmt_`
|Specify the file format for conversion. By default, this is inferred from the file extension.
|===
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

@@ -1,74 +0,0 @@
= Object-type catalog figure generator
This directory generates the figures used by
`doc/asciidoc/articles/object_types.adoc`. The `objtype_*.png` images in the
parent `images/` directory are a *committed snapshot*: the documentation build
consumes them like any other image, and this generator is the developer tool
that refreshes them from the actual built BRL-CAD tools.
Every pixel of every figure -- the shaded solids, the edge lines, and all the
on-image text -- is produced by BRL-CAD tools. No image-drawing library is
used.
== Pipeline
For each object the generator:
1. probes the object with `rt` (autoview) to learn the view and how much of the
frame the object fills, then picks a `viewsize` so it fills ~80% of the frame;
2. ray traces the shaded solid with `rt` into a disk framebuffer;
3. overlays silhouette + crease edges with `rtedge` (`overlay`,
`detect_distance`, `detect_normals`) so every shape reads clearly;
4. draws the parameter callouts (arrows, vectors, dimensions, labels) with
`fbline` and `fblabel`;
5. grabs the framebuffer to PNG with `fb-png`.
Variety montages render each cell the same way (with a `fblabel` caption burned
in) and then tile the finished cells into a grid.
Python is used only to orchestrate the tools, to project 3D parameter points to
2D pixels (reconstructed from the exact view `rt` reports, so callouts land on
the geometry), and for image I/O (measuring the object extent, tiling montage
cells).
== Files
* `objtype_lib.py` -- tool drivers, the projection/`View` helper, the
framebuffer drawing primitives, and `render` / `render_cell` / `montage`.
* `gen_object_types.py` -- one builder per object type plus a registry.
== Requirements
* A built BRL-CAD (`rt`, `rtedge`, `mged`, `fbline`, `fblabel`, `fb-png`,
`png-pix`, ...).
* Python 3 with `numpy` and `Pillow` (measurement / montage tiling only).
== Usage
[source,bash]
----
BRLCAD_BIN=/path/to/brlcad/bin python gen_object_types.py # rebuild all
BRLCAD_BIN=/path/to/brlcad/bin python gen_object_types.py ell tor # rebuild some
----
If `BRLCAD_BIN` is unset the script looks for a build under `out/build/...` or
`build/` relative to the repository root.
== Platform notes
* The disk framebuffer only behaves at dimensions >= 512, so cells are rendered
at 512 and downsampled.
* A framebuffer device name is always a bare relative name (a `D:\...` path is
misread as `host:port`), and the tools are run with their working directory
set to this scratch directory; data files (`dsp`, `ebm`, `vol`) are likewise
referenced by bare basename.
* `nmg` is a real facetize -n solid, ray traced single-threaded (`-P1`): the
NMG hitmiss freelist (`re_nmgfree`) is a process-global that is not
thread-safe, so parallel shooting races. Two libnmg init fixes
(`src/libnmg/isect.c`, in `nmg_isect_ray_model`) make the single-threaded
path correct.
* `submodel` is a real instanced submodel; a librt path-resolution fix
(`src/librt/primitives/submodel/submodel.c`, `rt_submodel_resolve_path`)
lets it find a relative `file=` next to the parent `.g`.
* `cline` is built with `put` (its tcl keys are `V H R T`).
* Scratch files (`_*`) are temporary and are not committed.
@@ -1,720 +0,0 @@
#!/usr/bin/env python3
"""
Generate every figure used by doc/asciidoc/articles/object_types.adoc.
Each renderable primitive gets:
* objtype_<key>.png - an annotated parameter diagram (the "hero"),
rt-shaded with rtedge silhouette/crease edges,
with parameter callouts drawn by fbline/fblabel
* objtype_<key>_variety.png - a montage of distinct parameterizations
All rendering and all on-image text is produced by BRL-CAD tools (rt, rtedge,
fbline, fblabel); see objtype_lib.py. Output lands in ../ (articles/images).
Usage:
python gen_object_types.py [key ...] # build all, or only the named keys
BRLCAD_BIN=/path/to/bin python gen_object_types.py
"""
import math
import os
import struct
import sys
import objtype_lib as L
from objtype_lib import FG
HERE = os.path.dirname(os.path.abspath(__file__))
IMG = os.path.dirname(HERE) # .../articles/images
def OUT(key):
return os.path.join(IMG, "objtype_%s.png" % key)
def VAR(key):
return os.path.join(IMG, "objtype_%s_variety.png" % key)
def scratch(name):
return os.path.join(HERE, "_%s" % name)
def put_data(name, data):
# Data files are referenced by bare basename and the tools run with cwd in
# this directory (a Windows "D:\..." path is misread as host:port / .\path).
path = scratch(name)
with open(path, "wb") as fh:
fh.write(bytes(data))
return os.path.basename(path)
def fresh(key):
g = scratch("%s.g" % key)
if os.path.exists(g):
os.remove(g)
return g
def add(v, w):
return tuple(a + b for a, b in zip(v, w))
# ---------------------------------------------------------------------------
# generic builders
# ---------------------------------------------------------------------------
def hero(key, gtype, params, anns, az=35, el=25, color=FG, fill=0.80):
g = fresh(key)
L.build(g, gtype, params, color=color)
L.render(g, "r", OUT(key), az=az, el=el, anns=anns, fill=fill)
print("hero", key)
def variety(key, entries, az=35, el=25, cols=None, fill=0.80):
"""entries: (caption, gtype, params) or (caption, gtype, params, color)."""
cells = []
for i, e in enumerate(entries):
cap, gt, pr = e[0], e[1], e[2]
col = e[3] if len(e) > 3 else FG
g = fresh("%s_v%d" % (key, i))
L.build(g, gt, pr, color=col)
png = scratch("%s_v%d.png" % (key, i))
L.render_cell(g, "r", png, size=360, caption=cap, az=az, el=el, fill=fill)
cells.append(png)
L.montage(cells, VAR(key), cols=cols)
print("variety", key)
# ===========================================================================
# Planar-faced
# ===========================================================================
def do_arb8():
pts = [0,0,0, 6,0,0, 6,4,0, 0,4,0, 0,0,3, 6,0,3, 6,4,3, 0,4,3]
def pt(i):
return tuple(pts[3*(i-1):3*i])
anns = [{"t": "pt", "p": pt(i), "label": str(i), "off": (10, -14)}
for i in (2, 3, 4, 5, 6, 7, 8)]
hero("arb8", "arb8", pts, anns)
# The full arb family as real arbs (arb4-arb8). Rotated off-axis so the
# tetrahedron and the others show three faces instead of a flat silhouette.
variety("arb8", [
("arb4 tetrahedron", "arb4", [0,0,0, 5,0,0, 2.5,4.5,0, 2.5,1.8,4]),
("arb5 pyramid", "arb5", [0,0,0, 5,0,0, 5,5,0, 0,5,0, 2.5,2.5,4.5]),
("arb6 prism", "arb6", [0,0,0, 5,0,0, 5,4,0, 0,4,0, 2.5,0,4, 2.5,4,4]),
("arb7", "arb7", [0,0,0, 5,0,0, 5,4,0, 0,4,0, 0,0,3, 5,0,3, 5,4,1.5]),
("arb8 box", "arb8",
[0,0,0, 4,0,0, 4,4,0, 0,4,0, 0,0,4, 4,0,4, 4,4,4, 0,4,4]),
], cols=5, fill=0.70, az=55, el=28)
def do_arbn():
R, Hh = 3.0, 2.2
planes = []
for k in range(6):
a = math.radians(60*k)
planes += [math.cos(a), math.sin(a), 0, R]
planes += [0,0,1, Hh, 0,0,-1, Hh]
params = [8] + planes
hero("arbn", "arbn", params, [
{"t": "seg", "a": (0,0,0), "b": (R,0,0)},
{"t": "pt", "p": (R,0,0), "label": "plane: n, d", "off": (58, -8)},
], az=25, el=32, fill=0.72)
# "hex prism" removed: it duplicates the highlight image above.
variety("arbn", [
("oct prism", "arbn",
[10] + [c for k in range(8)
for c in (math.cos(math.radians(45*k)),
math.sin(math.radians(45*k)), 0, 3)]
+ [0,0,1, 2, 0,0,-1, 2]),
("clipped box", "arbn",
[7, 1,0,0,3, -1,0,0,3, 0,1,0,3, 0,-1,0,3, 0,0,1,3, 0,0,-1,3,
1,1,1,4.2]),
], az=25, el=32, fill=0.70, cols=2)
def do_half():
g = fresh("half")
L.mged_batch(g, [
["in", "sp", "sph", 0,0,0, 3],
["in", "hf", "half", 0,0,1, 0],
["r", "r", "u", "sp", "-", "hf"],
["mater", "r", "plastic", FG[0], FG[1], FG[2], 0],
])
L.render(g, "r", OUT("half"), az=35, el=20, anns=[
{"t": "vec", "a": (0,0,0), "b": (0,0,3), "label": "N", "off": (22, 2)},
{"t": "pt", "p": (0,0,0), "label": "d", "off": (-26, -14)},
])
print("hero half")
# ===========================================================================
# Ellipsoids
# ===========================================================================
def do_ell():
V=(0,0,0); A=(5,0,0); B=(0,3,0); C=(0,0,2)
hero("ell", "ell", [*V,*A,*B,*C], [
{"t": "pt", "p": V, "label": "V", "off": (-34, 8)},
{"t": "vec", "a": V, "b": A, "label": "A", "off": (0, 22)},
{"t": "vec", "a": V, "b": B, "label": "B", "off": (16, -2)},
{"t": "vec", "a": V, "b": C, "label": "C", "off": (-14, 0)},
])
# "tri-axial" removed: the highlight image above is already tri-axial.
variety("ell", [
("sphere |A|=|B|=|C|", "ell", [0,0,0, 3,0,0, 0,3,0, 0,0,3]),
("flat disc |C| small", "ell", [0,0,0, 4,0,0, 0,4,0, 0,0,0.6]),
("spike |C| large", "ell", [0,0,0, 0.7,0,0, 0,0.7,0, 0,0,5]),
], cols=3)
def do_sph():
V=(0,0,0); r=3.0
hero("sph", "sph", [*V, r], [
{"t": "pt", "p": V, "label": "V", "off": (-30, 8)},
{"t": "dim", "a": V, "b": (r,0,0), "label": "r", "off": (0, 18)},
])
def do_superell():
V=(0,0,0); A=(3,0,0); B=(0,3,0); C=(0,0,3)
hero("superell", "superell", [*V,*A,*B,*C, 2.5, 2.5], [
{"t": "pt", "p": V, "label": "V", "off": (-32, 8)},
{"t": "vec", "a": V, "b": A, "label": "A", "off": (0, 20)},
{"t": "vec", "a": V, "b": B, "label": "B", "off": (16, -2)},
{"t": "vec", "a": V, "b": C, "label": "C", "off": (-14, 0)},
])
variety("superell", [
("n=e=1 ellipsoid", "superell", [0,0,0,3,0,0,0,3,0,0,0,3, 1,1]),
("n=e=0.4 pinched", "superell", [0,0,0,3,0,0,0,3,0,0,0,3, 0.4,0.4]),
("n=e=2.5 rounded box", "superell", [0,0,0,3,0,0,0,3,0,0,0,3, 2.5,2.5]),
("n=1 e=4 cushion", "superell", [0,0,0,3,0,0,0,3,0,0,0,3, 1.0,4.0]),
])
# ===========================================================================
# Tori
# ===========================================================================
def do_tor():
V=(0,0,0); N=(0,0,1); r1=4.0; r2=1.2
hero("tor", "tor", [*V,*N, r1, r2], [
{"t": "pt", "p": V, "label": "V", "off": (-30, 8)},
{"t": "vec", "a": V, "b": (0,0,2.4), "label": "N", "off": (-20, 6)},
{"t": "dim", "a": V, "b": (r1,0,0), "label": "r1", "off": (0, -26)},
{"t": "dim", "a": (r1,0,0), "b": (r1+r2,0,0), "label": "r2", "off": (34, -12)},
], az=35, el=42)
variety("tor", [
("ring r1 >> r2", "tor", [0,0,0,0,0,1, 4, 0.8]),
("fat torus r1 ~ r2", "tor", [0,0,0,0,0,1, 2.2, 1.8]),
("washer thin", "tor", [0,0,0,0,0,1, 4, 0.35]),
], az=35, el=42)
def do_eto():
V=(0,0,0); N=(0,0,1); r=4.0; C=(1.4,0,1.4); d=0.7
tube = (r, 0, 0) # tube cross-section center (on +x)
# semi-minor axis d: perpendicular to C within the cross-section (x-z) plane
import math as _m
cn = _m.hypot(C[0], C[2])
dperp = (C[2]/cn * d, 0.0, -C[0]/cn * d)
hero("eto", "eto", [*V,*N, r, *C, d], [
{"t": "pt", "p": V, "label": "V", "off": (-28, 8)},
{"t": "vec", "a": V, "b": (0,0,2.6), "label": "N", "off": (-20, 6)},
{"t": "dim", "a": V, "b": tube, "label": "r", "off": (0, -24)},
{"t": "vec", "a": tube, "b": add(tube, C), "label": "C", "off": (22, 0)},
{"t": "vec", "a": tube, "b": add(tube, dperp), "label": "d", "off": (-16, 14)},
], az=35, el=42)
variety("eto", [
("upright ellipse", "eto", [0,0,0,0,0,1, 4, 0,0,1.6, 0.7]),
("tilted ellipse", "eto", [0,0,0,0,0,1, 4, 1.4,0,1.4, 0.6]),
("flat tube", "eto", [0,0,0,0,0,1, 4, 1.8,0,0, 0.5]),
], az=35, el=42)
# ===========================================================================
# Cone / cylinder (TGC family)
# ===========================================================================
def do_tgc():
# a genuine frustum so the top scale factors read clearly
V=(0,0,0); Hh=(0,0,6); A=(2.6,0,0); B=(0,1.7,0); c=0.5; d=0.5
top = (0, 0, 6)
hero("tgc", "tgc", [*V,*Hh,*A,*B, c, d], [
{"t": "pt", "p": V, "label": "V", "off": (-30, 4)},
{"t": "vec", "a": V, "b": (0,0,6), "label": "H", "off": (22, 0)},
{"t": "vec", "a": V, "b": A, "label": "A", "off": (2, -16)},
{"t": "vec", "a": V, "b": B, "label": "B", "off": (18, 2)},
{"t": "vec", "a": top, "b": add(top, (c*2.6, 0, 0)),
"label": "c*A", "off": (2, -16)},
])
variety("tgc", [
("cylinder rcc", "rcc", [0,0,0,0,0,6, 2.2]),
("cone trc", "trc", [0,0,0,0,0,6, 2.4, 0.4]),
("elliptical rec", "rec", [0,0,0,0,0,6, 2.6,0,0, 0,1.3,0]),
("skewed funnel", "tgc", [0,0,0, 1.5,0,6, 2.4,0,0, 0,2.4,0, 0.4,0.9]),
])
def do_rcc():
V=(0,0,0)
hero("rcc", "rcc", [*V, 0,0,6, 2.5], [
{"t": "pt", "p": V, "label": "V", "off": (-30, 0)},
{"t": "vec", "a": V, "b": (0,0,6), "label": "H", "off": (20, 0)},
{"t": "dim", "a": V, "b": (2.5,0,0), "label": "r", "off": (0, 18)},
])
def do_trc():
hero("trc", "trc", [0,0,0, 0,0,6, 2.6, 1.0], [
{"t": "pt", "p": (0,0,0), "label": "V", "off": (-28, 0)},
{"t": "vec", "a": (0,0,0), "b": (0,0,6), "label": "H", "off": (20, 0)},
{"t": "dim", "a": (0,0,0), "b": (2.6,0,0), "label": "r_base", "off": (0, 16)},
{"t": "dim", "a": (0,0,6), "b": (1.0,0,6), "label": "r_top", "off": (0, 16)},
])
def do_rec():
hero("rec", "rec", [0,0,0, 0,0,6, 2.8,0,0, 0,1.4,0], [
{"t": "pt", "p": (0,0,0), "label": "V", "off": (-26, 0)},
{"t": "vec", "a": (0,0,0), "b": (0,0,6), "label": "H", "off": (20, 0)},
{"t": "vec", "a": (0,0,0), "b": (2.8,0,0), "label": "A", "off": (2, -14)},
{"t": "vec", "a": (0,0,0), "b": (0,1.4,0), "label": "B", "off": (16, 2)},
])
# ===========================================================================
# Quadric / conic
# ===========================================================================
def do_rpc():
V=(0,0,0)
hero("rpc", "rpc", [*V, 0,0,6, 0,3,0, 1.5], [
{"t": "pt", "p": V, "label": "V", "off": (-28, 6)},
{"t": "vec", "a": V, "b": (0,0,6), "label": "H", "off": (20, 0)},
{"t": "vec", "a": V, "b": (0,3,0), "label": "B", "off": (18, 2)},
{"t": "dim", "a": V, "b": (1.5,0,0), "label": "r", "off": (0, 16)},
])
variety("rpc", [
("tall narrow", "rpc", [0,0,0, 0,0,6, 0,3,0, 0.8]),
("shallow wide", "rpc", [0,0,0, 0,0,6, 0,1.2,0, 2.4]),
("stubby", "rpc", [0,0,0, 0,0,2.5, 0,3,0, 2.0]),
])
def do_rhc():
V=(0,0,0)
hero("rhc", "rhc", [*V, 0,0,6, 0,3,0, 1.5, 1.2], [
{"t": "pt", "p": V, "label": "V", "off": (-28, 6)},
{"t": "vec", "a": V, "b": (0,0,6), "label": "H", "off": (20, 0)},
{"t": "vec", "a": V, "b": (0,3,0), "label": "B", "off": (18, 2)},
{"t": "dim", "a": V, "b": (1.5,0,0), "label": "r", "off": (0, 16)},
])
variety("rhc", [
("sharp small c", "rhc", [0,0,0, 0,0,6, 0,3,0, 1.5, 0.4]),
("blunt large c", "rhc", [0,0,0, 0,0,6, 0,3,0, 1.5, 3.0]),
("wide", "rhc", [0,0,0, 0,0,6, 0,2,0, 3.0, 1.2]),
])
def do_epa():
V=(0,0,0)
hero("epa", "epa", [*V, 0,0,6, 2.5,0,0, 1.5], [
{"t": "pt", "p": V, "label": "V", "off": (-28, 4)},
{"t": "vec", "a": V, "b": (0,0,6), "label": "H", "off": (20, 0)},
{"t": "vec", "a": V, "b": (2.5,0,0), "label": "A", "off": (8, -14)},
])
variety("epa", [
("bullet r1=r2", "epa", [0,0,0, 0,0,6, 2,0,0, 2.0]),
("dish short H", "epa", [0,0,0, 0,0,2, 3,0,0, 3.0]),
("elliptical base", "epa", [0,0,0, 0,0,6, 3,0,0, 1.2]),
])
def do_ehy():
V=(0,0,0)
hero("ehy", "ehy", [*V, 0,0,6, 2.5,0,0, 1.5, 1.0], [
{"t": "pt", "p": V, "label": "V", "off": (-28, 4)},
{"t": "vec", "a": V, "b": (0,0,6), "label": "H", "off": (20, 0)},
{"t": "vec", "a": V, "b": (2.5,0,0), "label": "A", "off": (8, -14)},
])
variety("ehy", [
("horn small c", "ehy", [0,0,0, 0,0,6, 2,0,0, 2.0, 0.4]),
("near-cone large c", "ehy", [0,0,0, 0,0,6, 2,0,0, 2.0, 4.0]),
("elliptical base", "ehy", [0,0,0, 0,0,6, 3,0,0, 1.2, 1.0]),
])
def do_hyp():
V=(0,0,0)
hero("hyp", "hyp", [*V, 0,0,6, 3,0,0, 1.6, 0.4], [
{"t": "vec", "a": V, "b": (0,0,6), "label": "H", "off": (24, 0)},
{"t": "vec", "a": V, "b": (3,0,0), "label": "A", "off": (0, 20)},
], az=35, el=15)
# "cooling tower" removed: the highlight above is already the pinched form.
variety("hyp", [
("near-cylinder c=0.9", "hyp", [0,0,0, 0,0,6, 2.4,0,0, 2.4, 0.9]),
("elliptical section", "hyp", [0,0,0, 0,0,6, 3.6,0,0, 0.9, 0.55]),
], az=35, el=15, cols=2)
def do_part():
V=(0,0,0)
hero("part", "part", [*V, 0,0,6, 1.0, 2.0], [
{"t": "pt", "p": V, "label": "V", "off": (-28, 4)},
{"t": "vec", "a": V, "b": (0,0,6), "label": "H", "off": (22, 0)},
{"t": "dim", "a": V, "b": (1.0,0,0), "label": "r_v", "off": (-6, 14)},
{"t": "dim", "a": (0,0,6), "b": (2.0,0,6), "label": "r_h", "off": (0, 16)},
])
variety("part", [
("sphere H->0", "part", [0,0,0, 0,0,0.01, 2.5, 2.5]),
("capsule r_v=r_h", "part", [0,0,0, 0,0,6, 1.5, 1.5]),
("lozenge r_v!=r_h", "part", [0,0,0, 0,0,6, 0.6, 2.2]),
])
def do_hrt():
V=(0,0,0)
hero("hrt", "hrt", [*V, 3,0,0, 0,3,0, 0,0,3, 3.0], [
{"t": "pt", "p": V, "label": "V", "off": (-34, -10)},
{"t": "vec", "a": V, "b": (3,0,0), "label": "xdir", "off": (4, 20)},
{"t": "vec", "a": V, "b": (0,3,0), "label": "ydir", "off": (20, 2)},
{"t": "vec", "a": V, "b": (0,0,3), "label": "zdir", "off": (-18, -2)},
], az=0, el=20)
variety("hrt", [
("d = 2 rounded", "hrt", [0,0,0, 3,0,0, 0,3,0, 0,0,3, 2.0]),
("d = 3 classic", "hrt", [0,0,0, 3,0,0, 0,3,0, 0,0,3, 3.0]),
("d = 4.5 pointed", "hrt", [0,0,0, 3,0,0, 0,3,0, 0,0,3, 4.5]),
], az=0, el=20)
# ===========================================================================
# Implicit
# ===========================================================================
def do_metaball():
pts = [-2.8,-1.4,0, 2.3, 2.8,-1.4,0, 2.3, 0,2.8,0, 2.3]
g = fresh("metaball")
L.build(g, "metaball", [1, 1.0, 3] + pts)
offs = [(-34, -10), (34, -10), (0, 28)]
anns = [{"t": "pt", "p": (pts[4*i], pts[4*i+1], pts[4*i+2]),
"label": "P%d" % (i+1), "off": offs[i]} for i in range(3)]
L.render(g, "r", OUT("metaball"), az=20, el=60, anns=anns)
print("hero metaball")
variety("metaball", [
("far apart", "metaball", [1,1.0,2, -3,0,0,2.5, 3,0,0,2.5]),
("touching", "metaball", [1,1.0,2, -1.6,0,0,2.5, 1.6,0,0,2.5]),
("merged", "metaball", [1,1.0,2, -1.0,0,0,2.5, 1.0,0,0,2.5]),
], az=20, el=60)
# ===========================================================================
# Mesh & procedural
# ===========================================================================
def do_bot():
verts = [1,0,0, -1,0,0, 0,1,0, 0,-1,0, 0,0,1.4, 0,0,-1.4]
faces = [0,2,4, 2,1,4, 1,3,4, 3,0,4, 2,0,5, 1,2,5, 3,1,5, 0,3,5]
g = fresh("bot")
L.build(g, "bot", [6, 8, 2, 2] + verts + faces)
L.render(g, "r", OUT("bot"), az=25, el=25, anns=[
{"t": "pt", "p": (1,0,0), "label": "vertex", "off": (34, 0)},
# point the "triangle" label at a face centroid, not a vertex
{"t": "pt", "p": (1/3.0, 1/3.0, 1.4/3.0), "label": "triangle", "off": (40, -6)},
])
print("hero bot")
# Surface vs solid look identical from outside, so show cutaways: an
# open-topped shell (surface mode -> hollow) beside a corner-cut solid.
cv = [0,0,0, 4,0,0, 4,4,0, 0,4,0, 0,0,4, 4,0,4, 4,4,4, 0,4,4]
top = [4,5,6, 4,6,7]
walls = [0,2,1, 0,3,2, 0,1,5, 0,5,4, 3,7,6, 3,6,2, 0,4,7, 0,7,3, 1,2,6, 1,6,5]
cells = []
gs = fresh("bot_surf")
L.build(gs, "bot", [8, 10, 1, 2] + cv + walls) # mode 1 = surface, open top
ps = scratch("bot_surf.png")
L.render_cell(gs, "r", ps, size=380, caption="surface mode (open shell)",
az=45, el=35, fill=0.74)
cells.append(ps)
gd = fresh("bot_sol")
cutter = [2.4,2.4,2.4, 5,2.4,2.4, 5,5,2.4, 2.4,5,2.4,
2.4,2.4,5, 5,2.4,5, 5,5,5, 2.4,5,5]
L.mged_batch(gd, [
["in", "cube", "bot", 8, 12, 2, 2] + cv + walls + top,
["in", "cut", "arb8"] + cutter,
["r", "r", "u", "cube", "-", "cut"],
["mater", "r", "plastic", FG[0], FG[1], FG[2], 0],
])
pd = scratch("bot_sol.png")
L.render_cell(gd, "r", pd, size=380, caption="solid mode (cut away)",
az=45, el=35, fill=0.74)
cells.append(pd)
L.montage(cells, VAR("bot"), cols=2)
print("variety bot")
def do_ars():
npts, ncrv = 6, 5
rows = []
for j in range(ncrv):
z = j * 1.2
rad = 2.2 * math.sin(math.pi * (j + 0.5) / ncrv) + 0.6
row = []
for i in range(npts):
a = 2*math.pi*i/npts
row += [rad*math.cos(a), rad*math.sin(a), z]
rows.append(row)
flat = [npts, ncrv] + [c for row in rows for c in row]
hero("ars", "ars", flat, [
{"t": "pt", "p": (rows[2][0], rows[2][1], 2.4), "label": "waterline pts",
"off": (40, 0)},
], az=35, el=20)
def do_pipe():
params = [3,
0,0,0, 1.0, 2.0, 1.5,
0,0,4, 1.0, 2.0, 1.5,
4,0,4, 1.0, 2.0, 1.5]
hero("pipe", "pipe", params, [
{"t": "pt", "p": (0,0,0), "label": "pt 1", "off": (-30, 0)},
{"t": "pt", "p": (0,0,4), "label": "pt 2 (bend)", "off": (-40, 10)},
{"t": "pt", "p": (4,0,4), "label": "pt 3", "off": (28, 8)},
], az=35, el=20)
variety("pipe", [
("hollow tube", "pipe", [2, 0,0,0, 1.2,2.4,1.3, 0,0,5, 1.2,2.4,1.3]),
("solid rod", "pipe", [2, 0,0,0, 0,2.0,1.1, 0,0,5, 0,2.0,1.1]),
("tapered", "pipe", [2, 0,0,0, 0,1.0,1.5, 0,0,5, 0,2.6,1.5]),
], az=35, el=20)
def do_pnts():
coords = []
n = 0
for x in range(4):
for y in range(4):
for z in range(4):
coords += [x*1.2, y*1.2, z*1.2]
n += 1
g = fresh("pnts")
L.build(g, "pnts", ["no", n, "no", "no", "no", 0.18] + coords)
L.render(g, "r", OUT("pnts"), az=35, el=25, anns=[])
print("hero pnts")
def do_extrude():
g = fresh("extrude")
L.mged_batch(g, [
["put", "sk", "sketch", "V", "{0 0 0}", "A", "{1 0 0}", "B", "{0 1 0}",
"VL", "{ {0 0} {4 0} {4 1.5} {1.5 1.5} {1.5 4} {0 4} }",
"SL", "{ {line S 0 E 1} {line S 1 E 2} {line S 2 E 3} "
"{line S 3 E 4} {line S 4 E 5} {line S 5 E 0} }"],
["in", "s", "extrude", 0,0,0, 0,0,4, 1,0,0, 0,1,0, "sk"],
["r", "r", "u", "s"],
["mater", "r", "plastic", FG[0], FG[1], FG[2], 0],
])
L.render(g, "r", OUT("extrude"), az=35, el=25, anns=[
{"t": "pt", "p": (0,0,0), "label": "V", "off": (-28, 8)},
{"t": "vec", "a": (0,0,0), "b": (0,0,4), "label": "H", "off": (22, 0)},
])
print("hero extrude")
def do_revolve():
g = fresh("revolve")
L.mged_batch(g, [
["put", "pk", "sketch", "V", "{0 0 0}", "A", "{1 0 0}", "B", "{0 1 0}",
"VL", "{ {2 0} {3.5 0} {3 2} {3.5 4} {2 4} }",
"SL", "{ {line S 0 E 1} {line S 1 E 2} {line S 2 E 3} "
"{line S 3 E 4} {line S 4 E 0} }"],
["in", "s", "revolve", 0,0,0, 0,0,1, 1,0,0, 300, "pk"],
["r", "r", "u", "s"],
["mater", "r", "plastic", FG[0], FG[1], FG[2], 0],
])
L.render(g, "r", OUT("revolve"), az=35, el=25, anns=[
{"t": "vec", "a": (0,0,0), "b": (0,0,4), "label": "axis", "off": (-26, 4)},
])
print("hero revolve")
def do_dsp():
W = Ht = 48
data = bytearray()
for y in range(Ht):
for x in range(W):
dx = (x-W/2)/(W/4); dy = (y-Ht/2)/(Ht/4)
h = math.exp(-(dx*dx+dy*dy)) \
+ 0.4*math.exp(-(((x-10)/6.0)**2 + ((y-34)/6.0)**2))
data += struct.pack(">H", int(h*45000))
df = put_data("dsp.data", data)
g = fresh("dsp")
L.build(g, "dsp", ["f", df, W, Ht, 1, "a", 1.0, 0.00042])
L.render(g, "r", OUT("dsp"), az=45, el=35, anns=[])
print("hero dsp")
def do_ebm():
W = Ht = 40
data = bytearray()
for y in range(Ht):
for x in range(W):
dx = x-W/2; dy = y-Ht/2
r = math.hypot(dx, dy)
data.append(255 if 7 < r < 15 else 0)
df = put_data("ebm.data", data)
g = fresh("ebm")
L.build(g, "ebm", ["f", df, W, Ht, 14])
L.render(g, "r", OUT("ebm"), az=35, el=45, anns=[])
print("hero ebm")
def do_vol():
W = Ht = D = 24
data = bytearray()
for z in range(D):
for y in range(Ht):
for x in range(W):
dx=x-W/2; dy=y-Ht/2; dz=z-D/2
inside = (dx*dx+dy*dy+dz*dz) < 100 and not (abs(dx)<3 and abs(dy)<3)
data.append(200 if inside else 0)
df = put_data("vol.data", data)
g = fresh("vol")
L.build(g, "vol", ["f", df, W, Ht, D, 128, 255, 0.5, 0.5, 0.5])
L.render(g, "r", OUT("vol"), az=35, el=30, anns=[])
print("hero vol")
def do_nmg():
# A real n-Manifold Geometry solid (facetize -n). NMG ray tracing uses a
# global hitmiss freelist that is not thread-safe, so shoot single-threaded
# (-P1) to avoid the race; the shaded result is a genuine NMG.
g = fresh("nmg")
L.mged_batch(g, [
["in", "src", "ell", 0,0,0, 3,0,0, 0,2,0, 0,0,2],
["facetize", "-n", "s", "src"],
["r", "r", "u", "s"],
["mater", "r", "plastic", FG[0], FG[1], FG[2], 0],
])
L.render(g, "r", OUT("nmg"), az=35, el=25, anns=[], extra=["-P1"], hyper=2)
print("hero nmg")
def do_brep():
g = fresh("brep")
L.mged_batch(g, [
["in", "src", "ell", 0,0,0, 3,0,0, 0,2,0, 0,0,2],
["brep", "src", "brep", "s"],
["r", "r", "u", "s"],
["mater", "r", "plastic", FG[0], FG[1], FG[2], 0],
])
L.render(g, "r", OUT("brep"), az=35, el=25, anns=[])
print("hero brep")
def do_cline():
g = fresh("cline")
L.mged_batch(g, [
["put", "c", "cline", "V", "{0 0 0}", "H", "{0 0 8}", "R", "1.5", "T", "0.4"],
["r", "r", "u", "c"],
["mater", "r", "plastic", FG[0], FG[1], FG[2], 0],
])
L.render(g, "r", OUT("cline"), az=35, el=20, anns=[
{"t": "pt", "p": (0,0,0), "label": "V", "off": (-28, 6)},
{"t": "vec", "a": (0,0,0), "b": (0,0,8), "label": "H", "off": (20, 0)},
{"t": "dim", "a": (0,0,0), "b": (1.5,0,0), "label": "R", "off": (0, 16)},
])
print("hero cline")
def do_submodel():
# A real submodel: instance the treetop "widget" from a separate .g file as
# a single primitive. (The relative-path resolver bug is fixed in librt.)
parts = fresh("parts")
partsname = os.path.basename(parts) # referenced relative to cwd
L.mged_batch(parts, [
["in", "hub", "sph", 0,0,0, 1.6],
["in", "arm1", "rcc", 0,0,0, 4,0,0, 0.7],
["in", "arm2", "rcc", 0,0,0, 0,4,0, 0.7],
["in", "arm3", "rcc", 0,0,0, 0,0,4, 0.7],
["in", "cap1", "sph", 4,0,0, 1.0],
["in", "cap2", "sph", 0,4,0, 1.0],
["in", "cap3", "sph", 0,0,4, 1.0],
["r", "widget", "u", "hub", "u", "arm1", "u", "arm2", "u", "arm3",
"u", "cap1", "u", "cap2", "u", "cap3"],
["mater", "widget", "plastic", FG[0], FG[1], FG[2], 0],
])
g = fresh("submodel")
L.mged_batch(g, [
["in", "sm", "submodel", "widget", "0", partsname],
["r", "r", "u", "sm"],
["mater", "r", "plastic", FG[0], FG[1], FG[2], 0],
])
L.render(g, "r", OUT("submodel"), az=35, el=25, anns=[])
print("hero submodel")
# ===========================================================================
# Boolean combinations
# ===========================================================================
def do_comb():
spheres = [["in", "a", "sph", -1,0,0, 2.6], ["in", "b", "sph", 1.4,0,0, 2.0]]
ops = [("u", "union a u b"),
("-", "difference a - b"),
("+", "intersection a + b")]
# One shared view (from the union, the largest result) so all three panels
# are at the same scale and the spheres line up across them.
gu = fresh("comb_u")
L.mged_batch(gu, spheres + [["r", "r", "u", "a", "u", "b"],
["mater", "r", "plastic", FG[0], FG[1], FG[2], 0]])
orient, autosize, model, frac = L.probe(gu, "r", az=35, el=20)
C = ((model[0]+model[1])/2, (model[2]+model[3])/2, (model[4]+model[5])/2)
V = autosize * frac / 0.72
view = (orient, L.eye_for(C, 35, 20, V*3), V)
cells = []
for i, (op, cap) in enumerate(ops):
g = fresh("comb_%d" % i)
L.mged_batch(g, spheres + [["r", "r", "u", "a", op, "b"],
["mater", "r", "plastic", FG[0], FG[1], FG[2], 0]])
png = scratch("comb_%d.png" % i)
L.render_cell(g, "r", png, size=380, caption=cap, view=view)
cells.append(png)
L.montage(cells, VAR("comb"), cols=3)
print("comb done")
# ===========================================================================
# registry
# ===========================================================================
OBJECTS = {
"arb8": do_arb8, "arbn": do_arbn, "half": do_half,
"ell": do_ell, "sph": do_sph, "superell": do_superell,
"tor": do_tor, "eto": do_eto,
"tgc": do_tgc, "rcc": do_rcc, "trc": do_trc, "rec": do_rec,
"rpc": do_rpc, "rhc": do_rhc, "epa": do_epa, "ehy": do_ehy, "hyp": do_hyp,
"part": do_part, "hrt": do_hrt, "metaball": do_metaball,
"bot": do_bot, "ars": do_ars, "pipe": do_pipe, "pnts": do_pnts,
"extrude": do_extrude, "revolve": do_revolve,
"dsp": do_dsp, "ebm": do_ebm, "vol": do_vol,
"nmg": do_nmg, "brep": do_brep, "cline": do_cline, "submodel": do_submodel,
"comb": do_comb,
}
def main():
keys = sys.argv[1:] or list(OBJECTS.keys())
for k in keys:
if k not in OBJECTS:
print("unknown:", k)
continue
try:
OBJECTS[k]()
except Exception as e:
print("FAILED", k, "->", e)
if __name__ == "__main__":
main()
@@ -1,459 +0,0 @@
#!/usr/bin/env python3
"""
Shared helpers for the BRL-CAD object-type catalog image generator.
Everything visual is produced with BRL-CAD's own tools:
* ``rt`` ray traces the shaded solid into a disk framebuffer,
* ``rtedge`` overlays silhouette + crease edges onto the same framebuffer
(so every shape reads clearly), and
* ``fbline`` / ``fblabel`` / ``pix-fb`` draw the parameter callouts and
assemble the variety montages,
* ``fb-png`` grabs the finished framebuffer to a PNG.
Python is used only to orchestrate those tools, to size each view so the
object fills the frame, and to project 3D parameter points to 2D pixels. The
projection is reconstructed from the exact view ``rt`` reports (orientation,
size, model bounds), so callouts land precisely on the rendered geometry.
No image-drawing libraries (matplotlib, PIL drawing, ...) are used; PIL is used
only to measure the rendered object's extent so the view can be fit to it.
"""
import os
import re
import subprocess
import sys
import numpy as np
# ----------------------------------------------------------------------------
# Tool discovery
# ----------------------------------------------------------------------------
def find_bin():
env = os.environ.get("BRLCAD_BIN")
if env and os.path.isdir(env):
return env
here = os.path.dirname(os.path.abspath(__file__))
root = os.path.abspath(os.path.join(here, "..", "..", "..", "..", ".."))
for c in (os.path.join(root, "out", "build", "x64-Debug", "bin"),
os.path.join(root, "out", "build", "x64-Release", "bin"),
os.path.join(root, "build", "bin")):
if os.path.isdir(c) and (os.path.exists(os.path.join(c, "rt.exe"))
or os.path.exists(os.path.join(c, "rt"))):
return c
raise RuntimeError("Could not find BRL-CAD bin dir; set BRLCAD_BIN")
BIN = find_bin()
def _exe(name):
for ext in (".exe", ""):
p = os.path.join(BIN, name + ext)
if os.path.exists(p):
return p
return os.path.join(BIN, name)
def _cwd(gfile):
return os.path.dirname(os.path.abspath(gfile)) or None
# ----------------------------------------------------------------------------
# Palette
# ----------------------------------------------------------------------------
BG = (236, 238, 242) # panel background
FG = (95, 140, 205) # default object color
EDGE = (28, 30, 34) # rtedge line color
ACCENT = (214, 82, 28) # vector / dimension arrows
VERTEX = (196, 28, 28) # defining points
INK = (20, 20, 20) # label text
_CHARW = 17.7 # measured nonie.r.12 glyph advance (px)
def _c(rgb):
return "%d/%d/%d" % (rgb[0], rgb[1], rgb[2])
# ----------------------------------------------------------------------------
# mged drivers
# ----------------------------------------------------------------------------
def mged(gfile, *args):
cmd = [_exe("mged"), "-c", gfile] + [str(a) for a in args]
return subprocess.run(cmd, capture_output=True, text=True, cwd=_cwd(gfile))
def mged_batch(gfile, cmds):
script = "\n".join(" ".join(str(a) for a in c) for c in cmds) + "\nquit\n"
return subprocess.run([_exe("mged"), "-c", gfile], input=script,
capture_output=True, text=True, cwd=_cwd(gfile))
def make_in(gfile, name, gtype, params):
return mged(gfile, "in", name, gtype, *[str(x) for x in params])
def build(gfile, gtype, params, color=None, region="r", solid="s"):
"""Create a solid and wrap it in a colored region, in one mged process."""
color = color or FG
mged_batch(gfile, [
["in", solid, gtype] + [str(x) for x in params],
["r", region, "u", solid],
["mater", region, "plastic", color[0], color[1], color[2], 0],
])
# ----------------------------------------------------------------------------
# View parsing + projection
# ----------------------------------------------------------------------------
_re_orient = re.compile(r"Orientation:\s*([-\d.eE]+),\s*([-\d.eE]+),\s*([-\d.eE]+),\s*([-\d.eE]+)")
_re_size = re.compile(r"Size:\s*([-\d.eE]+)")
_re_model = re.compile(r"Model:\s*X\(([-\d.eE]+),\s*([-\d.eE]+)\),\s*Y\(([-\d.eE]+),\s*([-\d.eE]+)\),\s*Z\(([-\d.eE]+),\s*([-\d.eE]+)\)")
class View:
"""Maps model coordinates to final image pixels (top-left origin)."""
def __init__(self, orient, size, model, w, h):
x, y, z, wq = orient
n = np.sqrt(x*x + y*y + z*z + wq*wq) or 1.0
x, y, z, wq = x/n, y/n, z/n, wq/n
R = np.array([
[1-2*(y*y+z*z), 2*(x*y-wq*z), 2*(x*z+wq*y)],
[2*(x*y+wq*z), 1-2*(x*x+z*z), 2*(y*z-wq*x)],
[2*(x*z-wq*y), 2*(y*z+wq*x), 1-2*(x*x+y*y)],
])
self.R = R.T # rt reports view->model; we need model->view
self.size = size
xmn, xmx, ymn, ymx, zmn, zmx = model
self.center = np.array([(xmn+xmx)/2, (ymn+ymx)/2, (zmn+zmx)/2])
self.w, self.h = w, h
def project(self, P):
v = self.R @ (np.asarray(P, float) - self.center)
px = (v[0] / self.size + 0.5) * self.w
py = (0.5 - v[1] / self.size) * self.h
return px, py
def _parse_view(err, w, h):
mo, ms, mm = _re_orient.search(err), _re_size.search(err), _re_model.search(err)
if not (mo and ms and mm):
sys.stderr.write(err + "\n")
raise RuntimeError("rt did not report a view")
return (tuple(float(g) for g in mo.groups()),
float(ms.group(1)),
tuple(float(g) for g in mm.groups()))
# ----------------------------------------------------------------------------
# Framebuffer primitives (all via BRL-CAD tools)
# ----------------------------------------------------------------------------
# IMPORTANT: libfb reads a framebuffer name containing ":" (e.g. a Windows
# "D:\..." path) as host:port and tries to open a *network* framebuffer. So
# every framebuffer device below is a bare relative name and the tool is run
# with its cwd set to the directory that holds it.
def _run(cmd, cwd=None, timeout=25, retries=3):
"""Run a tool, killing and retrying if it hangs.
The tiny framebuffer tools (fbline/fblabel/fb-png/...) occasionally hang on
Windows (a virus scanner touching the frequently-rewritten .fb file); a
bounded timeout + retry keeps a single stuck call from stalling the whole
render. rt/rtedge pass a larger timeout for slow (e.g. -P1 NMG) shots.
"""
last = None
for _ in range(retries):
try:
return subprocess.run(cmd, capture_output=True, text=True,
cwd=cwd, timeout=timeout)
except subprocess.TimeoutExpired as e:
last = e
continue
sys.stderr.write("timed out after %d tries: %s\n" % (retries, cmd[0]))
return subprocess.CompletedProcess(cmd, 1, "", str(last))
def _prepare_out(path):
"""Ensure `path` is writable (clear a stale read-only attribute) so tools
can overwrite it, then remove it so a fresh file is created."""
import stat
if os.path.exists(path):
try:
os.chmod(path, stat.S_IWRITE | stat.S_IREAD)
os.remove(path)
except OSError:
pass
def fbclear(fb, size, rgb, cwd):
_run([_exe("fbclear"), "-F", fb, "-w", str(size), "-n", str(size),
str(rgb[0]), str(rgb[1]), str(rgb[2])], cwd=cwd)
def fbline(fb, size, x0, y0, x1, y1, rgb, cwd):
# framebuffer origin is bottom-left; caller supplies top-left pixels
y0 = size - 1 - y0
y1 = size - 1 - y1
_run([_exe("fbline"), "-F", fb, "-W", str(size), "-N", str(size),
"-r", str(rgb[0]), "-g", str(rgb[1]), "-b", str(rgb[2]),
str(int(round(x0))), str(int(round(y0))),
str(int(round(x1))), str(int(round(y1)))], cwd=cwd)
def fblabel(fb, size, x, y, text, rgb, cwd):
y = size - 1 - y
_run([_exe("fblabel"), "-F", fb, "-W", str(size), "-N", str(size),
"-C", _c(rgb), str(int(round(x))), str(int(round(y))), text], cwd=cwd)
def _white_block(path, w, h, rgb):
with open(path, "wb") as fh:
fh.write(bytes(rgb) * (w * h))
def fb_png(fb, size, out, cwd):
_run([_exe("fb-png"), "-F", fb, "-w", str(size), "-n", str(size), out], cwd=cwd)
def fb_pix(fb, size, out, cwd):
_run([_exe("fb-pix"), "-F", fb, "-w", str(size), "-n", str(size), out], cwd=cwd)
# ----------------------------------------------------------------------------
# Object measurement (fit view to object)
# ----------------------------------------------------------------------------
def _object_fraction(png, bg):
"""max(width, height) of the non-background region, as a fraction of frame."""
from PIL import Image
im = np.asarray(Image.open(png).convert("RGB")).astype(int)
diff = np.abs(im - np.array(bg)).sum(2)
mask = diff > 24
if not mask.any():
return 1.0
ys, xs = np.where(mask)
fw = (xs.max() - xs.min() + 1) / im.shape[1]
fh = (ys.max() - ys.min() + 1) / im.shape[0]
return max(fw, fh)
# ----------------------------------------------------------------------------
# Annotation drawing
# ----------------------------------------------------------------------------
def _arrow(fb, size, a, b, rgb, cwd, head=True):
ax, ay = a
bx, by = b
fbline(fb, size, ax, ay, bx, by, rgb, cwd)
if head:
dx, dy = bx - ax, by - ay
L = (dx*dx + dy*dy) ** 0.5 or 1.0
dx, dy = dx / L, dy / L
hl = max(9, size * 0.02)
for ang in (2.618, -2.618): # +/-150 deg
ca, sa = np.cos(ang), np.sin(ang)
hx = bx + hl * (dx * ca - dy * sa)
hy = by + hl * (dx * sa + dy * ca)
fbline(fb, size, bx, by, hx, hy, rgb, cwd)
def _marker(fb, size, p, rgb, cwd):
x, y = p
r = max(4, int(size * 0.009)) # small cross (2 fb calls)
fbline(fb, size, x - r, y, x + r, y, rgb, cwd)
fbline(fb, size, x, y - r, x, y + r, rgb, cwd)
_HALO = (248, 249, 251)
def _label(fb, size, cwd, x, y, text, rgb):
"""Text with a light halo so it reads on light or dark areas.
Drawn as several offset copies in the halo color, then the text on top;
this avoids the disk-framebuffer quirks of clear-color and image blits.
"""
lx, ly = int(x), int(y)
for dx, dy in ((-2, -2), (2, 2)): # light halo, few draws
fblabel(fb, size, lx + dx, ly + dy, text, _HALO, cwd)
fblabel(fb, size, lx, ly, text, rgb, cwd)
def _draw_annotations(fb, size, view, anns, cwd):
for a in anns:
t = a["t"]
if t == "pt":
p = view.project(a["p"])
_marker(fb, size, p, VERTEX, cwd)
if a.get("label"):
off = a.get("off", (10, -18))
_label(fb, size, cwd, p[0] + off[0], p[1] + off[1],
a["label"], INK)
elif t in ("vec", "dim", "seg"):
pa = view.project(a["a"])
pb = view.project(a["b"])
if t == "seg":
fbline(fb, size, pa[0], pa[1], pb[0], pb[1], ACCENT, cwd)
elif t == "dim":
_arrow(fb, size, pb, pa, ACCENT, cwd)
_arrow(fb, size, pa, pb, ACCENT, cwd)
else:
_arrow(fb, size, pa, pb, ACCENT, cwd)
if a.get("label"):
off = a.get("off", (10, -16))
mx = (pa[0] + pb[0]) / 2 + off[0]
my = (pa[1] + pb[1]) / 2 + off[1]
_label(fb, size, cwd, mx, my, a["label"], ACCENT)
# ----------------------------------------------------------------------------
# The rendering entry point
# ----------------------------------------------------------------------------
def probe(gfile, obj, az=35, el=25, ambient=0.42, extra=None):
"""Autoview probe: returns (orientation, autosize, model_bbox, fill_fraction)."""
scratch_dir = _cwd(gfile)
gname = os.path.basename(gfile)
pn = os.path.splitext(gname)[0] + ".pr.png"
p = _run([_exe("rt"), "-o", pn, "-w", "220", "-n", "220", "-C", _c(BG),
"-A", str(ambient), "-a", str(az), "-e", str(el)]
+ (extra or []) + [gname, obj], cwd=scratch_dir, timeout=90)
orient, autosize, model = _parse_view(p.stderr + p.stdout, 220, 220)
frac = _object_fraction(os.path.join(scratch_dir, pn), BG)
try:
os.remove(os.path.join(scratch_dir, pn))
except OSError:
pass
return orient, autosize, model, frac
def eye_for(center, az, el, dist):
"""Eye point that looks at `center` from the given az/el at `dist` mm."""
import math
a, e = math.radians(az), math.radians(el)
d = (math.cos(e)*math.cos(a), math.cos(e)*math.sin(a), math.sin(e))
return (center[0]+d[0]*dist, center[1]+d[1]*dist, center[2]+d[2]*dist)
def render(gfile, obj, out_png, size=600, az=35, el=25, fill=0.82,
color=FG, anns=None, hyper=2, ambient=0.42, edge=EDGE, caption=None,
view=None, extra=None):
"""Shaded rt render + rtedge overlay + parameter callouts.
If `view` = (orientation, eye_pt, viewsize) is given, that exact view is
used (so several images can share one frame -- e.g. the Boolean montage);
otherwise the object is probed and a viewsize chosen to fill `fill` of the
frame. Callouts require the probe path (they need the projection).
`extra` is a list of extra flags passed to rt and rtedge (e.g. ["-P1"] to
force single-threaded shooting -- the NMG hitmiss freelist is a global that
is not thread-safe).
"""
extra = extra or []
scratch_dir = _cwd(gfile)
gname = os.path.basename(gfile)
gbase = os.path.splitext(gname)[0] # unique per object -> parallel-safe
fb = gbase + ".render.fb"
vobj = None
if view is not None:
orient, eye, viewsize = view
common = ["-w", str(size), "-n", str(size),
"-c", "orientation %g %g %g %g" % tuple(orient),
"-c", "eye_pt %g %g %g" % tuple(eye),
"-c", "viewsize %g" % viewsize]
else:
orient, autosize, model, frac = probe(gfile, obj, az, el, ambient, extra)
viewsize = autosize * frac / fill
vobj = View(orient, viewsize, model, size, size)
common = ["-w", str(size), "-n", str(size), "-a", str(az), "-e", str(el),
"-c", "viewsize %g" % viewsize]
# shaded render into a pre-sized disk framebuffer
fbclear(fb, size, BG, scratch_dir)
_run([_exe("rt"), "-F", fb] + common + extra + ["-C", _c(BG),
"-A", str(ambient), "-H", str(hyper), gname, obj],
cwd=scratch_dir, timeout=90)
# overlay silhouette + crease edges (both sides, antialiased)
_run([_exe("rtedge"), "-F", fb] + common + extra + [
"-c", "set overlay=1", "-c", "set detect_distance=1",
"-c", "set detect_normals=1", "-c", "set both_sides=1",
"-c", "set antialias=1", "-c", "set fg=%s" % _c(edge),
gname, obj], cwd=scratch_dir, timeout=90)
# parameter callouts
if anns and vobj is not None:
_draw_annotations(fb, size, vobj, anns, scratch_dir)
if caption:
cx = int(size / 2 - len(caption) * (_CHARW / 2.0))
_label(fb, size, scratch_dir, cx, size - 20, caption, INK)
_prepare_out(out_png)
fb_png(fb, size, out_png, scratch_dir)
fp = os.path.join(scratch_dir, fb)
if os.path.exists(fp):
os.remove(fp)
return vobj
def render_cell(gfile, obj, out_png, size=360, caption=None, az=35, el=25,
fill=0.82, color=FG, hyper=2, ambient=0.42, view=None, extra=None):
"""Render one montage cell (shaded + edges + burned-in caption) to a PNG.
Rendered at 512 (the disk framebuffer only behaves at >= 512), with the
caption drawn on the framebuffer, then downsampled to `size`.
"""
scratch_dir = _cwd(gfile)
tmp_png = os.path.basename(out_png) + ".r.png"
render(gfile, obj, os.path.join(scratch_dir, tmp_png), size=512,
az=az, el=el, fill=fill, anns=None, hyper=hyper, ambient=ambient,
caption=caption, view=view, extra=extra)
from PIL import Image
im = Image.open(os.path.join(scratch_dir, tmp_png)).convert("RGB")
im.load()
_prepare_out(out_png)
im.resize((size, size), Image.LANCZOS).save(out_png)
im.close()
try:
os.remove(os.path.join(scratch_dir, tmp_png))
except OSError:
pass
def montage(cell_pngs, out_png, cell=360, gap=18, cols=None):
"""Tile captioned cell PNGs (rendered + labelled by BRL-CAD) into a grid.
This is pure image layout (PIL paste): every pixel of every cell, including
its caption, was produced by rt/rtedge/fblabel above.
"""
from PIL import Image
n = len(cell_pngs)
if cols is None:
cols = n if n <= 4 else (n + 1) // 2
rows = (n + cols - 1) // cols
W = cols * cell + (cols + 1) * gap
H = rows * cell + (rows + 1) * gap
canvas = Image.new("RGB", (W, H), BG)
for i, p in enumerate(cell_pngs):
r, c = divmod(i, cols)
im = Image.open(p).convert("RGB")
im.load()
if im.size != (cell, cell):
im = im.resize((cell, cell), Image.LANCZOS)
canvas.paste(im, (gap + c * (cell + gap), gap + r * (cell + gap)))
im.close()
_prepare_out(out_png)
canvas.save(out_png)
if __name__ == "__main__":
print("BIN =", BIN)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 44 KiB

+8 -24
View File
@@ -2452,13 +2452,13 @@ mged> bev -t triangulated_lens sphere1 + sphere2
– Create a triangulated object by intersecting objects _sphere1_ and _sphere2._
*bo*_[-o|-i pattern [h|n]type] dest source_
*bo*_[-o|-i pattern type] dest source_
The “bo” command is used to create or retrieve binary opaque objects. One of _-i_ or _-o_ must be specified.
The _-o_ option “outputs” or extracts a binary object from the database object _source_ to a host-order file called _dest_.
The _-o_ option “outputs” or extracts a binary object from the database object _source_ to a file called _dest_.
The _-i_ option “inputs” or imports a file called _source_ into a binary object called _dest_ in the database. There are two additional arguments that must be specified with the _-i_ option: pattern and type. Currently, only uniform binary objects (arrays of values) are supported. As a result, the _pattern_ is always _u_ for “uniform” pattern. Input defaults to host byte order. An `h` or `n` prefix on _type_ explicitly selects host or network byte order. The base _type_ can be one of the following:
The _-i_ option “inputs” or imports a file called _source_ into a binary object called _dest_ in the database. There are two additional arguments that must be specified with the _-i_ option: pattern and type. Currently, only uniform binary objects (arrays of values) are supported. As a result, the _pattern_ is always _u_ for “uniform” pattern. The _type_ can be one of the following:
_f_-> float
@@ -2482,14 +2482,10 @@ _L_-> unsigned long (64 bit)
Examples:
`mged>` *bo -i u c cmds /usr/brlcad/html/manuals/mged/mged_cmds.html*
`mged>` *bo -i -u c cmds /usr/brlcad/html/manuals/mged/mged_cmds.html*
– Create an opaque uniform binary object of characters with the name _cmds_ that contains the contents of the file __/usr/brlcad/html/manuals/mged/mged_cmds.html.__
`mged>` *bo -i u nS dsp.data terrain.dsp*
– Import a standard network-order DSP data file as an unsigned-short binary object named _dsp.data_.
`mged>` *bo -o /home/jim/cmds.html cmds*
– Copy the contents of the binary object named _cmds_ into the file named _/home/jim/cmds.html._
@@ -4318,8 +4314,8 @@ mged> nmg_simplify poly shapea.poly shapea.nmg
**
oed path_lhs [path_rhs]::
The “oed” command places MGED directly into matrix edit mode. With one path, __path_lhs__ is the complete path to the object being edited; the matrix immediately above its final component is selected and the object's bounding-box center is used as the keypoint. With two paths, __path_rhs__ must end in a primitive shape, and __path_lhs__ must identify a combination containing the first component of __path_rhs__. The matrix between the final component of __path_lhs__ and the first component of __path_rhs__ is selected, and the final primitive in __path_rhs__ supplies the keypoint. The selected object path must currently be displayed in MGED.
oed path_lhs path_rhs::
The “oed” command places MGED directly into the matrix edit mode. The __path_rhs__ must be a path to a primitive shape, and __path_lhs__ must be a path to a combination that includes the first component of __path_rhs__ as one of its members. Also, path_rhs/path_lhs must be a path that is currently displayed in mged. The edited matrix will be the matrix in the final component of __path_lhs__ that corresponds to the first component of __path_rhs__. The last component in __path_rhs__ is used as the reference shape during object editing.
Examples:::
@@ -4329,12 +4325,6 @@ mged> oed group1/group2 region1/shapea
– Place MGED into matrix edit mode, editing the matrix in _group2_ that corresponds to _region1_, using _shapea_ as the reference shape.
mged> oed group1/group2/region1
– Place MGED into matrix edit mode for _region1_, using the center of its bounding box as the keypoint.
**
@@ -6433,18 +6423,12 @@ mged *rset r draw 1* – Draw rubber band.
mged *rset ax*
Axes model_draw=0 model_size=500 model_linewidth=1 model_pos=0,0,0 model_tick_enable=0 model_tick_interval=100 model_ticks_per_major=10 model_tick_length=4 model_tick_major_length=8 model_tick_threshold=8 view_draw=0 view_size=500 view_linewidth=1 view_pos=0,0 edit_draw=0 edit_size1=500 edit_size2=500 edit_linewidth1=1 edit_linewidth2=1.
Axes model_draw=0 model_size=500 model_linewidth=1 model_pos=0,0,0 view_draw=0 view_size=500 view_linewidth=1 view_pos=0,0 edit_draw=0 edit_size1=500 edit_size2=500 edit_linewidth1=1 edit_linewidth2=1.
–Prints the values of the axes
mged *rset ax model_size* – Get size of model axes 500.
mged *rset ax model_tick_enable* – Enable (1) or disable (0) a ticked scale
along the model axes. The tick spacing is set with *rset ax
model_tick_interval* (in mm), with a major tick every *rset ax
model_ticks_per_major* ticks. This gives a measurable scale in the target
coordinate system.
**
@@ -6959,7 +6943,7 @@ A <<REGION,region>> may be assigned an integer _material code_ by the user. This
*matrix edit mode*
This is the mode that <<mged,_mged_>> is in while editing a transformation matrix in a <<COMBINATION,combination>>. It is characterized by the illumination of one object in the graphics window, and the appearance of matrix editing selections in the _Edit_ menu. This mode may be entered through the _Matrix Selection.._ entry of the _Edit_ menu, or via the <<oed,_oed_>> command. Editing operations such as rotation, translation, and scale may be performed in this mode and will affect all objects below the edited matrix in the <<tree,tree>>. These operations are applied relative to a keypoint obtained from a key solid, an object's bounding-box center, or an explicit *keypoint* command.
This is the mode that <<mged,_mged_>> is in while editing a transformation matrix in a <<COMBINATION,combination>>. It is characterized by the illumination of one object in the graphics window, and the appearance of matrix editing selections in the _Edit_ menu. This mode may be entered through the _Matrix Selection.._ entry of the _Edit_ menu, or via the <<oed,_oed_>> command. Editing operations such as rotation, translation, and scale may be performed in this mode and will affect all objects below the edited matrix in the <<tree,tree>>. These operations will be applied in reference to a key solid that is a leaf of that tree.
*member*
File diff suppressed because it is too large Load Diff
+11 -41
View File
@@ -12,17 +12,9 @@ The syntax of *oed* is fairly straightforward: footnote:[Note: _lhs_ is an abbre
[source]
----
oed {path_lhs} [{path_rhs}]
oed {path_lhs} {path_rhs}
----
When only __path_lhs__ is specified, it is the complete path to the
object being edited. The matrix immediately above its final component is
selected, and the center of that object's bounding box is used as the
editing keypoint. When __path_rhs__ is also specified, the two paths are
joined conceptually: the matrix between the final component of
__path_lhs__ and the first component of __path_rhs__ is selected, and the
primitive at the end of __path_rhs__ supplies the keypoint.
*oed* serves primarily to make working with combinations and regions practical when there are large numbers of primitives involved. It is of course possible to move primitives one by one to desired locations, but the process is extremely tedious for any non-trivial combination of primitives and the result is inflexible - for example,if the modeler wished to return the primitives in a combination to their original position after moving them _as primitives_ the process of moving them would need to be reversed one by one as well. Barring being able to do everything perfectly the first time, individual primitive placement is impractical.
The notion of _path_ in this context refers to the tree of objects that traditionally makes up a CSG model. Primitives will be combined with other primitives to make groups of objects, and the "path" to any individual shape within the combinations is described by the series of nodes in the tree that identify the object of interest. For example, take a simple model of a lollipop:
@@ -65,22 +57,14 @@ In the "file system" of a BRL-CAD object combinations can hold combinations, reg
....
To operate on this combination without choosing a primitive keypoint, use
the complete object path as the single argument:
Note that if we wish to operate on this combination it is not enough to specify /lollipop/outer-candy-shell.r for the lhs and outer-candy-sphere.c for the rhs - _combinations and regions do not themselves have default control points._ In other words, if you want to rotate a combination there must be a point around which that rotation occurs - a combination will have no default point assigned. This is the reason the rhs must always end with a primitive - even though the intent is not to edit the primitive, information necessary for most operations on the combination will use information (such as default keypoint settings) that the primitive _does_ have. So,
....
oed /lollipop/outer-candy-shell.r/outer-candy-sphere.c
oed /lollipop/outer-candy-shell.r outer-candy-sphere.c
....
This form uses the center of the bounding box of
__outer-candy-sphere.c__ as the keypoint. To use a primitive's default
keypoint instead, split the path at the matrix to edit and supply a right
hand path ending in that primitive. For example, any of the following
selects the matrix between __outer-candy-shell.r__ and
__outer-candy-sphere.c__ while obtaining the keypoint from a different
primitive:
is not enough. Either
....
@@ -102,10 +86,7 @@ or
oed /lollipop/outer-candy-shell.r outer-candy-sphere.c/stick.s
....
Because they are primitives in the outer-candy-sphere.c combination,
outer-candy-sphere.s, core.s and stick.s are all legal reference shapes -
there will be illustrations later of the consequences of different
primitive choices.
is needed to have *oed* actually enter edit mode on lollipop's outer-candy-sphere.c. Because they are primitives in the outer-candy-sphere.c combination, outer-candy-sphere.s, core.s and stick.s are all legal - there will be illustrations later of the consequences of different primitive choices.
To demonstrate basic *oed* behavior an example is in order. footnote:[Bear in mind that these examples will be using very basic primitives for the sake of simplicity and it is not guaranteed that they will behave well for things like raytracing. In this document raytraced screenshots are included to aid visualization. Most of them are simple but there are sometimes a number of extra steps needed to actually allow the objects to be raytraced with the results seen here.] footnote:[__path_lhs__ will be set to "/" for these simple cases - this means either we will be working with combinations that are not contained within any other combination/region or the intent is to transform _every_ instance of the combination/region present regardless of where it appears in the tree structure. "/" denotes the toplevel lhs path, or the "root of all trees" in the database. Because every object in the database exists "on its own" at the top level as well as inside tree structures, operating on any object with a "/" path_lhs will always edit the matrix associated with that particular combination/region independently of any other transformations applied within tree structures.]
@@ -400,7 +381,7 @@ Now the primitives have changed, and the combination is back to being just a boo
[[Right_Hand_Path_Section]]
== Right Hand Path Selection - Reasons and Implications
Notice in the previous section that sphere.s was explicitly selected as part of the *oed* __path_rhs__. What would the impact have been had cube.s been selected instead?
Notice in the previous section that sphere.s was selected when using the *oed* command as part of the path_rhs. What would the impact have been had cube.s been selected instead?
Using the commands shown below, clear the old object1.c tree from MGED, re-insert the primitives, and make a combination as before. This time make two objects using the same primitives, for later use. At the moment, only the object2.c combination will be displayed.
@@ -541,22 +522,13 @@ object2.c: --
Selection of a particular primitive when using the two-path form of *oed*
will depend on the particular situation. If no primitive has an
appropriate default keypoint, use the one-path form to select the object's
bounding-box center or set the keypoint explicitly after entering object
edit mode.
Selection of a particular primitive when using *oed* will depend on the particular situation. Combinations do not have control points of their own, and thus cannot provide any basis for these operations - a primitive MUST be supplied for every *oed* operation.
[[Flexible_Manipulation]]
== Flexible Manipulation with keypoint
The one-path form of *oed* uses the center of the specified object's
bounding box as the point from which translations, rotations, and scaling
are defined. The two-path form instead derives this point from the
specified primitive. BRL-CAD's term for this point is the _keypoint_. For
cases where neither default is appropriate, BRL-CAD also offers an option
for explicitly setting the keypoint.
It might be reasonable to expect the *oed* command to use the center of the combination bounding box as a default if no primitive is supplied and/or take as an optional parameter an explicit keypoint setting, but this is not the current behavior of BRL-CAD as of version 7.12 - a primitive is required. As seen in the previous section, the *oed* uses the specified primitive to select a point from which translations/rotations/etc. are defined. BRL-CAD's term for this point is the _keypoint_. For cases where it is not practical to select a primitive that will provide the correct keypoint, BRL-CAD does offer an option for explicitly setting the keypoint.
For example, to rotate object2.c around the z axis intersecting point (2,2,0) the keypoint must be set explicitly - this is not a point that can be selected by identifying a primitive.
@@ -578,7 +550,7 @@ keypoint
....
V (-5, 5, 5)
(null) (-5, 5, 5)
....
In order to set a new keypoint, we simply supply an x y z style coordinate option to the keypoint command:
@@ -915,11 +887,9 @@ The major points of the *oed* command are:
* *oed* is the standard tool when working with combinations and regions instead of primitives.
* Object edit mode does not alter primitives directly but instead works on a transformation matrix that BRL-CAD uses when interpreting the primitive.
* If __path_rhs__ is omitted, __path_lhs__ is the complete path to the object being edited and its bounding-box center is the keypoint.
* If __path_rhs__ is supplied, it must end in a primitive shape whose default keypoint will be used for object editing.
* BRL-CAD requires that a primitive shape be supplied at the end of the __path_rhs__ for all object edit mode operations.
* *push* is used to force changes corresponding to the transformation down to the primitives, but the operation is destructive in that it replaces the previous information defining the primitive.
* _keypoint_ is used in object edit mode as the point moved by *translate* operations and around which rotations occur. It is set from the object's bounding-box center or the primitive supplied to *oed*, and can also be set manually in object edit mode with the *keypoint* command.
* _keypoint_ is used in object edit mode as the point moved by *translate* operations and around with rotations occur - it is set from the primitive supplied to *oed* but can also be set manually when in object edit mode with the *keynote* command.
* When editing objects inside other objects it is important to remember to use __path_lhs__ to precisely identify the shape to be worked on - subtle and messy errors are possible if the wrong path is used.
* When using *oed* in a script, the object must be in view so a *B* or *draw* command to select the object must be entered before using the *oed* command on it.
@@ -79,7 +79,7 @@ building the `procedural-gallery-snapshot` target.
|image:images/gallery_brickwall.png[brickwall,512]
|*brickwall*: Builds a brick wall: emits mged commands that create RPP brick solids arranged in rows (with optional mortar slabs between them) to fill a specified wall width and height. Output is a stream of mged commands on stdout, not a .g directly.
|image:images/gallery_mkbuilding.png[mkbuilding,512]
|*mkbuilding*: Generates physically dimensioned buildings from presets, a validated native JSON schema, OSM GeoJSON or Overpass data, and CityJSON 2.x. It supports arbitrary footprints, storeys and basements, material-separated envelopes and roofs, doors and windows, structural grids, installations, and nested building parts.
|*mkbuilding*: Procedurally builds a small building: a floor slab, four framed walls with openings, and an overhanging roof.
|image:images/gallery_cchannel.png[cchannel,512]
|*cchannel*: Creates a section of fully configurable C-channel (structural metal beam). Default is a 1" diameter by 12" long section of American standard C-channel, here generated with a row of drilled holes.
|image:images/gallery_ringworld.png[ringworld,512]
@@ -22,7 +22,7 @@ set(RENDERER_GALLERY_ITEM_4 [=[rt_l4|RT lighting models|rt|png|-l4|rt -l4 curva
set(RENDERER_GALLERY_ITEM_5 [=[rt_l5|RT lighting models|rt|png|-l5|rt -l5 principal direction|Principal curvature direction debug display.]=])
set(RENDERER_GALLERY_ITEM_6 [=[rt_l6|RT lighting models|rt|png|-l6|rt -l6 UV|UV coordinate test-map style; U appears in red and V in blue.]=])
set(RENDERER_GALLERY_ITEM_7 [=[rt_l7|RT lighting models|rt|png|-l7,1024,0,8,60.0,1,0,0,0,1.0,|rt -l7 photon map|Photon-mapping global illumination using a small deterministic photon count so regeneration remains quick enough for documentation snapshots.]=])
set(RENDERER_GALLERY_ITEM_8 [=[rt_l8|RT lighting models|rt|png|-l8|rt -l8 heat graph|Heat-graph diagnostic mode maps the high-resolution current-thread CPU time needed to render each fully shaded pixel to grayscale; brighter pixels took longer to render.]=])
set(RENDERER_GALLERY_ITEM_8 [=[rt_l8|RT lighting models|rt|png|-l8|rt -l8 heat graph|Heat-graph mode. Current PNG file output matches the shaded image while heat timing is reported in the render log.]=])
set(RENDERER_GALLERY_ITEM_9 [=[rt_haze|RT output options|rt|png|-m 0.0008,0.55,0.72,0.92|rt haze|Full lighting with atmospheric haze enabled.]=])
set(RENDERER_GALLERY_ITEM_10 [=[rt_cutaway|RT output options|rt|png|-k 0,1,0,260|rt cut plane|Full lighting with a view-wide cutting plane applied at render time.]=])
+1 -1
View File
@@ -43,7 +43,7 @@ regenerate them from the built tools by configuring with
|image:images/renderer_gallery_rt_l7.png[rt_l7,512]
|*rt -l7 photon map*: Photon-mapping global illumination using a small deterministic photon count so regeneration remains quick enough for documentation snapshots.
|image:images/renderer_gallery_rt_l8.png[rt_l8,512]
|*rt -l8 heat graph*: Heat-graph diagnostic mode maps the high-resolution current-thread CPU time needed to render each fully shaded pixel to grayscale; brighter pixels took longer to render.
|*rt -l8 heat graph*: Heat-graph mode. Current PNG file output matches the shaded image while heat timing is reported in the render log.
|===
== RT output options

Some files were not shown because too many files have changed in this diff Show More