Compare commits
36
Commits
@@ -1,2 +0,0 @@
|
||||
# Try to tell GitHub how to handle .asc files
|
||||
*.asc linguist-language=Tcl
|
||||
@@ -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."
|
||||
@@ -1,637 +0,0 @@
|
||||
# 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.
|
||||
|
||||
name: Distcheck
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '30 3 * * 5'
|
||||
|
||||
jobs:
|
||||
bext:
|
||||
name: Prepare bext
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
steps:
|
||||
- name: Setup - CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- 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
|
||||
# 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: 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 }}
|
||||
|
||||
distcheck-default_build_type:
|
||||
name: distcheck-default_build_type
|
||||
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-default_build_type
|
||||
- name: Configure
|
||||
run: cmake -S brlcad -B build_distcheck-default_build_type -G Ninja -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output
|
||||
- name: Build
|
||||
run: cmake --build build_distcheck-default_build_type --target distcheck-default_build_type
|
||||
- name: Log
|
||||
if: always()
|
||||
run: cat build_distcheck-default_build_type/distcheck-default_build_type.log
|
||||
|
||||
distcheck-debug:
|
||||
name: distcheck-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-debug
|
||||
- name: Configure
|
||||
run: cmake -S brlcad -B build_distcheck-debug -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBRLCAD_EXT_DIR=${{ runner.temp }}/bext_output
|
||||
- name: Build
|
||||
run: cmake --build build_distcheck-debug --config Debug --target distcheck-debug
|
||||
- name: Log
|
||||
if: always()
|
||||
run: cat build_distcheck-debug/distcheck-debug.log
|
||||
|
||||
distcheck-release:
|
||||
name: distcheck-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-release
|
||||
- name: Configure
|
||||
run: cmake -S brlcad -B build_distcheck-release -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_DIR=${{ runner.temp }}/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
|
||||
|
||||
distcheck-enableall_debug:
|
||||
name: distcheck-enableall_debug
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [distcheck-default_build_type]
|
||||
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-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
|
||||
- name: Build
|
||||
run: cmake --build build_distcheck-enableall_debug --config Debug --target distcheck-enableall_debug
|
||||
- name: Log
|
||||
if: always()
|
||||
run: cat build_distcheck-enableall_debug/distcheck-enableall_debug.log
|
||||
|
||||
distcheck-enableall_release:
|
||||
name: distcheck-enableall_release
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [distcheck-debug]
|
||||
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-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
|
||||
- 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
|
||||
|
||||
distcheck-prepared_debug:
|
||||
name: distcheck-prepared_debug
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [distcheck-release]
|
||||
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-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
|
||||
- name: Build
|
||||
run: cmake --build build_distcheck-prepared_debug --config Debug --target distcheck-prepared_debug
|
||||
- name: Log
|
||||
if: always()
|
||||
run: cat build_distcheck-prepared_debug/distcheck-prepared_debug.log
|
||||
|
||||
distcheck-prepared_release:
|
||||
name: distcheck-prepared_release
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [distcheck-no_unity_debug]
|
||||
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-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
|
||||
- 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
|
||||
|
||||
distcheck-no_tcl:
|
||||
name: distcheck-no_tcl
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [distcheck-no_unity_release]
|
||||
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_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
|
||||
- name: Build
|
||||
run: cmake --build build_distcheck-no_tcl --config Debug --target distcheck-no_tcl
|
||||
- name: Log
|
||||
if: always()
|
||||
run: cat build_distcheck-no_tcl/distcheck-no_tcl.log
|
||||
|
||||
distcheck-no_tk:
|
||||
name: distcheck-no_tk
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [distcheck-enableall_debug]
|
||||
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 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_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
|
||||
- name: Build
|
||||
run: cmake --build build_distcheck-no_tk --config Debug --target distcheck-no_tk
|
||||
- name: Log
|
||||
if: always()
|
||||
run: cat build_distcheck-no_tk/distcheck-no_tk.log
|
||||
|
||||
distcheck-no_strict:
|
||||
name: distcheck-no_strict
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [distcheck-enableall_release]
|
||||
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_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
|
||||
- name: Build
|
||||
run: cmake --build build_distcheck-no_strict --config Debug --target distcheck-no_strict
|
||||
- name: Log
|
||||
if: always()
|
||||
run: cat build_distcheck-no_strict/distcheck-no_strict.log
|
||||
|
||||
distcheck-no_object:
|
||||
name: distcheck-no_object
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [distcheck-prepared_debug]
|
||||
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_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
|
||||
- name: Build
|
||||
run: cmake --build build_distcheck-no_object --config Debug --target distcheck-no_object
|
||||
- name: Log
|
||||
if: always()
|
||||
run: cat build_distcheck-no_object/distcheck-no_object.log
|
||||
|
||||
distcheck-odd_pathnames:
|
||||
name: distcheck-odd_pathnames
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [distcheck-prepared_release]
|
||||
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-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
|
||||
- name: Build
|
||||
run: cmake --build build_distcheck-odd_pathnames --config Debug --target distcheck-odd_pathnames
|
||||
- name: Log
|
||||
if: always()
|
||||
run: cat build_distcheck-odd_pathnames/distcheck-odd_pathnames.log
|
||||
|
||||
distcheck-in_src_dir:
|
||||
name: distcheck-in_src_dir
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [distcheck-no_tcl]
|
||||
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-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
|
||||
- name: Build
|
||||
run: cmake --build build_distcheck-in_src_dir --config Debug --target distcheck-in_src_dir
|
||||
- name: Log
|
||||
if: always()
|
||||
run: cat build_distcheck-in_src_dir/distcheck-in_src_dir.log
|
||||
@@ -1,85 +0,0 @@
|
||||
# The purpose of this particular test definition is to support on-demand
|
||||
# interactive command shells. We sometimes see problems that occur only in the
|
||||
# Github Runner environments, and in order to explore what is happening we need
|
||||
# an interactive prompt (the alternative is hours-per-cycle submit and test
|
||||
# loops, which doesn't scale at all.)
|
||||
#
|
||||
# Unlike the other BRL-CAD tests, this one is started manually from the Github
|
||||
# website. For more information see https://mxschmitt.github.io/action-tmate/
|
||||
#
|
||||
# The "recommended" way to use this action is for the dev to make a fork of
|
||||
# the repository, alter the configure and/or build logic below for their
|
||||
# particular use case (the example below is a libged-only build used to zero
|
||||
# in on a specific libged behavior) before running.
|
||||
|
||||
name: BRL-CAD Linux Interactive Debugging
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
debug_enabled:
|
||||
type: boolean
|
||||
description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)'
|
||||
required: false
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
|
||||
linux:
|
||||
name: Ubuntu Latest GCC
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Setup - CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- name: Setup - System
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
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 liblief-dev
|
||||
# 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
|
||||
# Cleanup (we want to avoid wasting disk space)
|
||||
sudo apt-get clean
|
||||
|
||||
- name: Setup - System Qt Build Requirements
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
run: |
|
||||
sudo apt-get update
|
||||
# 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 libxkbcommon-dev libxkbcommon-x11-dev
|
||||
sudo apt-get install libgl-dev
|
||||
sudo apt-get install libinput-dev
|
||||
sudo apt-get clean
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Build Directory setup
|
||||
run: |
|
||||
cmake -E make_directory ./build_linux
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
export PATH=$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
|
||||
cmake --build build_linux --config Release --target check
|
||||
|
||||
- name: Debugging - tmate session
|
||||
if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
with:
|
||||
limit-access-to-actor: true
|
||||
|
||||
@@ -1,449 +0,0 @@
|
||||
# This file defines Continuous Integration (CI) tests for BRL-CAD using the
|
||||
# Github Actions framework that are executed each time a commit is pushed.
|
||||
# Currently it defines configurations for Windows, Linux and OSX.
|
||||
#
|
||||
# For more information about available platforms for testing, see:
|
||||
#
|
||||
# https://docs.github.com/en/free-pro-team@latest/actions/reference/specifications-for-github-hosted-runners
|
||||
#
|
||||
# The general rule when building in CI is to go more verbose in output settings
|
||||
# rather than less, since iterative debugging isn't practical. We also want to
|
||||
# avoid parallel building - while that will sometimes catch dependency issues,
|
||||
# it also makes the outputs far harder to interpret when there is a problem.
|
||||
# Better to do parallel build debugging in an environment were more interactive
|
||||
# and iterative debugging is available while preserving the readability of the
|
||||
# CI outputs for other issues.
|
||||
|
||||
name: Per-push
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
|
||||
linux:
|
||||
name: Ubuntu GCC
|
||||
runs-on: ubuntu-24.04
|
||||
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
|
||||
- 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: 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
|
||||
cmake -E make_directory $HOME/.cache
|
||||
cmake -E make_directory $HOME/.cache/BRL-CAD
|
||||
|
||||
- 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
|
||||
|
||||
- name: Build
|
||||
id: build_parallel
|
||||
run: |
|
||||
export PATH=$GITHUB_WORKSPACE:$PATH
|
||||
cmake --build build_linux --config Release --target check -j2
|
||||
cmake --build build_linux --config Release --target package -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_linux --config Release --target check
|
||||
cmake --build build_linux --config Release --target package
|
||||
|
||||
# A full distcheck is too expensive for the runners, but we can run the
|
||||
# repository integrity check and make sure we can build source archives.
|
||||
archives:
|
||||
name: Source Archives
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [linux]
|
||||
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: 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 --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
|
||||
strategy:
|
||||
fail-fast: true
|
||||
if: github.event_name == 'push'
|
||||
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: pwsh
|
||||
run: Add-Content -Path $env:GITHUB_PATH -Value $env:GITHUB_WORKSPACE
|
||||
|
||||
- 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
|
||||
|
||||
- name: Build
|
||||
id: build_parallel
|
||||
shell: powershell
|
||||
run: |
|
||||
ninja
|
||||
working-directory: ${{ github.workspace }}/build_winninja
|
||||
continue-on-error: true
|
||||
|
||||
- name: Build (serial for diagnostics)
|
||||
if: steps.build_parallel.outcome == 'failure'
|
||||
shell: powershell
|
||||
run: |
|
||||
ninja -j1 -v
|
||||
working-directory: ${{ github.workspace }}/build_winninja
|
||||
|
||||
- name: Check
|
||||
shell: powershell
|
||||
run: |
|
||||
ninja check -v
|
||||
working-directory: ${{ github.workspace }}/build_winninja
|
||||
|
||||
- name: Package
|
||||
shell: powershell
|
||||
run: |
|
||||
ninja package
|
||||
working-directory: ${{ github.workspace }}/build_winninja
|
||||
|
||||
windows_std_tools:
|
||||
name: MSVC - Standard Tools
|
||||
needs: [windows]
|
||||
runs-on: windows-2025
|
||||
strategy:
|
||||
fail-fast: true
|
||||
if: github.event_name == 'push'
|
||||
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: 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
|
||||
|
||||
- name: Build
|
||||
id: build_parallel
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake --build build_winstd --config Release -j2
|
||||
continue-on-error: true
|
||||
|
||||
- name: Build (serial for diagnostics)
|
||||
if: steps.build_parallel.outcome == 'failure'
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake --build build_winstd --config Release --target mged
|
||||
|
||||
- name: Check
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake --build build_winstd --config Release --target check -j2
|
||||
|
||||
- name: Package
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake --build build_winstd --config Release --target package -j2
|
||||
|
||||
osx:
|
||||
name: macOS Clang
|
||||
needs: [linux]
|
||||
runs-on: macos-14
|
||||
strategy:
|
||||
fail-fast: true
|
||||
steps:
|
||||
- name: Setup - CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- name: Install Xquartz
|
||||
run: |
|
||||
brew install xquartz --cask
|
||||
|
||||
- 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
|
||||
cmake -E make_directory $HOME/.cache
|
||||
cmake -E make_directory $HOME/.cache/BRL-CAD
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
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
|
||||
|
||||
- name: Build
|
||||
id: build_parallel
|
||||
run: |
|
||||
export PATH=$GITHUB_WORKSPACE:$PATH
|
||||
make -j2
|
||||
working-directory: ${{ github.workspace }}/build_osx
|
||||
continue-on-error: true
|
||||
|
||||
- name: Build (serial for diagnostics)
|
||||
if: steps.build_parallel.outcome == 'failure'
|
||||
run: |
|
||||
make
|
||||
working-directory: ${{ github.workspace }}/build_osx
|
||||
|
||||
- name: Check
|
||||
run: |
|
||||
export PATH=$GITHUB_WORKSPACE:$PATH
|
||||
make check
|
||||
working-directory: ${{ github.workspace }}/build_osx
|
||||
|
||||
- name: Package
|
||||
run: |
|
||||
export PATH=$GITHUB_WORKSPACE:$PATH
|
||||
make package
|
||||
working-directory: ${{ github.workspace }}/build_osx
|
||||
@@ -1,400 +0,0 @@
|
||||
# This file defines Continuous Integration (CI) tests for BRL-CAD using the
|
||||
# Github Actions framework. Currently it defines configurations for Windows,
|
||||
# Linux and OSX. These tests are run on a fixed schedule, rather than per
|
||||
# push, and will typically take longer to run.
|
||||
#
|
||||
# Tests here are intended to test more expensive integrations and longer
|
||||
# builds than the ones targeted at per-commit feedback. The tradeoff is
|
||||
# that a failure in these tests might be cause by any commit within a
|
||||
# 24 hour block of time, so the developer will need to track down the
|
||||
# specifics themselves.
|
||||
|
||||
name: Scheduled
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 3 * * *' # daily at 03:00 UTC
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
linux_bext:
|
||||
name: Linux - BRL-CAD bext build
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: true
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
steps:
|
||||
- name: Setup - CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
# Install system dependencies
|
||||
- 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_linux
|
||||
cmake -E make_directory $HOME/.cache
|
||||
cmake -E make_directory $HOME/.cache/BRL-CAD
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
export PATH=$GITHUB_WORKSPACE:$PATH
|
||||
cmake -S brlcad -B build_linux -G Ninja -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_PARALLEL=1 -DBRLCAD_BEXT_CLEANUP=ON -DBRLCAD_ENABLE_QT=ON
|
||||
|
||||
- name: Build + Check + Package
|
||||
run: |
|
||||
export PATH=$GITHUB_WORKSPACE:$PATH
|
||||
cmake --build build_linux --config Release --target check
|
||||
cmake --build build_linux --config Release --target package
|
||||
|
||||
windows_bext:
|
||||
name: MSVC - Ninja - BRL-CAD bext build
|
||||
needs: [linux_bext]
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: true
|
||||
if: ${{ !cancelled() }}
|
||||
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: powershell
|
||||
run: Add-Content -Path $env:GITHUB_PATH -Value $env:GITHUB_WORKSPACE
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
path: brlcad
|
||||
|
||||
- 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" -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_PARALLEL=1 -DBRLCAD_BEXT_CLEANUP=ON -DBRLCAD_ENABLE_QT=ON
|
||||
|
||||
- name: Build
|
||||
shell: powershell
|
||||
run: |
|
||||
ninja -j1 -v
|
||||
working-directory: ${{ github.workspace }}/build_winninja
|
||||
|
||||
- name: Check
|
||||
shell: powershell
|
||||
run: |
|
||||
ninja check -v
|
||||
working-directory: ${{ github.workspace }}/build_winninja
|
||||
|
||||
- name: Package
|
||||
shell: powershell
|
||||
run: |
|
||||
ninja package
|
||||
working-directory: ${{ github.workspace }}/build_winninja
|
||||
|
||||
windows_std_tools_bext:
|
||||
name: MSVC - Standard Tools - BRL-CAD bext build
|
||||
needs: [windows_bext]
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: true
|
||||
if: ${{ !cancelled() }}
|
||||
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%"
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
path: brlcad
|
||||
|
||||
- name: Build Directory setup
|
||||
run: |
|
||||
cmake -E make_directory ./build_winstd
|
||||
|
||||
- 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
|
||||
|
||||
- name: Build
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake --build build_winstd --config Release --target mged
|
||||
|
||||
- name: Check
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake --build build_winstd --config Release --target check
|
||||
|
||||
- name: Package
|
||||
shell: cmd
|
||||
run: |
|
||||
cmake --build build_winstd --config Release --target package
|
||||
|
||||
osx_bext:
|
||||
name: macOS - BRL-CAD bext build
|
||||
needs: [linux_bext]
|
||||
runs-on: macos-14
|
||||
strategy:
|
||||
fail-fast: true
|
||||
if: ${{ !cancelled() }}
|
||||
steps:
|
||||
- name: Setup - CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- name: Install Xquartz
|
||||
run: |
|
||||
brew install xquartz --cask
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
path: brlcad
|
||||
|
||||
- name: Build Directory setup
|
||||
run: |
|
||||
cmake -E make_directory build_osx
|
||||
cmake -E make_directory $HOME/.cache
|
||||
cmake -E make_directory $HOME/.cache/BRL-CAD
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
export PATH=$GITHUB_WORKSPACE:$PATH
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
cmake -S brlcad -B build_osx -DCMAKE_BUILD_TYPE=Release -DBRLCAD_EXT_PARALLEL=1 -DBRLCAD_BEXT_CLEANUP=ON -DBRLCAD_ENABLE_QT=ON
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
make
|
||||
working-directory: ${{ github.workspace }}/build_osx
|
||||
|
||||
- name: Check
|
||||
run: |
|
||||
make check
|
||||
working-directory: ${{ github.workspace }}/build_osx
|
||||
|
||||
- name: Package
|
||||
run: |
|
||||
make package
|
||||
working-directory: ${{ github.workspace }}/build_osx
|
||||
|
||||
linux_static:
|
||||
name: Clang Static Analyser
|
||||
needs: [linux_bext]
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: true
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
|
||||
steps:
|
||||
- name: Setup - CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
# Setup hint from https://github.com/darktable-org/rawspeed/blob/develop/.github/workflows/ci-static-analysis.yml
|
||||
- name: Clang Static Analyzer Setup
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install clang-18 clang-tools-18
|
||||
# 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 # Cleanup
|
||||
|
||||
- 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
|
||||
cmake -E make_directory $HOME/.cache
|
||||
cmake -E make_directory $HOME/.cache/BRL-CAD
|
||||
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 .
|
||||
./clang-static-analyzer-run.sh
|
||||
working-directory: ${{ github.workspace }}/brlcad/build_clangstatic
|
||||
|
||||
- name: Summary
|
||||
if: success() || failure()
|
||||
run: |
|
||||
sudo apt-get install html2text
|
||||
html2text scan-reports-all/*/index.html
|
||||
working-directory: ${{ github.workspace }}/brlcad/build_clangstatic
|
||||
|
||||
|
||||
# See https://app.codecov.io/gh/BRL-CAD/brlcad for analysis results
|
||||
linux_cov:
|
||||
name: LCOV Coverage testing
|
||||
needs: [linux_bext]
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
fail-fast: true
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
if: ${{ !cancelled() && github.ref == 'refs/heads/main' }}
|
||||
steps:
|
||||
- name: Setup - CMake
|
||||
uses: lukka/get-cmake@latest
|
||||
|
||||
- name: Setup - System
|
||||
run: |
|
||||
sudo apt-get update
|
||||
# Get the lcov tool and its dependencies
|
||||
sudo apt-get install lcov gdb
|
||||
# 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: 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
|
||||
cmake -E make_directory $HOME/.cache
|
||||
cmake -E make_directory $HOME/.cache/BRL-CAD
|
||||
|
||||
- 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
|
||||
|
||||
- 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
|
||||
|
||||
- name: Run Tests
|
||||
id: coverage_tests
|
||||
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: |
|
||||
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
|
||||
rm coverage-*.info
|
||||
mv coverage_cad.info ..
|
||||
working-directory: ${{ github.workspace }}/build_lcov
|
||||
|
||||
- name: Upload
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
files: ./coverage_cad.info
|
||||
|
||||
+32
-40
@@ -1,41 +1,33 @@
|
||||
# Common build directories used in the source tree
|
||||
/build*
|
||||
/.build*
|
||||
/*_build*
|
||||
/*-build*
|
||||
/out
|
||||
|
||||
# Temporary files
|
||||
# CVS default ignores begin
|
||||
tags
|
||||
TAGS
|
||||
.make.state
|
||||
.nse_depinfo
|
||||
*~
|
||||
\#*\#
|
||||
.\#*
|
||||
[._]*.s[a-v][a-z]
|
||||
[._]*.sw[a-p]
|
||||
[._]s[a-v][a-z]
|
||||
[._]sw[a-p]
|
||||
|
||||
# OS specific files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
|
||||
# CMake supports some configuration files to allow users a convenient way to pre-define
|
||||
# sets of configuration options:
|
||||
# https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html
|
||||
/CMakeUserPresets.json
|
||||
|
||||
# Visual Studio (note that CMakePresets.json is recommended instead of
|
||||
# CMakeSettings.json for Visual Studio going forward)
|
||||
# https://learn.microsoft.com/en-us/cpp/build/cmake-presets-vs
|
||||
# https://learn.microsoft.com/en-us/cpp/build/customize-cmake-settings
|
||||
/.vs
|
||||
.vscode
|
||||
/CMakeSettings.json
|
||||
|
||||
#Qt Creator
|
||||
CMakeLists.txt.user
|
||||
|
||||
# Misc
|
||||
.clang-format
|
||||
*__pycache__*
|
||||
|
||||
|
||||
\#*
|
||||
.#*
|
||||
,*
|
||||
_$*
|
||||
*$
|
||||
*.old
|
||||
*.bak
|
||||
*.BAK
|
||||
*.orig
|
||||
*.rej
|
||||
.del-*
|
||||
*.a
|
||||
*.olb
|
||||
*.o
|
||||
*.obj
|
||||
*.so
|
||||
*.exe
|
||||
*.Z
|
||||
*.elc
|
||||
*.ln
|
||||
core
|
||||
# CVS default ignores end
|
||||
.lib*.* .proc-db.* .cvsignore .util.* .patch.* .burst.* .iges.* .mged.*
|
||||
.fbserv.* .canon.* .anim.* .bench.* .conv.* .remrt.* .tools.* .comgeom-g.*
|
||||
.tab.* .sig.* .irprep.* .vdeck.* .fbed.* .jack.* .vas4.* .off.* .jove.*
|
||||
.lgt.* .nirt.* .mk.* .db.* .fb.* .rt.* .halftone.* .gtools.*
|
||||
.cake*.* .bwish.* .cwish.* .tk.* .btclsh.* .iwidgets* .unigraphics.*
|
||||
|
||||
@@ -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.
|
||||
@@ -0,0 +1,65 @@
|
||||
The US Army BRL-CAD Develoment Team would like to take this opportunity
|
||||
to thank the many people and organizations who have contributed code or
|
||||
suggestions for improving the BRL-CAD Package:
|
||||
|
||||
Sun Microsystems (William C. Lindemann)
|
||||
mged/dm-sun.c
|
||||
|
||||
Sun Microsystems (Timothy G. Smith, Christopher J. Jackson, and James D. Fiori)
|
||||
Substantial fixes to ease Solaris 2.X porting
|
||||
24-bit LIBFB support
|
||||
New improved XGL support for Solaris
|
||||
|
||||
University of Alabama in Huntsville
|
||||
Research Institute, RI E-47
|
||||
Sparkman DR NW
|
||||
Huntsville, AL 35899
|
||||
POC: Mark Huston Bowden or M. Shane Strickland
|
||||
|
||||
mged/hideline.c Hidden line removal
|
||||
mged/dm-hp.c HP2397A terminal
|
||||
mged/m-ps390.c color version for serial line connection
|
||||
mged/dm-pss.c gsr routines
|
||||
|
||||
util/pl-hpgl.c convert UNIX-plot file to HP plotter language
|
||||
|
||||
Geometric Solutions, Inc (Christopher T. Johnson) <cjohnson@camelot.com>
|
||||
Paladin Software
|
||||
Cray Research, Inc.
|
||||
|
||||
halftone/*
|
||||
remrt/rtsrv control support, movie speed ups, extra commands
|
||||
A/UX support
|
||||
mged push support, articulation support, animation support
|
||||
located awf for brlman support.
|
||||
some plotting tools
|
||||
bug fixes
|
||||
too many dinner time bug reports
|
||||
format converter support (librt/cv_* routines), CV program
|
||||
scriptsort
|
||||
|
||||
Geometric Solutions: reed@camelot.com (Harry J. Reed)
|
||||
havoc.g
|
||||
tank-car.g
|
||||
t62a.g
|
||||
|
||||
Manchester-Computing-Centre, UK (Terry Hewitt)
|
||||
Computer Graphics Unit, MCC" <HEWITT@vmsfe.mcc.ac.uk>
|
||||
and
|
||||
Mario Brand <mgbk1@tnofel.fel.tno.nl>
|
||||
|
||||
Support for BRL-CAD on HP-9000/730:
|
||||
machinetype.sh, Cakefile.defs, libplot3/htond.c
|
||||
|
||||
Bill Laut (Gull Island Consultants, Inc.)
|
||||
P.O. Box 627, Muskegon, MI 49440
|
||||
rt/sh_marble.c -- substantial enhancements
|
||||
rt/sh_wood.c -- a completely new shader
|
||||
h/light.h enhancements
|
||||
rt/sh_light.c enhancements for more easily aimable lights.
|
||||
|
||||
Henry Spencer
|
||||
Regular expression library
|
||||
|
||||
John Ousterhout <john.ousterhout@eng.sun.com>
|
||||
Tcl/Tk
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,621 +0,0 @@
|
||||
BRL-CAD Bugs
|
||||
============
|
||||
|
||||
Bugs should be reported to the bug tracker on the project website at
|
||||
http://sourceforge.net/tracker/?atid=640802&group_id=105292
|
||||
|
||||
The bugs and issues listed in here may or may not be the same as or
|
||||
related to the bugs reported to the bug tracker. In general, users
|
||||
should not look to this file for information regarding the status of
|
||||
bugs. Informal bug-related information that is intended for
|
||||
developers will generally be found here. This may include short term
|
||||
issues that are in active development as well as long term and
|
||||
on-going issues.
|
||||
|
||||
Recent Bugs
|
||||
-----------
|
||||
|
||||
* fbserv as well as -F option handling (e.g., -F0 or -F/dev/wgls) that
|
||||
is supported across myriad other tools appears to be broken on
|
||||
Windows in a git bash shell (problem is not seen in Command Prompt.)
|
||||
Something is concatenating EXEPATH and/or fbserv silently fails with
|
||||
return codes (e.g., when not specifying -F, only giving the port.)
|
||||
|
||||
* recursive bu_parallel() failure, tbd whether cpp11 or pthread impl,
|
||||
likely because IDs are exceeding MAX_PSW, causing mayhem and chaos.
|
||||
|
||||
* 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.
|
||||
|
||||
* very peculiar non-linear memory issue in rt when allocating a large
|
||||
flat hierarchy of objects. I have three combs, each with 10k
|
||||
members unioned. Each member is an rcc. Rendering with just one
|
||||
comb results in about 2GB usage. Two combs result in about 3.5GB
|
||||
usage. Three combs results in 18GB usage. Four is killed after
|
||||
24GB. Suspect there is some 32-bit issue once we exceed 4GB that is
|
||||
causing subsequent allocations to be bigger than necessary. Looking
|
||||
at allocation stack, rt_ct_get() appears to be allocating 10MB
|
||||
chunks.
|
||||
|
||||
[HARD] Superlinear growth (3 combs -> 18GB) points at an
|
||||
integer/overflow interaction deep in the space-partitioning cut
|
||||
allocator (rt_ct_get 10MB chunks), intertwined with bu memory.
|
||||
Painful to isolate and validate at scale.
|
||||
[FAN-OUT: poor -- one focused investigator with an allocator/profiler
|
||||
trace; not parallelizable.]
|
||||
|
||||
* rt from mged is not outputting overlap log messages or rt summary.
|
||||
Stops printing after opendb line. (Observed on Mac)
|
||||
|
||||
* mged running an rt with excessive overlaps ends up in a deadlock.
|
||||
Backtrace indicates write buffer is full, likely because no output
|
||||
is going to terminal. (Observed on Mac)
|
||||
|
||||
* 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 %
|
||||
|
||||
* 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
|
||||
first character matching the v4 .g first character.
|
||||
|
||||
* MGED on Mac hides the main command window on File->Open when you
|
||||
cancel the open. Presumably the withdraw is somehow getting routed
|
||||
to the window and not just the open dialog.
|
||||
|
||||
* running pkgIndex and/or mkIndex during build appears to be randomly
|
||||
crashing on Mac using bundled libs
|
||||
|
||||
* Visual error when drawing using -S -m1 of a region with the same solid
|
||||
subtracted and then unioned.
|
||||
|
||||
make two boxes stacked on top of one another
|
||||
> r boxes.r u box - box1 u box1
|
||||
> e -S -m1 boxes.r
|
||||
box1 is not drawn
|
||||
|
||||
* 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
|
||||
brep ehy.
|
||||
|
||||
* ogl display manager still crashes on attach in mged on Mac OS X 10.5
|
||||
|
||||
* running archer "" at least on windows results in a file type dialog
|
||||
and errors with "can't read "_conv_log": no such variable
|
||||
|
||||
* 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
|
||||
|
||||
* object names with a / or \ in them make ls or underlying directory
|
||||
parsing logic display them incorrectly.
|
||||
|
||||
* search -exec results are inconsistent with search filtered
|
||||
results. for example, "search . -attr ..." returns A B C, but
|
||||
"search . -attr ... -exec attr show {} \;" results in attr show
|
||||
output for A B C as well as subtracted repetitions. For example,
|
||||
say A contains - B - C, then it will show output for A B C B C.
|
||||
|
||||
adding -bool u gets closer to consistent but still appears to repeat
|
||||
the last object
|
||||
|
||||
* fbclear -c appears to hang indefinitely inside pkg_bwaitfor,
|
||||
possible protocol mismatch or capability removed/changed in fbserv.
|
||||
|
||||
* apparently all four BRL-CAD Tutorial Series volumes are missing from
|
||||
our bibliography...
|
||||
|
||||
* mater -d information stored in the .g file doesn't survive a
|
||||
garbage collection operation.
|
||||
|
||||
|
||||
* fix checker.sh script and/or overlap GUI so that the latter will
|
||||
read the resulting overlap pairings file from the prior.
|
||||
alternatively, need to be able to run overlap check on server
|
||||
without GUI, so could implement an overlaps file output option to be
|
||||
run via mged -c.
|
||||
|
||||
* running 'put' on geometry that is already displayed results in a NaN
|
||||
view (at least View and Eye_pos parameters are non) despite geometry
|
||||
still being displayed. this causes 'rt' to fly into an infinite
|
||||
loop, presumably trying to increment rays from the eye position.
|
||||
|
||||
* 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.
|
||||
|
||||
* 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.
|
||||
Another (confirmed) hung mged (stuck/inf loop).
|
||||
|
||||
* annotation bugs:
|
||||
in sph1.s sph 0 0 0 10
|
||||
in ann1.s annot 0 0 0 test1 10 10 3 1
|
||||
in ann2.s annot 30 30 30 test2 40 40 3 1
|
||||
# ann2.s's label looks wrong, points at origin?
|
||||
in ann3.s annot 0 0 0 1 10 10 3 1
|
||||
# using numbers for a label results in no label
|
||||
|
||||
* 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.
|
||||
|
||||
* 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.
|
||||
Looks like this may be only in situations where the "-" is the
|
||||
lead character and on Windows? Been hard to reproduce...
|
||||
|
||||
* dsp does not facetize correctly with zero elevation areas in the
|
||||
data - need robustness improvements
|
||||
|
||||
* dsp primitives specifying data using Windows style file paths
|
||||
don't work.
|
||||
|
||||
* attempting to create a dsp using a binary object caused a crash on
|
||||
Linux - need to figure out if this was caused by feeding it the wrong
|
||||
kind of binary object or some other error...
|
||||
|
||||
* screengrab on windows does not work
|
||||
|
||||
* Recursive submodel predictably goes infinite, need stack-based
|
||||
db_walk_tree(): mged> in submodel submodel submodel grid test.g
|
||||
|
||||
* 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
|
||||
event issue. Inspecting further, it may be related to environments
|
||||
where shmget() fails (or is requested via /dev/oglp) and we get
|
||||
private memory -- looks like private memory is not initialized
|
||||
(observed on Mac 10.6, Windows, and Ubuntu Linux using 7.26).
|
||||
|
||||
* 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.
|
||||
|
||||
* rtedge doesn't refresh a /dev/X fbserv (presumably double-buffered)
|
||||
after doing an overlay render. it does draw, though, as confirmed
|
||||
by a forced fb-fb refresh.
|
||||
|
||||
* 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:
|
||||
rt_db_cvt_to_external5 expecting non-NULL name parameter
|
||||
wdb_export((null)): solid export failure
|
||||
|
||||
* report of mged command history not working with the down arrow key
|
||||
in 7.25.0 (on Windows, unknown on other platforms). Up arrow works
|
||||
fine.
|
||||
|
||||
* wgl framebuffer is not lingering on windows (regardless of using
|
||||
wgll or default) when it should
|
||||
|
||||
* report of LIBBU not working when accessed by a multithreaded
|
||||
application on Windows. reportedly due to some problem with the
|
||||
debug memory queue.
|
||||
|
||||
* report of g-iges crashing (on Windows) when exporting a 1.2MB BoT
|
||||
mesh (presumably imported via stl-g). worked for smaller models.
|
||||
|
||||
* autoview [scale] isn't updating the wireframe when opening a
|
||||
database, drawing geometry, then running autoview. the status bar
|
||||
shows the scale change, but the graphics window remains unaffected
|
||||
unless you run "view size" to set it.
|
||||
|
||||
* overlay command reports an error when trying to load a file
|
||||
names edges.pl, but succeeds when the file is called patches.pl
|
||||
Need to see why edges.pl is not accepted.
|
||||
|
||||
* step-g crashing on mac with lazy symbol load failure missing:
|
||||
brlcad::SurfaceTree::SurfaceTree(ON_BrepFace*, bool, int)
|
||||
|
||||
* metaball tessellation enters either an infinite loop or an absurdly
|
||||
long tessellation process - observed on Linux 64 bit system - quick
|
||||
test:
|
||||
|
||||
rm -f metaball.g && mged -c metaball.g "make m.s metaball; facetize m.bot m.s"
|
||||
|
||||
* corruption/crash issue rendering terra.g without terra.dsp,
|
||||
possibly/probably parallel-related in libbn/noise.c's
|
||||
bn_noise_turb() function. gdb eventually catches a segfault in
|
||||
find_spec_wgt() loop with indications of corrupted memory. valgrind
|
||||
confirms corrupted memory (8 bytes) after a build_spec_table()
|
||||
realloc within find_spec_wgt() but it's not clear why. etbl
|
||||
book-keeping seems okay.. corrupted read consistently detected on
|
||||
spec_wgts = ep->spec_wgts line in bn_noise_turb(). observed on
|
||||
64-bit linux system:
|
||||
|
||||
rm -f terra.pix && valgrind bin/rt -o terra.pix -P1 -H3 -s1024 share/brlcad/7.21.0/db/terra.g all.g
|
||||
|
||||
[HARD] valgrind-confirmed 8-byte corruption after a build_spec_table()
|
||||
realloc in find_spec_wgt(), where "bookkeeping seems okay" -- i.e.,
|
||||
root cause is non-obvious. Classic hard-to-pin data race.
|
||||
[FAN-OUT: poor -- a single heisenbug needing one careful
|
||||
investigator, not parallel coverage.]
|
||||
|
||||
* mged 'joint' hold command isn't working. looks like the fp_names
|
||||
book-keeping is fuxored or the db_lookup is returning NULL (or isn't
|
||||
yet performed).
|
||||
|
||||
* encountered a crash during rtarea on a (default) facetized version
|
||||
of the hyp from the proc-db csgbrep tool.
|
||||
|
||||
* raytracing rhc crashes (inside malloc, so previous memory badness)
|
||||
with normal tolerance set to non-default value (e.g. tol norm 0.1);
|
||||
also fails (non-crash) if absolute tolerance is changed (e.g., tol
|
||||
abs 0.1)
|
||||
|
||||
* revolve raytracing seems to be busted.. at least with the example
|
||||
csgbrep revolve shape
|
||||
|
||||
* torus with a near zero inner diameter results in zero-length edges
|
||||
during tessellation.
|
||||
|
||||
* 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.
|
||||
|
||||
* infinite loop in rt_find_backing_dist() raytracing a BoT (without
|
||||
pieces) for bot_smooth (i.e., rt_bot_smooth()). encountered inf
|
||||
loop on a jetski fastgen model that was solid but unoriented, with
|
||||
about 8k faces. NOTE: possibly already have a fix for this bug
|
||||
pending review and testing. --CSM
|
||||
|
||||
* run make to create all primitives at the origin. there are raytrace
|
||||
differences, crashes, and overall bad behavior between default
|
||||
ungrouped "e *" view and adding all of those primitives to a single
|
||||
region. Script for creating all primitives via make command:
|
||||
|
||||
for i in `mged -c test.g make asdf asdf 2>&1 | awk '{print $12}' | sed 's/[<>|]/ /g'` ; do mged -c test.g make $i $i ; done
|
||||
mged -c test.g "g primitives *"
|
||||
mged -c test.g r primitives.r u primitives
|
||||
rt -a 35 -e 25 test.g primitives
|
||||
rt -a 35 -e 25 test.g primitives.r
|
||||
|
||||
* MGED on Mac OS X 10.6 mouse bindings fail to zoom in incrementally.
|
||||
Pan, zoom out, and interactive zoom work. Shift-grip bindings need
|
||||
to be verified.
|
||||
|
||||
* rt -i -s4096 -H16 -F/dev/null boolean-ops.g all
|
||||
|
||||
* compilation reportedly fails when building Tcl if the path to the
|
||||
source directory includes a space.
|
||||
|
||||
* mged/tcl "gets" command doesn't work if you run the "source" command
|
||||
to read in a script that uses gets on stdin. it just hangs until
|
||||
multiple sigint's are received.
|
||||
|
||||
* invoking mged from a system menu seems to be broken. reported by a
|
||||
reliable ArchLinux user. probably exhibits cross-platform on KDE,
|
||||
GNOME, or XFCE (but original environment is unknown). the bug is
|
||||
undoubtedly related to mged's interactive and stdin/stdout input
|
||||
detection where mged thinks it's being scripted (beginning on or
|
||||
about mged.c:1150)
|
||||
|
||||
* Report of copy/paste not working with Tk on Windows Vista - does
|
||||
work on Windows XP.
|
||||
|
||||
* Update/create .mgedrc results in bogus qray lines if a db is not
|
||||
open when the file is created.
|
||||
|
||||
* MGED doesn't initialize multipane view to the documented multipane
|
||||
defaults if you just open a db with multipane already enabled.
|
||||
|
||||
* Creating an 'extrude' via MGED gui crashes MGED.
|
||||
|
||||
* edcomb command seems to be busted similar to red, doesn't seem to do
|
||||
anything.
|
||||
|
||||
* Detailed BoT model ray trace image had incorrect background pixel
|
||||
values in framebuffer, off slightly by one.
|
||||
|
||||
* rt is consuming 100% CPU in fb_close() on a lingering ogl
|
||||
framebuffer waiting to close. needs to sleep or select for a while.
|
||||
|
||||
* /dev/oglb 'copy mode' fails to refresh the framebuffer
|
||||
|
||||
* X display manager (and probably others) will lock up mged if you Z/B
|
||||
while the wireframe is being actively drawn (in X_drawVList()).
|
||||
reproducible by cloning havoc a dozen or more times, getting
|
||||
sub-1sec fps, Z/B after rotating wireframe but before update
|
||||
finishes drawing.
|
||||
|
||||
* report of rt aborting randomly on 64-bit with camo shader.
|
||||
|
||||
* mged rrt command is not respecting the view size, just does
|
||||
something similar to autoview but even gets az/el wrong too.
|
||||
|
||||
* Windows mged build is not generating tclIndex files with all
|
||||
entries. notably the pattern_gui.tcl file is not getting included
|
||||
as well as a variety of others. see missing entries in
|
||||
tclscripts/mged/tclIndex for examples:
|
||||
https://sourceforge.net/tracker/?func=detail&atid=640802&aid=2923199&group_id=105292
|
||||
|
||||
* hyp tessellation routine creates bot that does not raytrace
|
||||
|
||||
* hyp used in a boolean with other objects (even unions) does not
|
||||
raytrace
|
||||
|
||||
* if you attach a display manager in tk-mged, kill the window, then
|
||||
quit, mged crashes on exit.
|
||||
|
||||
* mged segfaults when drawing lots of solids at once (e.g. draw *.s)
|
||||
|
||||
* mged command mode doesn't display the output of multiple
|
||||
semicolon-separated commands. Only the output of the very last mged
|
||||
command is displayed. Example:
|
||||
|
||||
mged -c moss.g "tops ; title"
|
||||
mged -c moss.g "puts OK ; tops ; puts OK2 ; title ; puts DONE"
|
||||
|
||||
Note that this is consistent with doing the same thing on the MGED
|
||||
Command Window's command prompt - if the above is a bug it is
|
||||
apparently not restricted to command/classic mode.
|
||||
|
||||
Further investigation suggests that this is a consequence of
|
||||
Tcl treating multiple commands in a single " " block as one command,
|
||||
insofar as capturing the output is concerned. It probably relates
|
||||
to situations where Tcl_SetResult is called where (in this case)
|
||||
Tcl_AppendResult would have been better, but it is not clear whether
|
||||
changing this result setting approach would cause other breakage.
|
||||
|
||||
* mged rotation halts after a few events and after zooming in/out at
|
||||
least once (Mac OS X 10.5)
|
||||
More info: This problem appears to be specific to a particular
|
||||
X11 version or versions - it has been observed with
|
||||
xorg-server-1.4.2-apple33 on 10.5. It does not occur with the
|
||||
community XQuartz 2.5.0 (xorg-server 1.7.6), nor does it occur
|
||||
when Tk 8.5.8 is compiled to use the Aqua backend. At least one other
|
||||
(possibly earlier) version of X11 from Apple on a 10.5 Mac did not
|
||||
exhibit bad rotate behavior. The problem is not specifically the
|
||||
zooming action - rather, the zoom triggers
|
||||
a Tk focus call on the display manager window (rather than the
|
||||
Tk parent window) and the problem manifests when focus is on the
|
||||
display manager window. mged classic mode, where there is no
|
||||
parent window, exhibits the bad rotate behavior immediately.
|
||||
|
||||
* infinite light sources close to objects result in unexpected/bad
|
||||
light behavior. example is a 1m sph light about 5m from a box about
|
||||
1k x 1k x 1k in size. setting make each light be red, green, and
|
||||
blue respectively, set to infinite (and fraction 10) and sides to
|
||||
the cube will render sides with a fixed color (green, blue) and top
|
||||
magenta. On one test with all lights at fraction 1.0 and only one
|
||||
inf, was getting interleaved partial flat/no color all around cube.
|
||||
|
||||
* fastgen plate mode bots are reporting invalid shotline segments.
|
||||
depending on whether you shoot from the front or back can result in
|
||||
bogus lists visible with nirt in mged, entirely missing the bot, or
|
||||
mismatched entry/exit/overlap segments.
|
||||
|
||||
* tab completion in classic/command mode sometimes doesn't work
|
||||
(presumably if mged can't find tcl resources). was finally able to
|
||||
reproduce this with the result given as:
|
||||
|
||||
invalid command name "bind"
|
||||
|
||||
* mged 'facetize -n' command is giving many errors:
|
||||
ERROR: color index out of range (-128 > 255)
|
||||
and it shouldn't. seems to be happening on 3-manifold surfaces but
|
||||
only for particular faces. looks like the painting algorithm that is
|
||||
being used is flawed (and an incomplete implementation).
|
||||
|
||||
* running 'keep' on too many objects (hundreds is causing a usage
|
||||
statement (and not doing the keep)
|
||||
|
||||
* fbserv is receiving image data very slowly if the framebuffer is a
|
||||
remote X24 interface. could reproduce on mac with the following:
|
||||
|
||||
fbserv -s1024 1 /dev/X &
|
||||
rt -F1 -s1024 db/moss.g all.g
|
||||
rt -F1 -i -s1024 db/moss.g all.g # 8x worse
|
||||
|
||||
* ls -A and/or e -A reportedly crashes on use, unverified
|
||||
|
||||
* File->Export seems to not work on Windows
|
||||
|
||||
* xpush fails to properly create a hierarchy killing existing objects
|
||||
resulting in dangling references. This may have been fixed by
|
||||
r69256, but a model that exposes the issue has to be tested to be
|
||||
sure.
|
||||
|
||||
* mged on Mac OS X will crash on an X11 call if compiled against
|
||||
system Tcl/Tk (at least on 10.4 linking against 8.4), see TODO
|
||||
|
||||
* the ray tracer fails to report LOS and sometimes even hits on a BoT
|
||||
that is marked as unoriented or is inverted (even though it
|
||||
sometimes will report the segments, just without LOS). this seems
|
||||
to happen for bots that are neither lh or rh (they're mixed) and
|
||||
causes the raytrace to fail if they're set to anything other than
|
||||
'no' for orientation. this affects rt, nirt, et al.
|
||||
|
||||
* g-vrml ignores bots that are created with dxf-g
|
||||
|
||||
* Mac OS X installer doesn't include the symbolic links, only
|
||||
including the versioned installation directory.
|
||||
|
||||
* Mouse cursor turns into a huge yellow-translucent arrow when running
|
||||
MGED through remote X11.
|
||||
|
||||
Running this fixes the bug: .id_0t config -cursor "xterm black"
|
||||
|
||||
* mged (on debian) is reporting this when the user presses tab:
|
||||
Error in bgerror: invalid command name "::swidgets::togglearrow"
|
||||
the second time they press tab, they get:
|
||||
Error in bgerror: window name "_secErrorDialog" already exists in parent
|
||||
|
||||
The problem was noticed on 7.12.4 and happens regardless of there
|
||||
being a db opened or not. The problem does not occur in classic
|
||||
mode.
|
||||
|
||||
* mged command window is showing up as an empty 0x0 dimensioned window
|
||||
on freebsd using xfce and metacity (single display, 1680x1050 res).
|
||||
dm shows up just fine.
|
||||
|
||||
* g2asc of a v4 is apparently writing out the wrong s_cgtypes and
|
||||
otherwise parsing v4 .g files incorrectly
|
||||
|
||||
* bump shader seems to be busted. only renders as flat by itself and
|
||||
stacked with phong it seems to ignore the uv settings.
|
||||
|
||||
* the graphics window does not acquire keybinding focus in mged on
|
||||
ubuntu linux. key events go to the command window even with the
|
||||
graphics window has focus.
|
||||
|
||||
* mged tab-completion doesn't work if the object names have spaces
|
||||
|
||||
* Open dialog in MGED seems rather busted for scrolling and selection
|
||||
(seems to be Mac OS X specific)
|
||||
|
||||
* turning on Framebuffer->Rectangle Area in mged disables the
|
||||
embedded framebuffer display on Mac OS X when you sweep a raytrace
|
||||
rectangle. sweeping still works if you leave it at All.
|
||||
|
||||
* invalid shaders result in an "Unable to locate where BRL-CAD ... is
|
||||
installed" message that refers to being unable to find a
|
||||
/lib/libSHADER.so file. Quite a bogus message and probably not
|
||||
something that should abort the ray-trace.
|
||||
|
||||
* rtedge seems to get stuck in a loop at the end of rendering, never
|
||||
terminates (unless you rtabort/kill the process); works with -P1
|
||||
|
||||
* nirt/query_ray reports intersection messages in triplicate if the
|
||||
shot routines miss but still print out messages
|
||||
|
||||
* mged's plot tool (the gui one, not the 'plot' command) outputs a
|
||||
plot file that has an erase as the last command, causing empty plots
|
||||
|
||||
* interactive mouse edits in mged can go haywire on Mac OS X with
|
||||
snap-to-grid enabled
|
||||
|
||||
* overlap tool in mged encourages very inefficient CSG operations
|
||||
(e.g. a simple bolt with an entire hull armor subtracted)
|
||||
|
||||
* permute (in mged) requires apply or save before 'new' vertex values
|
||||
will function properly as keypoints.
|
||||
|
||||
* facedef then move face undoes the facedef in mged
|
||||
|
||||
* dsp primitive is going into what seems to be an unbounded memory
|
||||
allocation loop during prep, inside dsp_layers().
|
||||
|
||||
* libfb cannot open a file descriptor when piping/redirecting output.
|
||||
|
||||
OK: rt -F/./dev/stdout moss.g all.g
|
||||
BAD: rt -F/./dev/stdout moss.g all.g > test.pix
|
||||
|
||||
* ray-tracers assume a seekable output stream. libfb reports numerous
|
||||
fseek errors and outputs slightly corrupted pix data.
|
||||
|
||||
OK: rt -o test.pix moss.g all.g && pix-png test.pix > test.png && rm -f test.pix
|
||||
BAD: rt -o /dev/stdout moss.g all.g | pix-png > test.png
|
||||
|
||||
* running any of the various mged commands (e.g. clicking the raytrace
|
||||
button many times quickly, or running rtarea on a large model) that
|
||||
output a lot of data will hang mged (idle cpu utilization).
|
||||
|
||||
* solids.sh regression test fails on Mac OS X with one pixel
|
||||
off-by-many on the edge of the middle ARB8 when using an optimized
|
||||
-O3 compile (-fno-unsafe-math-optimizations makes no difference)
|
||||
|
||||
* triangulation of some pipe in toyjeep.g fails (rather reliably) on
|
||||
some given bend. fails in nmg_triangulate model().
|
||||
|
||||
* 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
|
||||
via bu_debug. so when bu_debug is set to 2 or 3, it ends up
|
||||
reporting errors during bu_free() for items that were allocated and
|
||||
were not yet being tracked.
|
||||
|
||||
* mged View menu says I and O are keybindings for zoom in/out -- they
|
||||
are apparently not.
|
||||
|
||||
* raytracers report the wrong amount of cumulative time (reports as
|
||||
0.0 seconds elapsed) on amd64 linux; most likely the same pthread
|
||||
accounting bug visited a couple years ago.
|
||||
|
||||
* Create menu.. create "part" boo hiss..
|
||||
|
||||
* fbed is looking for /usr/lib/vfont/nonie.r.12
|
||||
|
||||
* mged doesn't check if html_dir does not exist when searching for
|
||||
docs/browser.
|
||||
|
||||
* permute then translate doesn't refresh the graphics window
|
||||
permute 4378
|
||||
translate menus
|
||||
p 0 0 0
|
||||
p 0 0 0
|
||||
|
||||
* constrained axis translation bindings on OS X don't work
|
||||
object/matrix edit
|
||||
shift-alt mouse (left/mid/right for x/y/z respectively) should work
|
||||
|
||||
* the findfont directive in gv postscript is reporting font not found
|
||||
|
||||
* concave arbs give correct wireframe but do not raytrace correctly.
|
||||
|
||||
* 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
|
||||
framebuffers. zooming logic seems to be broken (was crashing in
|
||||
memcpy, but that was fixed) for at least -s96 and smaller:
|
||||
|
||||
./libtool --mode=execute gdb --args src/rt/rt -F/dev/X -P1 -s64 db/moss.g all.g
|
||||
|
||||
* g2asc exports attr lines but will not grok them on asc2g
|
||||
|
||||
* mged's matrix selection does not modify the correct matrix if there
|
||||
are multiply referenced non-unique paths (e.g. referencing the same
|
||||
object N times in a combination).
|
||||
|
||||
* facetize -t doesn't work (tnurb support)
|
||||
|
||||
* on os x, the -fast option results in an odd optimization/aliasing
|
||||
bug where rtip contents are lost in rt after returning from
|
||||
rt_gettrees().
|
||||
|
||||
* tra in console mode outputs a warning about mged_players
|
||||
|
||||
* mged primitive editor doesn't accept/apply values to disk for
|
||||
certain primitives (e.g. sph)
|
||||
|
||||
* enabling perspective mode horks shaded mode, also Z clipping
|
||||
shouldn't be required to get the shading.
|
||||
|
||||
* an underlay framebuffer does not underlay with shaded mode
|
||||
|
||||
* rtarea gives incorrect areas when using -H hypersample flag
|
||||
|
||||
* setting src/librt/db5_io.c's AVS_ADD off in db5_import_attributes
|
||||
causes bad things to happen and it really shouldn't.
|
||||
|
||||
* vrml exporter (and probably others) doesn't export primitives
|
||||
directly as one might expect like the ray-tracers, only regions.
|
||||
|
||||
* sketches extruded with non-square AB vectors results in inner sketch
|
||||
components not getting scaled properly.
|
||||
|
||||
* bot-bldxf fails in db_walk_tree(), interface may have changed
|
||||
|
||||
|
||||
---
|
||||
Bugs should be reported to the bug tracker on the project website at
|
||||
http://sourceforge.net/tracker/?atid=640802&group_id=105292
|
||||
|
||||
BUGS should be formatted to column 70 (M-q in emacs), no tabs.
|
||||
|
||||
// Local Variables:
|
||||
// mode: Text
|
||||
// fill-column: 70
|
||||
// End:
|
||||
@@ -1,87 +0,0 @@
|
||||
= BRL-CAD Interface Change Policy
|
||||
:toc: macro
|
||||
|
||||
toc::[]
|
||||
|
||||
== Scope
|
||||
|
||||
This policy defines how BRL-CAD public interfaces may change. Public
|
||||
interfaces include developer APIs, command-line interfaces, graphical
|
||||
interfaces, documented commands, installed headers, public macros,
|
||||
public types, and other behavior users reasonably rely on.
|
||||
|
||||
Renaming an application is not minimally impacting: an application
|
||||
name is the primary way users find and run the tool.
|
||||
|
||||
Every public interface change must be either minimally impacting or
|
||||
formally deprecated.
|
||||
|
||||
== Minimally Impacting
|
||||
|
||||
A minimally impacting change may be made at any time. A change is
|
||||
minimally impacting only when it can be represented by the documented
|
||||
rule language in
|
||||
link:doc/changes/minimally-impacting.rules[doc/changes/minimally-impacting.rules]
|
||||
and emitted by the generated update script.
|
||||
|
||||
If the rule language cannot express a change, either extend the rule
|
||||
language so the generated script can perform the update, or treat the
|
||||
change as formally deprecated.
|
||||
|
||||
Minimally impacting path includes:
|
||||
|
||||
* recently introduced interfaces that have not yet appeared unchanged
|
||||
in two releases;
|
||||
* appreciably broken interfaces that have been unusable for at least
|
||||
two releases and have no secondary utility;
|
||||
* elementary mechanical changes such as renames, parameter reordering,
|
||||
parameter removal, defaulted parameter insertion, equivalent
|
||||
interface substitutions, and header moves.
|
||||
|
||||
For function argument rewrites, BRL-CAD assumes callers are not
|
||||
relying on preprocessor-generated call syntax and are not passing
|
||||
nested function calls as arguments to the changed function. That
|
||||
assumption keeps generated substitutions deterministic and reviewable.
|
||||
|
||||
Rule syntax and generated update-script workflow are documented in
|
||||
link:doc/changes/README.adoc[doc/changes/README.adoc]. The generated
|
||||
build-tree rendering of minimally impacting changes is
|
||||
`doc/changes/minimally-impacting.adoc`.
|
||||
|
||||
== Formally Deprecated
|
||||
|
||||
Any public interface change that is not minimally impacting must
|
||||
follow the formal deprecation process.
|
||||
|
||||
During a major release, such as 7.x to 8.x, any public interface may
|
||||
change without advance notice. Major version changes imply interface
|
||||
incompatibility.
|
||||
|
||||
During a minor release, such as 7.44.x to 7.46.x, a public interface
|
||||
must be deprecated beforehand with advance notice in at least two
|
||||
minor releases and at least 90 days elapsed since the initial release
|
||||
announcement.
|
||||
|
||||
Public interfaces scheduled for change should be listed in
|
||||
link:doc/changes/deprecated.adoc[doc/changes/deprecated.adoc] and
|
||||
visibly marked in the source code. Appropriate markings include
|
||||
`DEPRECATED` declarations, preprocessor warnings, `@DEPRECATED`
|
||||
comments, runtime warnings when they do not disrupt valid usage, and
|
||||
documentation updates.
|
||||
|
||||
After a deprecation window has completed, removed or significantly
|
||||
changed interfaces are listed in
|
||||
link:doc/changes/obsoleted.adoc[doc/changes/obsoleted.adoc].
|
||||
|
||||
== Examples
|
||||
|
||||
Removing `rt_shootray()` after it has been published and documented in
|
||||
multiple releases is not minimally impacting unless a generated rule
|
||||
can update callers to an equivalent interface. Otherwise, it must be
|
||||
listed as deprecated, marked in the headers, announced in releases,
|
||||
and only later obsoleted.
|
||||
|
||||
Renaming `bu_log()` or adding a defaulted first argument can be
|
||||
minimally impacting if the change is listed in
|
||||
`minimally-impacting.rules` and the generated update script rewrites
|
||||
existing callers.
|
||||
-3430
File diff suppressed because it is too large
Load Diff
@@ -1,116 +0,0 @@
|
||||
BRL-CAD Copying and Distribution
|
||||
================================
|
||||
|
||||
BRL-CAD is Open Source software with copyright primarily held by the
|
||||
U.S. Government. The source code is controlled and maintained by a
|
||||
core team of Open Source developers working around the world. Those
|
||||
core developers operate under a meritocracy organizational structure
|
||||
adhering to developer guidelines outlined in the HACKING developer's
|
||||
guide and to the legal conventions and requirements outlined in this
|
||||
document.
|
||||
|
||||
As a unified work, BRL-CAD is made available under the terms of the
|
||||
GNU Lesser General Public License (LGPL) as published by the Free
|
||||
Software Foundation.
|
||||
|
||||
As distinctly organized and separate components, parts of BRL-CAD are
|
||||
made available under different licenses for different portions
|
||||
including the BSD license and files in the public domain. The Overview
|
||||
section describes how the various licenses apply to the different
|
||||
portions of BRL-CAD.
|
||||
|
||||
BRL-CAD is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this file. If you did not, please contact one of
|
||||
the BRL-CAD project administrators listed at the Github project
|
||||
site https://github.com/BRL-CAD/brlcad/ or listed in the AUTHORS file
|
||||
included as part of the distribution.
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
BRL-CAD consists primarily of libraries, applications, scripts,
|
||||
documentation, geometric models, images, data resources, and build
|
||||
infrastructure. The BRL-CAD libraries provide their headers in the
|
||||
include/ directory as well as all of the directories that begin with
|
||||
the prefix "lib" in the src/ directory (e.g. src/librt/). All of
|
||||
BRL-CAD's libraries, applications, and any content lacking a license
|
||||
specification are covered by the terms of the LGPL.
|
||||
|
||||
Most of BRL-CAD's build infrastructure including files required by
|
||||
the GNU Build System (such as the CMakeLists.txt files), a variety
|
||||
of scripts located in the misc/ and sh/ directories, and the testing
|
||||
infrastructure (scripts and resources) are provided either under
|
||||
the BSD license or are in the public domain. Similarly, most of
|
||||
the geometric models, images, and other data resources are also
|
||||
provided under the BSD license. Refer to each individual file for
|
||||
specific terms.
|
||||
|
||||
BRL-CAD's documentation consists of manual pages located throughout
|
||||
the package, most of the files in the doc/ directory, and the
|
||||
top-level administrative project text files (e.g. README & AUTHORS).
|
||||
Unless otherwise denoted, all of BRL-CAD's documentation is made
|
||||
available under the terms of the BSD Documentation License (BDL) or
|
||||
are in the public domain. Refer to each document for specific terms.
|
||||
|
||||
The full text of the LGPL, BDL, and BSD license should be included in
|
||||
the source distribution of BRL-CAD in the doc/legal/ directory. Refer
|
||||
to the full license text for more details, information, requirements,
|
||||
and implications of each license.
|
||||
|
||||
3rd-Party Components
|
||||
--------------------
|
||||
|
||||
The BRL-CAD package utilizes and redistributes several 3rd party
|
||||
source codes, libraries, and applications. Said 3rd party source
|
||||
code, libraries, and applications all retain their respective
|
||||
agreements, licenses, and copyrights and should be referred to
|
||||
individually for their specific terms. For the purposes of
|
||||
redistribution and legal compatibility for all of BRL-CAD's existing
|
||||
user base, NO 3RD PARTY LIBRARIES SHALL BE INCLUDED THAT ARE UNDER THE
|
||||
TERMS OF THE GNU GENERAL PUBLIC LICENSE or any other license with
|
||||
similar legal implications that would impose legal obligations on
|
||||
external codes that utilize BRL-CAD as a library.
|
||||
|
||||
When referring to BRL-CAD, its source code, documentation, and
|
||||
libraries, the reference is not meant to include or imply 3rd party
|
||||
source code, libraries, and/or applications unless specifically stated
|
||||
otherwise. No endorsement or claim of authorship is implied to any
|
||||
3rd party asset that is included with BRL-CAD.
|
||||
|
||||
Copyright
|
||||
---------
|
||||
|
||||
All contributions to BRL-CAD have been provided under agreement. By
|
||||
requiring all contributions be given back to the BRL-CAD developers,
|
||||
this agreement allows the BRL-CAD project to continue to grow
|
||||
unhindered. As such, a majority of the source code is copyright by
|
||||
the United States Government as represented by the United States Army
|
||||
Research Laboratory.
|
||||
|
||||
Authors and other BRL-CAD contributors must comply with the copyright
|
||||
terms for their respective contributions unless otherwise noted or
|
||||
arranged. This includes an implicit assignment of copyright for any
|
||||
and all contributions being made. The following notice should be
|
||||
prominent in the BRL-CAD sources:
|
||||
|
||||
Copyright (c) 1984-2026 United States Government as represented by
|
||||
the U.S. Army Research Laboratory.
|
||||
|
||||
Contact
|
||||
-------
|
||||
|
||||
Questions or comments regarding BRL-CAD legal issues pertaining to
|
||||
copying, linking, licensing, trademark, or otherwise should be
|
||||
directed to the BRL-CAD Development Team at the following address:
|
||||
|
||||
BRL-CAD Development Team
|
||||
devs@brlcad.org
|
||||
http://brlcad.org
|
||||
|
||||
---
|
||||
$Revision$
|
||||
@@ -0,0 +1,28 @@
|
||||
Re-distribution of this software is restricted, as described in your
|
||||
"Statement of Terms and Conditions for the Release of The BRL-CAD
|
||||
Package" agreement.
|
||||
|
||||
Portions of this software and the associated databases and images are
|
||||
Copyright (C) 1985-2004 by the United States Army in all countries
|
||||
except the USA. Unauthorized redistribution in any form is
|
||||
prohibited. Recipients of this distribution are authorized unlimited
|
||||
use within their corporation, organization, or agency.
|
||||
|
||||
The mark "BRL-CAD" is a Registered Trademark of the United States
|
||||
Army. All rights reserved.
|
||||
|
||||
There is no warranty or other guarantee of fitness for this software,
|
||||
it is provided solely "as is". Bug reports or fixes must be sent to
|
||||
ARL, which may or may not act on them.
|
||||
|
||||
This software was developed by and is proprietary to the United States
|
||||
Government, and any use of the software without the written permission
|
||||
of the US Army Research Laboratory is strictly prohibited. Any
|
||||
unauthorized use of the software will be construed as an infringement
|
||||
of the Government's rights and will subject the unauthorized user to
|
||||
action(s) for infringement damages. (BRL MFR 380-15, Feb-88)
|
||||
|
||||
The software in the "contributed" directory is Public Domain,
|
||||
Distribution Unlimited. In addition, certain other modules in the
|
||||
BRL-CAD package bear this designation. Files so marked are available
|
||||
for unlimited use.
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Top level Cakefile.
|
||||
*
|
||||
* This Cakefile serves the same purpose as the top level Makefile,
|
||||
* ie, to run the "gen.sh" script with the given argument.
|
||||
*
|
||||
* $Header$
|
||||
*/
|
||||
|
||||
%&:
|
||||
/bin/sh gen.sh %
|
||||
|
||||
all&::
|
||||
/bin/sh gen.sh
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* C A K E F I L E . L I B
|
||||
*
|
||||
* Cakefile for building a single library archive.
|
||||
* Symbol PRODUCTS should be name of a single library
|
||||
*
|
||||
* Author -
|
||||
* Michael John Muuss
|
||||
*
|
||||
* Source -
|
||||
* SECAD/VLD Computing Consortium, Bldg 394
|
||||
* The U. S. Army Ballistic Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5066
|
||||
*
|
||||
* Distribution Status -
|
||||
* Public Domain, Distribution Unlimitied.
|
||||
*
|
||||
* $Header$
|
||||
*/
|
||||
|
||||
#ifndef PRODUCTS
|
||||
# include "Symbol PRODUCTS required to make library"
|
||||
#endif
|
||||
#ifndef SRCDIR
|
||||
# include "Symbol SRCDIR required"
|
||||
#endif
|
||||
#ifndef OBJ
|
||||
# include "Symbol OBJ required"
|
||||
#endif
|
||||
#ifndef VERSION_VARIABLE
|
||||
# include "Symbol VERSION_VARIABLE required"
|
||||
#endif
|
||||
#ifndef LIBRARY_TITLE
|
||||
# include "Symbol LIBRARY_TITLE required"
|
||||
#endif
|
||||
|
||||
#ifndef EXTRA_OBJ
|
||||
# define EXTRA_OBJ /**/
|
||||
#endif
|
||||
|
||||
#ifndef EXTRA_SETUP
|
||||
# define EXTRA_SETUP /**/
|
||||
#endif
|
||||
|
||||
#ifndef EXTRA_OBJ_NO_DEPENDENCY
|
||||
# define EXTRA_OBJ_NO_DEPENDENCY /**/
|
||||
#endif
|
||||
|
||||
#ifndef LIB_FLAGS
|
||||
# define LIB_FLAGS /**/
|
||||
#endif
|
||||
|
||||
#if !defined(BUILD_LIBRARY)
|
||||
PRODUCTS:: EXTRA_OBJ OBJ
|
||||
newvers.sh VERSION_VARIABLE LIBRARY_TITLE
|
||||
CC CFLAGS -c vers.c
|
||||
rm -f PRODUCTS; EXTRA_SETUP
|
||||
AR r PRODUCTS OBJ EXTRA_OBJ EXTRA_OBJ_NO_DEPENDENCY vers.o
|
||||
RANLIB PRODUCTS
|
||||
|
||||
/* If RANLIB is specified, be sure it is run when installing libraries */
|
||||
# define AFTERINSTALL RANLIB
|
||||
#else
|
||||
/* Shared library support.
|
||||
* Can't list SHARED_PRODUCT in 'rm' command, or will get wrong version number.
|
||||
* (Cake won't re-run the LIBVERS shell script)
|
||||
* If non-null, LIBVERS will start with a leading dot.
|
||||
* Note that the RM command zaps anything starting with PRODUCTS.
|
||||
* Note that if you have shared libraries, you better have symlinks.
|
||||
*/
|
||||
# define SHARED_PRODUCT PRODUCTS''[[LIBVERS]]
|
||||
PRODUCTS&:: EXTRA_OBJ OBJ
|
||||
newvers.sh VERSION_VARIABLE LIBRARY_TITLE
|
||||
CC CFLAGS -c vers.c
|
||||
rm -f PRODUCTS*; EXTRA_SETUP
|
||||
BUILD_LIBRARY SHARED_PRODUCT OBJ EXTRA_OBJ EXTRA_OBJ_NO_DEPENDENCY vers.o
|
||||
sharedliblink.sh SHARED_PRODUCT
|
||||
|
||||
/* Use this opportunity to build the symlink on install */
|
||||
# define AFTERINSTALL sharedliblink.sh
|
||||
#endif
|
||||
|
||||
%.o&: SRCDIR,,%,o if exist ../SRCDIR/%.c
|
||||
|
||||
%9,,%,o&: ../%9/%.c HDR_DEP9 if exist ../%9/%.c
|
||||
CC CFLAGS LIB_FLAGS -c ../%9/%.c
|
||||
|
||||
/* Override the modes for the library */
|
||||
#undef BINDIR
|
||||
#undef BINPERM
|
||||
#define BINDIR LIBDIR
|
||||
#define BINPERM LIBPERM
|
||||
+269
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* C A K E F I L E . R U L E S
|
||||
*/
|
||||
|
||||
/*
|
||||
* Patterns to handle the installation and uninstallation
|
||||
* of products, manuals, and manual stubs.
|
||||
* This is complicated by the fact that not all directories
|
||||
* will contain all three types of items.
|
||||
*/
|
||||
#define MAN_EXISTS {{ls ../SRCDIR|grep -s .MANSECTION'$'}}
|
||||
#define STUB_EXISTS {{ls ../SRCDIR|grep -s .MANSECTION.stub'$'}}
|
||||
#define ARG_EXISTS {{ARGS="%"; test '%' != "$ARGS" -o -f %}}
|
||||
|
||||
/* Format sources for printing on stdout. Use macro to bypass ANSI cpp "bug" */
|
||||
#define PRINT_STUFF [[SUB X X.print ../SRCDIR/Cakefile ]] \
|
||||
[[SUB X X.print ../SRCDIR/''*.[h''MANSECTION] ]] \
|
||||
[[SUB X X.nroff ../SRCDIR/''*.MANSECTION ]] \
|
||||
[[SUB X ../SRCDIR/X''SRCSUFF.print FILES]]
|
||||
|
||||
print&: PRINT_SUFF
|
||||
|
||||
%.print&: do-%.print if ARG_EXISTS
|
||||
%.print&: if not ARG_EXISTS
|
||||
|
||||
do-%.print&:
|
||||
@pr %
|
||||
|
||||
/*
|
||||
*/
|
||||
nroff&: do-nroff if MAN_EXISTS
|
||||
nroff&: if not MAN_EXISTS
|
||||
|
||||
do-nroff&: [[SUB X X.nroff ../SRCDIR/''*.MANSECTION ]]
|
||||
|
||||
%.nroff&: ../SRCDIR/%
|
||||
@nroff -Tlp -man ../SRCDIR/%
|
||||
|
||||
/*
|
||||
* Typeset all the non-stub manual pages. Do them all at once,
|
||||
* to prevent lots of extra header sheets on the printer
|
||||
*
|
||||
* do-typeset-a creates the file "troff.out" with the macros in it
|
||||
* %.troff adds each manual page to "troff.out"
|
||||
*/
|
||||
typeset&: do-typeset if MAN_EXISTS
|
||||
typeset&: if not MAN_EXISTS
|
||||
|
||||
do-typeset&: do-typeset-a troff.out
|
||||
( TYPESET_MAN2 ) < troff.out
|
||||
@rm -f troff.out
|
||||
|
||||
do-typeset-a&:
|
||||
TYPESET_MAN0 TYPESET_MAN1 > troff.out
|
||||
|
||||
troff.out&: [[SUB X X.troff ../SRCDIR/''*.MANSECTION ]]
|
||||
|
||||
%.troff&: if ARG_EXISTS
|
||||
TYPESET_MAN0 % >> troff.out
|
||||
|
||||
#define SRC_LIST `SUB X ../SRCDIR/X''SRCSUFF FILES`
|
||||
|
||||
lint&:
|
||||
LINT LFLAGS -I''INCDIR SRC_LIST LLIBES > SRCDIR.lint
|
||||
|
||||
tags: [[echo SRC_LIST]]
|
||||
ctags SRC_LIST
|
||||
|
||||
TAGS: [[echo SRC_LIST]]
|
||||
etags SRC_LIST
|
||||
|
||||
flow&: [[echo SRC_LIST]]
|
||||
cflow -I''INCDIR SRC_LIST > SRCDIR.flow
|
||||
|
||||
xref&: [[echo SRC_LIST]]
|
||||
cxref -c -s -w132 -I''INCDIR SRC_LIST > SRCDIR.xref
|
||||
|
||||
compare&: [[SUB X X.compare PRODUCTS]]
|
||||
|
||||
%.compare&: %
|
||||
cmp BINDIR/% %
|
||||
|
||||
#if !defined(DONT_INSTALL)
|
||||
uninstall&: uninstall-prod uninstall-man uninstall-stub
|
||||
#else
|
||||
uninstall&:
|
||||
#endif
|
||||
|
||||
#ifdef PRODUCTS
|
||||
uninstall-prod&: [[SUB X X.uninstall-prod PRODUCTS]]
|
||||
#else
|
||||
uninstall-prod&:
|
||||
#endif
|
||||
|
||||
%.uninstall-prod&:
|
||||
rm -f BINDIR/% BINDIR/%.bak
|
||||
|
||||
uninstall-man&: do-uninstall-man if MAN_EXISTS
|
||||
uninstall-man&: if not MAN_EXISTS
|
||||
|
||||
do-uninstall-man&: [[SUB ../SRCDIR/X X.ui-man ../SRCDIR/''*.MANSECTION]]
|
||||
|
||||
%.ui-man&:
|
||||
rm -f MANDIR''MANSECTION/% MANDIR''MANSECTION/%.bak
|
||||
|
||||
uninstall-stub&: do-uninstall-stub if STUB_EXISTS
|
||||
uninstall-stub&: if not STUB_EXISTS
|
||||
|
||||
do-uninstall-stub&: [[SUB ../SRCDIR/X.stub X.uninstall-stub ../SRCDIR/''*.stub]]
|
||||
|
||||
%.uninstall-stub&:
|
||||
rm -f MANDIR''MANSECTION/% MANDIR''MANSECTION/%.bak
|
||||
|
||||
#if !defined(EXTRA_INSTALL_TARGETS)
|
||||
# define EXTRA_INSTALL_TARGETS /**/
|
||||
#endif
|
||||
|
||||
#if !defined(DONT_INSTALL)
|
||||
install&: install-prod install-man install-stub
|
||||
|
||||
install-nobak&: install-prod-nobak install-man install-stub
|
||||
#else
|
||||
install&:
|
||||
|
||||
install-nobak&:
|
||||
#endif
|
||||
|
||||
#if defined(SHARED_PRODUCT)
|
||||
install-prod&: [[SUB X X.iprod SHARED_PRODUCT]] EXTRA_INSTALL_TARGETS
|
||||
|
||||
install-prod-nobak&: [[SUB X X.iprod-nobak SHARED_PRODUCT]] EXTRA_INSTALL_TARGETS
|
||||
|
||||
#else
|
||||
# if defined(PRODUCTS)
|
||||
install-prod&: [[SUB X X.iprod PRODUCTS]] EXTRA_INSTALL_TARGETS
|
||||
|
||||
install-prod-nobak&: [[SUB X X.iprod-nobak PRODUCTS]] EXTRA_INSTALL_TARGETS
|
||||
# else
|
||||
install-prod&:
|
||||
|
||||
install-prod-nobak&:
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Here is where we depend on having /bin/sh as the shell */
|
||||
%.iprod&: %
|
||||
@echo ......checking % 1>&2 ; \
|
||||
if cmp -s BINDIR/% %; \
|
||||
then exit 0; fi; \
|
||||
mv -f BINDIR/% BINDIR/%.bak 2>/dev/null; \
|
||||
if INS % BINDIR/%; \
|
||||
then if test x''AFTERINSTALL != x'AFTERINSTALL'; \
|
||||
then AFTERINSTALL BINDIR/%; fi; \
|
||||
echo "++++++INSTALLED" BINDIR/% 1>&2; \
|
||||
chmod BINPERM BINDIR/%; \
|
||||
fi
|
||||
|
||||
%.iprod-nobak&: %
|
||||
@echo ......checking % 1>&2 ; \
|
||||
if cmp -s BINDIR/% %; \
|
||||
then exit 0; fi; \
|
||||
rm -f BINDIR/% 2>/dev/null; \
|
||||
if INS % BINDIR/%; \
|
||||
then if test x''AFTERINSTALL != x'AFTERINSTALL'; \
|
||||
then AFTERINSTALL BINDIR/%; fi; \
|
||||
echo "++++++INSTALLED" BINDIR/% 1>&2; \
|
||||
chmod BINPERM BINDIR/%; \
|
||||
fi
|
||||
|
||||
install-man&: do-install-man if MAN_EXISTS
|
||||
install-man&: if not MAN_EXISTS
|
||||
|
||||
do-install-man&: [[SUB ../SRCDIR/X X.i-man ../SRCDIR/''*.MANSECTION ]]
|
||||
|
||||
%.i-man&: ../SRCDIR/%
|
||||
@if cmp -s MANDIR''MANSECTION/% ../SRCDIR/%; \
|
||||
then exit 0; fi; \
|
||||
mv -f MANDIR''MANSECTION/% MANDIR''MANSECTION/%.bak 2>/dev/null; \
|
||||
if INS ../SRCDIR/% MANDIR''MANSECTION/%; \
|
||||
then echo "++++++INSTALLED" MANDIR''MANSECTION/% 1>&2; \
|
||||
chmod MANPERM MANDIR''MANSECTION/%; \
|
||||
fi
|
||||
|
||||
install-stub&: do-install-stub if STUB_EXISTS
|
||||
install-stub&: if not STUB_EXISTS
|
||||
|
||||
do-install-stub&: [[SUB ../SRCDIR/X.stub X.install-stub ../SRCDIR/''*.stub]]
|
||||
|
||||
%.install-stub&: ../SRCDIR/%.stub
|
||||
@if cmp -s MANDIR''MANSECTION/% ../SRCDIR/%.stub; \
|
||||
then exit 0; fi; \
|
||||
mv -f MANDIR''MANSECTION/% MANDIR''MANSECTION/%.bak 2>/dev/null; \
|
||||
if INS ../SRCDIR/%.stub MANDIR''MANSECTION/%; \
|
||||
then echo "++++++INSTALLED" MANDIR''MANSECTION/% 1>&2; \
|
||||
chmod MANPERM MANDIR''MANSECTION/%; \
|
||||
fi
|
||||
|
||||
/*
|
||||
* Force installation of copies of all sources,
|
||||
* whether configured in or not, into the distribution tree.
|
||||
*/
|
||||
#ifndef STATIC_PRODUCTS
|
||||
# define STATIC_PRODUCTS /**/
|
||||
#endif
|
||||
#ifdef NFS
|
||||
#define INSTALL_PATTERNS STATIC_PRODUCTS \
|
||||
../SRCDIR/Cakefile ../SRCDIR/\\\\*.[hcsfyl] \
|
||||
../SRCDIR/\\\\*.sh \
|
||||
../SRCDIR/\\\\*.MANSECTION ../SRCDIR/\\\\*.MANSECTION.stub \
|
||||
../SRCDIR/\\\\*.doc
|
||||
#else
|
||||
#define INSTALL_PATTERNS STATIC_PRODUCTS \
|
||||
./Cakefile \\\\*.[hcsfyl] \\\\*.sh \
|
||||
\\\\*.MANSECTION \\\\*.MANSECTION.stub \\\\*.doc
|
||||
#endif
|
||||
|
||||
/* inst-dist is never run automatically, it has to be run by hand. */
|
||||
/* inst-dist is run from gen.sh as part of the final packaging of a distribution */
|
||||
inst-dist&: dist-clobber [[SUB X X.do-inst-dist INSTALL_PATTERNS]]
|
||||
|
||||
dist-clobber&:
|
||||
-rm -fr DISTRIBUTION/SRCDIR
|
||||
mkdir DISTRIBUTION/SRCDIR; chmod 775 DISTRIBUTION/SRCDIR
|
||||
|
||||
%.do-inst-dist&: %.inst-dist if ARG_EXISTS
|
||||
%.do-inst-dist&: if not ARG_EXISTS
|
||||
|
||||
%.inst-dist&:
|
||||
-INS % DISTRIBUTION/SRCDIR/.
|
||||
|
||||
#ifndef EXTRA_CLEAN
|
||||
# define EXTRA_CLEAN /**/
|
||||
#endif
|
||||
|
||||
/*
|
||||
* clean remove all .o files and by-products
|
||||
* noprod remove the final executables
|
||||
* clobber perform clean & noprod
|
||||
*/
|
||||
clobber&: clean noprod
|
||||
|
||||
clean&:
|
||||
-rm -f core *.core *~ *.o EXTRA_CLEAN SRCDIR.out SRCDIR.err SRCDIR.xref SRCDIR.flow SRCDIR.lint
|
||||
|
||||
#if defined(LIBRARY_TITLE)
|
||||
/*
|
||||
* The asterisk is to glob all the variations of (shared) library names.
|
||||
* This depends on the fact that for libraries, PRODUCTS is a single name,
|
||||
* not a list of file names, and that there will be no source file called
|
||||
* PRODUCTS.c, e.g., no librt.c file for making librt.so.10.
|
||||
*
|
||||
* The "SRCDIR.*" version is to catch the case where we're changing
|
||||
* from shared libraries to non-shared libraries.
|
||||
*/
|
||||
noprod&:
|
||||
-rm -f PRODUCTS* SRCDIR.*
|
||||
#else
|
||||
noprod&:
|
||||
-rm -f PRODUCTS
|
||||
#endif
|
||||
|
||||
#ifdef never
|
||||
/*
|
||||
* Insist that, by default, Cake work on making the products.
|
||||
* THIS SHOULD BE THE LAST THING CAKE SEES!
|
||||
* The double-colon marks this as the main target.
|
||||
*/
|
||||
"!MAINCAKE!"&:: PRODUCTS
|
||||
#endif
|
||||
@@ -1,476 +1,47 @@
|
||||
The Installation Guide to BRL-CAD
|
||||
=================================
|
||||
To compile and install the BRLCAD source, perform the following steps:
|
||||
|
||||
This document covers the installing BRL-CAD from either a source or binary
|
||||
distribution. Please see REPORTING PROBLEMS to troubleshoot.
|
||||
% mkdir /usr/brlcad
|
||||
|
||||
Some platforms have additional platform-specific documentation provided in the
|
||||
doc/ directory with additional information. This presently includes the
|
||||
following:
|
||||
If you choose a directory other than /usr/brlcad, you will need to set the
|
||||
environment variable BRLCAD_ROOT to be the name of this directory. Because a
|
||||
number of paths are compiled into the package, it is not possible to compile
|
||||
the package for one location, then move it to another. Be sure that
|
||||
/usr/brlcad/bin or $BRLCAD_ROOT/bin is in your shell path. For example:
|
||||
|
||||
doc/README.BSD -- FreeBSD, NetBSD, OpenBSD, etc.
|
||||
doc/README.Linux -- Various Linux distributions
|
||||
doc/README.MacOSX -- Apple Mac OS X
|
||||
doc/README.Solaris -- Oracle Solaris, OpenIndiana (Illumos), etc.
|
||||
doc/README.VAX -- Virtual Address eXtension architecture from DEC.
|
||||
One of the original BRL-CAD platforms. These
|
||||
days, re-created using the simh simulator.
|
||||
doc/README.Windows -- Microsoft Windows
|
||||
sh:
|
||||
BRLCAD_ROOT=/foobar/brlcad
|
||||
PATH=$PATH:/foobar/brlcad/bin
|
||||
export PATH
|
||||
csh:
|
||||
setenv BRLCAD_ROOT /foobar/brlcad
|
||||
set path=($path /foobar/brlcad/bin)
|
||||
|
||||
Compile:
|
||||
% cd /foobar/brlcad
|
||||
% sh setup.sh
|
||||
|
||||
TABLE OF CONTENTS
|
||||
-----------------
|
||||
Introduction
|
||||
Table of Contents
|
||||
Quick Source Install
|
||||
Installing from Binary
|
||||
Installing from Source
|
||||
Testing Functionality
|
||||
Post-Installation
|
||||
Reporting Problems
|
||||
Configuration Options
|
||||
The next step can take a considerable amount of time on some systems:
|
||||
|
||||
sh:
|
||||
make > make.log 2>&1
|
||||
csh:
|
||||
make >& make.log
|
||||
|
||||
Install:
|
||||
Review the log of compilation, then run:
|
||||
|
||||
QUICK SOURCE INSTALL
|
||||
--------------------
|
||||
make install
|
||||
|
||||
See https://brlcad.org/wiki/Compiling for a platform-specific walk-through
|
||||
including instructions for building on Windows.
|
||||
This process should proceed without problems on the following systems:
|
||||
|
||||
Required tools:
|
||||
- Git must be 2.17 or later
|
||||
- CMake must be 3.26 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
|
||||
- If using LLVM/Clang 5 or later
|
||||
- If using Intel, version 19.0.1 or later
|
||||
RedHat Linux 7.2
|
||||
FreeBSD 4.5
|
||||
SunOS 5.8 (Solaris)
|
||||
Irix 6.5
|
||||
Mac OS X (With X11 installed -- INSTALL.pmac for details)
|
||||
|
||||
Steps to compile, test, and install an optimized BRL-CAD on non-Windows
|
||||
platforms:
|
||||
For binary and source download instructions see:
|
||||
|
||||
git clone https://github.com/BRL-CAD/brlcad.git
|
||||
mkdir brlcad/build
|
||||
cd brlcad/build
|
||||
cmake .. -DENABLE_ALL=ON -DCMAKE_BUILD_TYPE=Release
|
||||
make -j4
|
||||
make check
|
||||
sudo make install
|
||||
http://ftp.arl.army.mil/brlcad
|
||||
|
||||
Once installed, run bin/mged or bin/archer to launch BRL-CAD's GUI apps. See
|
||||
POST-INSTALLATION for instruction adding bin/ folder to your system PATH to
|
||||
more easily run geometry converters.
|
||||
|
||||
|
||||
INSTALLING FROM BINARY
|
||||
----------------------
|
||||
|
||||
There are a variety of different kinds of binary distributions of
|
||||
BRL-CAD. Some of the binary distributions are sufficiently generic and
|
||||
are simply a binary compressed tarball distribution. Others are
|
||||
specific to a particular platform such as Debian, Mac OS X, FreeBSD,
|
||||
and Windows etc.
|
||||
|
||||
|
||||
Generic Binary Distributions:
|
||||
|
||||
For binary distributions that are simply compressed tarballs of the
|
||||
installation root, they should contain the entire hierarchy of the
|
||||
distribution. To put that hierarchy in its "installed" location, you just
|
||||
create the directory and move the expanded tarball contents:
|
||||
|
||||
gunzip BRL-CAD_X.Y.Z_Linux_ia64.tar.gz
|
||||
tar -xvf BRL-CAD_X.Y.Z_Linux_ia64.tar
|
||||
sudo mkdir /usr/brlcad/rel-X.Y.Z
|
||||
sudo mv BRL-CAD_X.Y.Z_Linux_ia64/* /usr/brlcad/rel-7.X.Y/
|
||||
|
||||
Of course, there are other compression options possible including zip and
|
||||
bzip2. By default, BRL-CAD expects to be installed into /usr/brlcad/rel-X.Y.Z.
|
||||
On some platforms the binary may be relocatable, but this is not guaranteed.
|
||||
It's recommended that you start from a source distribution if you would like to
|
||||
install into an alternate installation location. That said, if you do desire
|
||||
to install and/or run BRL-CAD from a different location, give it a try...on
|
||||
some platforms it will work.
|
||||
|
||||
Something to be aware of, even if a binary distribution IS relocatable: it will
|
||||
use its local copies of things like libraries only so long as the "final"
|
||||
installed target directory that the build was compiled for does not contain a
|
||||
BRL-CAD installation. Due to the way path logic is set, an installed copy of a
|
||||
library in the correct location will always be loaded first, regardless of the
|
||||
presence of a "local" copy.
|
||||
|
||||
|
||||
Mac OS X Disk Mounting Image:
|
||||
|
||||
Mount the .dmg and run the Installer .pkg contained therein. This will install
|
||||
into /usr/brlcad/rel-X.Y.Z and will only require confirming that your
|
||||
environment is set up properly (i.e. add /usr/brlcad/rel-X.Y.Z/bin to your
|
||||
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
|
||||
re-distribute BRL-CAD, checksums should be retained with the files so others
|
||||
can validate origination.
|
||||
|
||||
|
||||
INSTALLING FROM SOURCE
|
||||
----------------------
|
||||
|
||||
There are a couple of ways to obtain the BRL-CAD sources, usually via one of
|
||||
the following starting points:
|
||||
|
||||
1) from a Git checkout, or
|
||||
2) from a source distribution tarball
|
||||
|
||||
Using the latest Git sources is recommended where possible since it
|
||||
will have the latest changes.
|
||||
|
||||
There are many different ways to build BRL-CAD and depending on what
|
||||
you need/want will determine which configuration options you should
|
||||
use. See the CONFIGURATION OPTIONS section below for details on how
|
||||
to go about selecting which options are appropriate for you.
|
||||
|
||||
BRL-CAD's dependencies are managed in a separate repository, located at
|
||||
https://github.com/BRL-CAD/bext By default BRL-CAD's configure process will
|
||||
download and manage the necessary dependencies, avoiding the need for user
|
||||
awareness of the bext repository, but there are a number of scenarios where it
|
||||
is advantageous for developers to adjust how this process works.
|
||||
|
||||
The full dependency stack of BRL-CAD, with all optional and experimental
|
||||
features enabled, is a VERY large and long compile. Therefore, the bext build
|
||||
outputs can be built as their own separate, external project to allow for reuse
|
||||
of the compiled outputs. Building bext separately means BRL-CAD won't get a
|
||||
chance to customize what is and is not built, but the trade-off is that outputs
|
||||
can be built once and reused over and over. Doing so can significantly shorten
|
||||
time spent configuring BRL-CAD builds - reusing bext compiled outputs is
|
||||
recommended for serious developers.
|
||||
|
||||
Various useful configurations for working with bext:
|
||||
|
||||
* Get a git clone that has everything which might be needed (large,
|
||||
but useful for offline building)
|
||||
|
||||
git clone --recurse-submodules https://github.com/BRL-CAD/brlcad
|
||||
|
||||
* Have prebuilt bext outputs to reuse - BRL-CAD will simply copy and prepare
|
||||
the pre-existing files
|
||||
|
||||
cmake .. -DBRLCAD_EXT_DIR=/home/user/bext_output
|
||||
|
||||
* Already have an existing bext clone but want BRL-CAD to build bext outputs
|
||||
|
||||
cmake .. -DBRLCAD_EXT_SOURCE_DIR=/home/user/bext
|
||||
|
||||
* Download, build and bundle only what is needed for librt
|
||||
|
||||
cmake .. -DBRLCAD_COMPONENTS=librt
|
||||
|
||||
* Build and bundle only what is needed, but don't require internet for bext clone
|
||||
cmake .. -DBRLCAD_EXT_SOURCE_DIR=/home/user/bext -DBRLCAD_COMPONENTS=librt
|
||||
|
||||
|
||||
By default, the build system will prepare a Debug build and install into the
|
||||
/usr/brlcad/dev-X.Y.Z directory. The CMAKE_INSTALL_PREFIX option may be used
|
||||
to change that directory, or a Release build type may be specified to install
|
||||
to /usr/brlcad/rel-X.Y.Z - more on this below. The tradition of non-system
|
||||
installation paths goes back a couple of decades and is a convenient means to
|
||||
isolate the BRL-CAD solid modeling system from your system, resolves conflicts,
|
||||
facilitates uninstalls, and simplifies upgrades. The default configuration is
|
||||
performed by running `cmake'. It is not required to do the build in a
|
||||
directory different from your source directory, but it is much cleaner and
|
||||
*highly* recommended - this guide will illustrate the build process with the
|
||||
assumption that the BRL-CAD source code is in the directory brlcad-X.Y.Z and
|
||||
the directory intended to hold the build output is brlcad-build, located in the
|
||||
same parent directory as brlcad-X.Y.Z:
|
||||
|
||||
.
|
||||
./brlcad-X.Y.Z
|
||||
./brlcad-build
|
||||
|
||||
To start the build process, cd into brlcad-build and run CMake,
|
||||
pointing it to the source directory:
|
||||
|
||||
cd brlcad-build
|
||||
cmake ../brlcad-X.Y.Z
|
||||
|
||||
As mentioned earlier, CMake uses two "build types", controlled by
|
||||
the CMAKE_BUILD_TYPE variable, that are useful for specific purposes:
|
||||
|
||||
* Debug (-DCMAKE_BUILD_TYPE=Debug) - Debug is the configuration that most
|
||||
developers will want to use when working on BRL-CAD. It will add
|
||||
debug flags to the compile, and sets the default install directory to
|
||||
be /usr/brlcad/dev-X.Y.Z - in order to run the resulting installed
|
||||
binaries, the developer should ensure that the dev-X.Y.Z path is
|
||||
first in his or her PATH environment variable.
|
||||
|
||||
* Release (-DCMAKE_BUILD_TYPE=Release) - A release build is intended for
|
||||
final consumption by end users and as such has optimizations enabled.
|
||||
It also sets the install path to /usr/brlcad/rel-X.Y.Z - best practice
|
||||
for release installation is to set up symbolic links in /usr/brlcad to
|
||||
point to the most current BRL-CAD release, while allowing older versions
|
||||
to remain installed on the system in case they are needed.
|
||||
|
||||
In both of these cases any individual variable may be overridden - for
|
||||
example, setting -DCMAKE_INSTALL_PREFIX=/usr/brlcad in a Debug build will
|
||||
override the ../brlcad-install default. Build types are a convenient way
|
||||
to bundle sets of settings, but they do not prevent overrides if a more
|
||||
custom setup is needed.
|
||||
|
||||
If the autodetection mechanisms fail to produce a working configuration,
|
||||
the next simplest approach is typically to enable ALL the third party
|
||||
components - this is typically a well tested configuration, but will
|
||||
increase both the build time and final install size of BRL-CAD on
|
||||
the system. To set this variable on the command line, use -D to
|
||||
define ENABLE_ALL for CMake:
|
||||
|
||||
-DENABLE_ALL=ON
|
||||
|
||||
To obtain an optimized build (for example, for BRL-CAD Benchmark
|
||||
performance evaluation), enable BRLCAD_FLAGS_OPTIMIZATION:
|
||||
|
||||
-DBRLCAD_FLAGS_OPTIMIZATION=ON
|
||||
|
||||
See the CONFIGURATION OPTIONS below for more details on all of the
|
||||
possible settings.
|
||||
|
||||
Once configured, you should be able to successfully build BRL-CAD via
|
||||
make:
|
||||
|
||||
make
|
||||
|
||||
(On multicore systems, adding the -j flag (e.g. -j6) is recommended)
|
||||
|
||||
Installing the Compilation:
|
||||
|
||||
After the build successfully completes and assuming the benchmark also
|
||||
produces correct results, installation may begin. Like any package,
|
||||
you must have sufficient filesystem permissions to install. To
|
||||
install into a system location, you can generally either become a
|
||||
super user via the su command and run
|
||||
|
||||
make install
|
||||
|
||||
or on operating systems set up to use sudo:
|
||||
|
||||
sudo make install
|
||||
|
||||
|
||||
TESTING FUNCTIONALITY
|
||||
---------------------
|
||||
|
||||
The primary build target to validate a compilation of BRL-CAD is:
|
||||
|
||||
make check
|
||||
|
||||
That runs a trio of test sets including "benchmark", "regress", and
|
||||
"unit". The first set is a performance test that also validates
|
||||
whether ray tracing behavior is correct:
|
||||
|
||||
make benchmark
|
||||
|
||||
The second test set is our regression tests that run a host of
|
||||
rigorous integration tests and validate essential behavior:
|
||||
|
||||
make regress
|
||||
|
||||
The third set runs unit tests that validate low-level behavior in
|
||||
BRL-CAD's core libraries:
|
||||
|
||||
make unit
|
||||
|
||||
Last but not least, one may simply run all available tests, though
|
||||
note that some tests will intentionally fail:
|
||||
|
||||
make test
|
||||
|
||||
|
||||
POST-INSTALLATION
|
||||
-----------------
|
||||
|
||||
Permissions:
|
||||
|
||||
Something to be aware of with CMake installations is that umask settings
|
||||
are ignored by current versions of CMake. It is a common situation in
|
||||
Unix environments to want "group" members to have read/write access -
|
||||
to achieve this, after installation the following find command can be
|
||||
run (of course, substituting the actual BRL-CAD version for X.Y.Z):
|
||||
|
||||
find /usr/brlcad/rel-X.Y.Z -type d -exec chmod ug+rwx {} \; -exec chmod o+rx {} \; -o -type f -exec chmod ug+rw {} \; -exec chmod o+r {} \;
|
||||
|
||||
The above 'find' line will set up permissions across a /usr/brlcad
|
||||
rooted installation such that 'user' and 'group' will have read-write
|
||||
access and 'other' will have read access consistently across all
|
||||
files.
|
||||
|
||||
|
||||
System PATH:
|
||||
|
||||
Normally, BRL-CAD's install directories are not in system PATH lists and
|
||||
consequently BRL-CAD's executables will not be invocable without specifying
|
||||
their full path. This is normally handled in Unix environments by adding
|
||||
the desired BRL-CAD installation's binary directory to the user's local path:
|
||||
|
||||
On Windows, the PATH system variable can be set using System Utility
|
||||
in control panel. Add the bin/ folder in the install directory to PATH.
|
||||
|
||||
On Linux/BSD/other systems:
|
||||
In the bash shell: export PATH=/usr/brlcad/rel-X.Y.Z:$PATH
|
||||
In the csh shell: setenv PATH /usr/brlcad/rel-X.Y.Z:$PATH
|
||||
|
||||
|
||||
REPORTING PROBLEMS
|
||||
------------------
|
||||
|
||||
Please report any bugs, support requests, or feature requests to:
|
||||
https://github.com/BRL-CAD/brlcad/issues
|
||||
|
||||
|
||||
|
||||
CONFIGURATION OPTIONS
|
||||
---------------------
|
||||
|
||||
--- ENABLE_ALL ---
|
||||
|
||||
If set to ON, and the BRL-CAD configure process is managing the bext
|
||||
dependencies, instructs bext to default to building local copies of the
|
||||
dependencies it will enable per the BRL-CAD feature settings, rather than
|
||||
searching for system versions.
|
||||
|
||||
|
||||
--- BRLCAD_ENABLE_OPENGL ---
|
||||
|
||||
Enable support for OpenGL based Display Managers in BRL-CAD.
|
||||
Default depends on whether OpenGL is successfully detected -
|
||||
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
|
||||
src/source_dirs.cmake for a list of the components that may be specified.
|
||||
|
||||
|
||||
--- BRLCAD_ENABLE_RUNTIME_DEBUG ---
|
||||
|
||||
Enables support for application and library debugging facilities.
|
||||
Disabling the run-time debugging facilities can provide a significant
|
||||
(10%-30%) performance boost at the expense of extensive error
|
||||
checking (that in turn help prevent corruption of your data).
|
||||
Default is "ON", and should only be disabled for read-only render
|
||||
work where performance is critical.
|
||||
|
||||
Aliases: ENABLE_RUNTIME_DEBUG, ENABLE_RUN_TIME_DEBUG, ENABLE_RUNTIME_DEBUGGING
|
||||
ENABLE_RUN_TIME_DEBUGGING
|
||||
|
||||
|
||||
--- BRLCAD_EXT_DIR ---
|
||||
|
||||
If specified, BRL-CAD will look in this directory for bext compiled outputs to
|
||||
bundle and use during the build.
|
||||
|
||||
|
||||
--- BRLCAD_EXT_SOURCE_DIR ---
|
||||
|
||||
If specified, BRL-CAD will look in this directory for bext source files. Use
|
||||
this when you have a pre-existing bext clone and don't want BRL-CAD's configure
|
||||
process to pull down another copy, but are still looking to have the BRL-CAD
|
||||
configure process manage producing bext build outputs.
|
||||
|
||||
|
||||
--- BRLCAD_EXT_PARALLEL ---
|
||||
|
||||
This number, when specified, describes how many compilation threads to use
|
||||
when compiling bext sources. Default is 8.
|
||||
|
||||
|
||||
--- BRLCAD_DEBUGGING ---
|
||||
|
||||
Add compiler flags to aid in program debugging. Defaults to ON.
|
||||
|
||||
Aliases: ENABLE_DEBUG, ENABLE_FLAGS_DEBUG, ENABLE_DEBUG_FLAGS
|
||||
BRLCAD_FLAGS_DEBUG
|
||||
|
||||
|
||||
--- BRLCAD_PGO ---
|
||||
|
||||
Enable profile-guided optimization build flags. Defaults to OFF.
|
||||
|
||||
Profile-guided optimization builds are possible via two-pass
|
||||
compilation. Compile with this flag set, run the benchmark suite,
|
||||
clean the build, and then compile again with this flag set. Supported
|
||||
compilers will utilize data from the first pass to guide optimization,
|
||||
typically resulting in a significant performance increase:
|
||||
|
||||
|
||||
--- BRLCAD_WARNINGS ---
|
||||
|
||||
Use extra warning flags when compiling C/C++ code. Defaults to ON.
|
||||
|
||||
Aliases: ENABLE_WARNINGS, ENABLE_COMPILER_WARNINGS
|
||||
BRLCAD_ENABLE_COMPILER_WARNINGS
|
||||
|
||||
|
||||
--- BRLCAD_ENABLE_STRICT ---
|
||||
|
||||
Causes all compilation warnings for C code to be treated as errors. This is now
|
||||
the default for BRL-CAD source code, and developers should address issues
|
||||
discovered by these flags whenever possible rather than disabling strict
|
||||
mode.
|
||||
|
||||
Aliases: ENABLE_STRICT, ENABLE_STRICT_COMPILE, ENABLE_STRICT_COMPILE_FLAGS
|
||||
|
||||
|
||||
--- ENABLE_ALL_CXX_COMPILE ---
|
||||
|
||||
Build all C and C++ files with a C++ compiler. Defaults to OFF.
|
||||
|
||||
EXPERIMENTAL!
|
||||
|
||||
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.
|
||||
|
||||
Aliases: ENABLE_DOCS, ENABLE_EXTRA_DOCS
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
Max OS X Installation Notes:
|
||||
|
||||
Being that this is the newest architecture to be added, there are some issues
|
||||
to keep in mind with the installation when building from source. First, XFree86
|
||||
will need to be installed if you want a gui. Mac OS X does not ship with an
|
||||
X11 server installed by default. The XDarwin project, however, will include
|
||||
the X11 libraries and headers necessary to properly build Tk (the only
|
||||
component that presently "requires" X) and may be found at:
|
||||
|
||||
http://www.xdarwin.org
|
||||
|
||||
To build and install, you'll need to modify the Cakefile.defs file in the
|
||||
source root. Modify the compilation options (near the top of the file)
|
||||
as follows:
|
||||
|
||||
#define BUILD_OPTIMIZED 1
|
||||
#define BUILD_SHARED 0
|
||||
#define BUILD_XWINDOWS 1
|
||||
#define BUILD_OPENGL 0
|
||||
#define BUILD_PRODUCTION 1
|
||||
|
||||
There are details in the Cakefile.defs file for what each of these options
|
||||
means, but the important one is that it is presently not possible to build
|
||||
with shared libaries (patches welcome). Other than that the instructions
|
||||
in INSTALL will all work with the exception of the "make install" step.
|
||||
Run this instead:
|
||||
|
||||
cake install
|
||||
|
||||
If the build and install fails for whatever reason, then the system default Tcl
|
||||
library is most likely getting in the way. You can temporarily move it out of
|
||||
the way by doing:
|
||||
|
||||
sudo mv /usr/lib/libtcl.dylib /usr/lib/libtcl.dylib.backup
|
||||
sudo mv /usr/lib/libtcl8.3.dylib /usr/lib/libtcl8.3.dylib.backup
|
||||
sudo mv /usr/lib/libtclstub8.3.a /usr/lib/libtclstub8.3.a.backup
|
||||
sudo mv /System/Library/Tcl /System/Library/Tcl.backup
|
||||
|
||||
Then you should be able to do:
|
||||
|
||||
sh setup.sh
|
||||
cake clobber
|
||||
cake
|
||||
cake install
|
||||
|
||||
You can tell if a build succeeded properly by running "mged" from a terminal.
|
||||
Also, you should be able to go into the "bench" directory and run the benchmark
|
||||
(see doc/benchmark.doc) test script:
|
||||
|
||||
bench/try.sh
|
||||
|
||||
A window should pop up with a raytrace being displayed. If not, something is
|
||||
not right. If you build without X support (setting in Cakefile.defs), then
|
||||
you may verify your build by running "mged -c" or "bench/run.sh".
|
||||
|
||||
E-mail the cad list [cad@arl.army.mil] if any issues or questions arise.
|
||||
|
||||
Happy installation!
|
||||
-3677
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,99 @@
|
||||
#################################################################
|
||||
# #
|
||||
# Makefile #
|
||||
# #
|
||||
# The top-level Makefile for the BRL CAD Software Distribution #
|
||||
# #
|
||||
# This exists mostly as a convienience, so folks can #
|
||||
# type "make install" and such like, and get the expected #
|
||||
# results, even in the face of the rather complex mechanism. #
|
||||
# Thus, we make Make into a simple front-end for gen.sh #
|
||||
# #
|
||||
# Author - #
|
||||
# Michael John Muuss #
|
||||
# #
|
||||
# Source - #
|
||||
# SECAD/VLD Computing Consortium, Bldg 394 #
|
||||
# The U. S. Army Ballistic Research Laboratory #
|
||||
# Aberdeen Proving Ground, Maryland 21005-5066 #
|
||||
# #
|
||||
# #
|
||||
#################################################################
|
||||
|
||||
# SHELL = /bin/sh
|
||||
|
||||
# Main rule (default):
|
||||
all:
|
||||
-@sh gen.sh $@
|
||||
help:
|
||||
-@sh gen.sh $@
|
||||
benchmark:
|
||||
-@sh gen.sh $@
|
||||
fast:
|
||||
-@sh gen.sh $@
|
||||
clean:
|
||||
-@sh gen.sh $@
|
||||
noprod:
|
||||
-@sh gen.sh $@
|
||||
clobber:
|
||||
-@sh gen.sh $@
|
||||
lint:
|
||||
-@sh gen.sh $@
|
||||
ls:
|
||||
-@sh gen.sh $@
|
||||
ls-bin:
|
||||
-@sh gen.sh $@
|
||||
depend:
|
||||
-@sh gen.sh $@
|
||||
install:
|
||||
-@sh gen.sh $@
|
||||
inst-nobak:
|
||||
-@sh gen.sh $@
|
||||
uninstall:
|
||||
-@sh gen.sh $@
|
||||
perms:
|
||||
-@sh gen.sh $@
|
||||
inst-man:
|
||||
-@sh gen.sh $@
|
||||
inst-dist:
|
||||
-@sh gen.sh $@
|
||||
print:
|
||||
-@sh gen.sh $@
|
||||
typeset:
|
||||
-@sh gen.sh $@
|
||||
nroff:
|
||||
-@sh gen.sh $@
|
||||
mkdir:
|
||||
-@sh gen.sh $@
|
||||
relink:
|
||||
-@sh gen.sh $@
|
||||
rmdir:
|
||||
-@sh gen.sh $@
|
||||
wc:
|
||||
-@sh gen.sh $@
|
||||
tclIndex:
|
||||
-@sh gen.sh $@
|
||||
tags:
|
||||
-@sh gen.sh $@
|
||||
TAGS:
|
||||
-@sh gen.sh $@
|
||||
etags:
|
||||
-@sh gen.sh $@
|
||||
command:
|
||||
-@sh gen.sh $@
|
||||
rcs-lock:
|
||||
-@sh gen.sh $@
|
||||
checkin:
|
||||
-@sh gen.sh $@
|
||||
dist:
|
||||
-@sh gen.sh $@
|
||||
arch:
|
||||
-@sh gen.sh $@
|
||||
pkg:
|
||||
-@sh gen.sh $@
|
||||
rpm:
|
||||
-@sh gen.sh $@
|
||||
sunpkg:
|
||||
-@sh gen.sh $@
|
||||
tcl:
|
||||
-@sh gen.sh $@
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
#################################################################
|
||||
# #
|
||||
# Makefile.rules #
|
||||
# #
|
||||
# Author - #
|
||||
# Michael John Muuss #
|
||||
# #
|
||||
# Source - #
|
||||
# SECAD/VLD Computing Consortium, Bldg 394 #
|
||||
# The U. S. Army Ballistic Research Laboratory #
|
||||
# Aberdeen Proving Ground, Maryland 21005 #
|
||||
# #
|
||||
# $Header$ #
|
||||
# #
|
||||
#################################################################
|
||||
|
||||
# Define default list of targets to be made
|
||||
all: ${PRODUCTS}
|
||||
|
||||
# Generic SCCS rule:
|
||||
#.DEFAULT:
|
||||
# $(GET) $(GFLAGS) -p s.$@ > $@
|
||||
# touch $@
|
||||
|
||||
# This is how to make the product, but may not always apply (eg, libs).
|
||||
# Also, this construct only works with the SysV make.
|
||||
#${PRODUCTS}: $$@.o ${OBJS}
|
||||
# $(CC) -o $@ ${LDFLAGS} $@.o ${OBJS} ${LIBES}
|
||||
# size $@
|
||||
|
||||
# Format sources for printing on stdout.
|
||||
# The invoker is responsible for diverting to their printer of choice.
|
||||
print: ${MAKEFILE} ${HEADERS} ${CFILES} ${TFILES}
|
||||
@pr ${MAKEFILE} ${HEADERS} ${CFILES} ${TFILES} *.${MANSECTION}
|
||||
@nroff -Tlp -man *.${MANSECTION}
|
||||
|
||||
# Don't bother doing the stub pages
|
||||
typeset:
|
||||
${TYPESET_MAN1} *.${MANSECTION} ${TYPESET_MAN2}
|
||||
|
||||
lint: ${HEADERS} ${CFILES}
|
||||
${LINT} ${LFLAGS} -I${INCDIR} ${CFILES} ${LLIBES} > ${SRCDIR}.lint
|
||||
|
||||
|
||||
tags: ${HEADERS} ${CFILES}
|
||||
ctags ${HEADERS} ${CFILES}
|
||||
|
||||
flow: ${HEADERS} ${CFILES}
|
||||
cflow -I${INCDIR} ${CFILES} > ${SRCDIR}.flow
|
||||
|
||||
xref: ${HEADERS} ${CFILES}
|
||||
cxref -c -s -w132 -I${INCDIR} ${CFILES} > ${SRCDIR}.xref
|
||||
|
||||
compare: all
|
||||
for prod in ${PRODUCTS} ; \
|
||||
do cmp ${BINDIR}/$$prod $$prod; \
|
||||
done
|
||||
|
||||
uninstall: all
|
||||
-@if test -n "${PRODUCTS}" ; \
|
||||
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) uninst-prod ; \
|
||||
fi
|
||||
-@files=`echo *.${MANSECTION}` ; \
|
||||
if test "$$files" != '*'.${MANSECTION} ; \
|
||||
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) uninst-man ; \
|
||||
fi
|
||||
-@files=`echo *.${MANSECTION}.stub` ; \
|
||||
if test "$$files" != '*'.${MANSECTION}.stub ; \
|
||||
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) uninst-stub ; \
|
||||
fi
|
||||
|
||||
uninst-prod:
|
||||
-@for prod in ${PRODUCTS} ; \
|
||||
do rm -f ${BINDIR}/$$prod ${BINDIR}/$$prod.bak 2>/dev/null; \
|
||||
done
|
||||
|
||||
uninst-man:
|
||||
-@for man in *.${MANSECTION} ; \
|
||||
do rm -f ${MANDIR}${MANSECTION}/$$man \
|
||||
${MANDIR}${MANSECTION}/$$man.bak 2>/dev/null ; \
|
||||
done
|
||||
|
||||
uninst-stub:
|
||||
-@for stub in *.${MANSECTION}.stub ; \
|
||||
do man=`basename $$stub .stub`; \
|
||||
rm -f ${MANDIR}${MANSECTION}/$$man \
|
||||
${MANDIR}${MANSECTION}/$$man.bak 2>/dev/null ; \
|
||||
done
|
||||
|
||||
# Handle all phases of final installation
|
||||
install: all
|
||||
-@if test -n "${PRODUCTS}" ; \
|
||||
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) inst-prod ; \
|
||||
fi
|
||||
-@files=`echo *.${MANSECTION}` ; \
|
||||
if test "$$files" != '*'.${MANSECTION} ; \
|
||||
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) inst-man ; \
|
||||
fi
|
||||
-@files=`echo *.${MANSECTION}.stub` ; \
|
||||
if test "$$files" != '*'.${MANSECTION}.stub ; \
|
||||
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) inst-stub ; \
|
||||
fi
|
||||
-@sh -c "if test `${GETHOST}` = ${MASTERHOST} ; then $(MAKE) inst-dist; else exit 0 ; fi"
|
||||
|
||||
# Install all products
|
||||
inst-prod: ${PRODUCTS}
|
||||
-@for prod in ${PRODUCTS} ; \
|
||||
do if cmp -s ${BINDIR}/$$prod $$prod; \
|
||||
then echo $$prod unchanged; \
|
||||
else mv -f ${BINDIR}/$$prod ${BINDIR}/$$prod.bak 2>/dev/null; \
|
||||
${INS} $$prod ${BINDIR} && \
|
||||
${AFTERINSTALL} ${BINDIR}/$$prod && \
|
||||
echo "++++++INSTALLED" ${BINDIR}/$$prod && \
|
||||
${AFTERINSTALL} ${BINDIR}/$$prod.bak && \
|
||||
chmod ${BINPERM} ${BINDIR}/$$prod; \
|
||||
fi \
|
||||
done
|
||||
|
||||
# Install the actual manual pages
|
||||
inst-man:
|
||||
-@for man in *.${MANSECTION} ; \
|
||||
do if cmp -s ${MANDIR}${MANSECTION}/$$man $$man; \
|
||||
then echo $$man unchanged; \
|
||||
else mv -f ${MANDIR}${MANSECTION}/$$man \
|
||||
${MANDIR}${MANSECTION}/$$man.bak 2>/dev/null ; \
|
||||
${INS} $$man ${MANDIR}${MANSECTION} && \
|
||||
echo "++++++INSTALLED" ${MANDIR}${MANSECTION}/$$man && \
|
||||
chmod ${MANPERM} ${MANDIR}${MANSECTION}/$$man; \
|
||||
fi \
|
||||
done
|
||||
|
||||
# Install the "stub" manual pages, which just source some other page
|
||||
inst-stub:
|
||||
-@for stub in *.${MANSECTION}.stub ; \
|
||||
do man=`basename $$stub .stub`; \
|
||||
if cmp -s ${MANDIR}${MANSECTION}/$$man $$stub; \
|
||||
then echo $$man unchanged; \
|
||||
else mv -f ${MANDIR}${MANSECTION}/$$man \
|
||||
${MANDIR}${MANSECTION}/$$man.bak 2>/dev/null ; \
|
||||
${INS} $$stub ${MANDIR}${MANSECTION}/$$man && \
|
||||
echo "++++++INSTALLED" ${MANDIR}${MANSECTION}/$$man && \
|
||||
chmod ${MANPERM} ${MANDIR}${MANSECTION}/$$man; \
|
||||
fi \
|
||||
done
|
||||
|
||||
|
||||
# It might be better to say ${HEADERS} ${CFILES} ${SFILES},
|
||||
# but that would miss routines that were not configured in a particular system.
|
||||
inst-dist:
|
||||
-rm -fr ${DISTRIBUTION}/${SRCDIR}/*
|
||||
-${INS} ./Makefile.loc Makefile *.[hcfs] ${SHFILES} \
|
||||
*.${MANSECTION} *.${MANSECTION}.stub \
|
||||
*.doc \
|
||||
${DISTRIBUTION}/${SRCDIR}/.
|
||||
|
||||
# running "make clobber" or "make clean noprod" will remove all binary files.
|
||||
# "clean" is intended to remove .o files and by-products.
|
||||
# "noprod" is intended to remove the final executables.
|
||||
# Either can be used without the other, depending on the effect desired.
|
||||
clobber: clean noprod
|
||||
|
||||
clean:
|
||||
-rm -f core *~ *.o \
|
||||
${SRCDIR}.out ${SRCDIR}.err ${SRCDIR}.xref \
|
||||
${SRCDIR}.flow ${SRCDIR}.lint
|
||||
|
||||
noprod:
|
||||
-rm -f ${PRODUCTS}
|
||||
|
||||
|
||||
#
|
||||
# Automaticly build #include dependencies.
|
||||
#
|
||||
# This code can't be simply replaced by the 4.3 BSD "cc -M".
|
||||
#
|
||||
# The convention for writing #include directives is:
|
||||
# #include "./file" gives file in current directory
|
||||
# #include "/file" gives file at absolute path
|
||||
# #include "file" gives file in ${INCDIR}
|
||||
# #include <file> leaves to CPP
|
||||
#
|
||||
# Note that there MUST be a SPACE after the "#include" in order to
|
||||
# be seen; this allows conditional includes (if needed) to be indicated
|
||||
# by a #include TAB, so as to not cause trouble.
|
||||
depend:
|
||||
-@if test -n "${CFILES}" ; \
|
||||
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) do-depend ; \
|
||||
fi
|
||||
|
||||
do-depend:
|
||||
cd ../${SRCDIR}; \
|
||||
mv -f Makefile.loc Makefile.bak; \
|
||||
cp Makefile.bak Makefile.loc; \
|
||||
chmod 664 Makefile.loc; \
|
||||
for k in ${CFILES}; do \
|
||||
i=`basename $$k .c`; \
|
||||
echo $$i.o: ../${SRCDIR}/$$k >>makedep; \
|
||||
grep '^#include ' /dev/null ../${SRCDIR}/$$k | sed \
|
||||
-e 's,^../'${SRCDIR}'/,,' \
|
||||
-e 's,c:[^"]*"\./\([^"]*\)".*,o: \1,' \
|
||||
-e 's,c:[^"]*"/\([^"]*\)".*,o: /\1,' \
|
||||
-e 's,c:[^"]*"\([^"]*\)".*,o: '${INCDIR}'/\1,' \
|
||||
-e '/debug.h/d' \
|
||||
-e '/c:[^<]*<\(.*\)>/d' \
|
||||
>>makedep; \
|
||||
echo ' $$(CC) $$(CFLAGS) -c ../'${SRCDIR}/$$k >>makedep; \
|
||||
done; \
|
||||
echo '# DO NOT DELETE THIS LINE -- make depend uses it' >>Makefile.loc; \
|
||||
echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile.loc; \
|
||||
echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep; \
|
||||
echo '$$r makedep' >>eddep; \
|
||||
echo 'w' >>eddep; \
|
||||
ed - Makefile.loc < eddep; \
|
||||
rm eddep makedep; \
|
||||
echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile.loc; \
|
||||
echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile.loc; \
|
||||
echo '# see make depend above' >> Makefile.loc
|
||||
@@ -1,183 +1,146 @@
|
||||
BRL-CAD
|
||||
Release 7.44.2
|
||||
http://brlcad.org/
|
||||
|
||||
BRL-CAD is a powerful cross-platform open source combinatorial
|
||||
solid modeling system that includes an interactive 3D solid geometry
|
||||
editor, a network-distributed symmetric multiprocessing (SMP)
|
||||
high-performance ray-tracer with support for rendering and geometric
|
||||
analysis, image and signal-processing tools, a system performance
|
||||
analysis benchmark suite, a flexible geometry scripting interface,
|
||||
and a high-performance geometric representation and analysis library.
|
||||
|
||||
|
||||
TABLE OF CONTENTS
|
||||
-----------------
|
||||
Introduction
|
||||
Table of Contents
|
||||
Getting Started
|
||||
Compile and Install
|
||||
Benchmark
|
||||
Communication
|
||||
Bug Reports/Feature Requests
|
||||
Distribution Details
|
||||
Background Information
|
||||
|
||||
|
||||
GETTING STARTED
|
||||
---------------
|
||||
|
||||
This README file exists only to provide you a brief roadmap to the
|
||||
contents of the BRL-CAD distribution.
|
||||
|
||||
Some platforms have additional platform-specific documentation that
|
||||
should be consulted after reading this file:
|
||||
|
||||
doc/README.Windows -- Microsoft Windows
|
||||
doc/README.MacOSX -- Apple Mac OS X
|
||||
doc/README.Linux -- Various Linux distributions
|
||||
doc/README.* -- Other platforms, e.g., BSD, VAX
|
||||
|
||||
Information on how to install and run the software, to get involved
|
||||
with development, or to run the performance benchmark test suite are
|
||||
covered in detail in separate standalone documents. For more details
|
||||
on what BRL-CAD provides, consult the main website.
|
||||
|
||||
Information relevant to the source code is contained in the HACKING
|
||||
(developer guide) and COPYING (legal overview) files.
|
||||
|
||||
Note that only sample geometry models are included in public
|
||||
distributions of BRL-CAD. Detailed models are only available through
|
||||
official U.S. Gov't channels, e.g., via Advanced Joint Effectiveness
|
||||
Model (AJEM) support.
|
||||
|
||||
|
||||
COMPILE AND INSTALL
|
||||
-------------------
|
||||
|
||||
In order to compile and install BRL-CAD from a source distribution,
|
||||
the latest CMake ( http://www.cmake.org ), a recent compiler, and at
|
||||
least 3GB of disk space are recommended. More details are available
|
||||
at https://brlcad.org/wiki/Compiling
|
||||
|
||||
Typically, the following steps should result in a successful install:
|
||||
|
||||
tar -xvzf brlcad-VERSION.tar.gz
|
||||
mkdir brlcad-VERSION/build
|
||||
cd brlcad-VERSION/build
|
||||
cmake .. -DBRLCAD_ENABLE_STRICT=OFF -DCMAKE_BUILD_TYPE=Release
|
||||
make -j4
|
||||
make install
|
||||
|
||||
See the included INSTALL text file for explanation of the various
|
||||
cmake configuration options available for building BRL-CAD.
|
||||
|
||||
|
||||
BENCHMARK
|
||||
---------
|
||||
|
||||
After the build successfully completes, you will be able to verify
|
||||
basic functionality by running the BRL-CAD Benchmark. Running the
|
||||
benchmark suite is integrated into the build system such that any time
|
||||
after running CMake (in the cmake gui, configure and generate must both
|
||||
be performed) you may run:
|
||||
|
||||
make benchmark
|
||||
|
||||
If the build is successful, you will see "CORRECT" numbers and a
|
||||
performance summary at the end. The "vgr" line effectively shows you
|
||||
approximately how much faster your machine is to a VAX 11/780. After
|
||||
installing BRL-CAD, you may run the 'benchmark' tool as well to run
|
||||
the BRL-CAD Benchmark.
|
||||
|
||||
See the paper in doc/benchmark.tr for information on analyzing and
|
||||
comparing the results of the benchmark tests in more detail.
|
||||
|
||||
|
||||
COMMUNICATION
|
||||
-------------
|
||||
|
||||
There are various BRL-CAD mailing lists available including three
|
||||
developer-oriented lists, a user list, and a read-only news
|
||||
announcement list:
|
||||
|
||||
http://sourceforge.net/mail/?group_id=105292
|
||||
|
||||
For interactive discussion, please join our Zulip chat:
|
||||
|
||||
https://brlcad.zulipchat.com
|
||||
|
||||
|
||||
BUG REPORTS AND FEATURE REQUESTS
|
||||
--------------------------------
|
||||
|
||||
Please submit all bugs, support requests, and feature requests to:
|
||||
|
||||
https://github.com/BRL-CAD/brlcad/issues
|
||||
|
||||
|
||||
DISTRIBUTION DETAILS
|
||||
--------------------
|
||||
|
||||
BRL-CAD releases are available at:
|
||||
|
||||
https://github.com/BRL-CAD/brlcad/releases
|
||||
|
||||
Assets stored for each release will always include source archives,
|
||||
and usually binary compilations for commonly used operating systems.
|
||||
|
||||
For developers, BRL-CAD is available via Git version control cloning:
|
||||
|
||||
https://github.com/BRL-CAD/brlcad
|
||||
|
||||
|
||||
BACKGROUND INFORMATION
|
||||
----------------------
|
||||
|
||||
BRL-CAD is the primary tri-service solid modeling CAD system used by
|
||||
the U.S. military to model weapons systems for vulnerability and
|
||||
lethality analyses. The solid modeling system is frequently used in a
|
||||
wide range of military and industrial application including in the
|
||||
design and analysis of vehicles, mechanical parts, and architecture.
|
||||
The package has also been used in radiation dose planning, medical
|
||||
visualization, computer graphics education, CSG concepts and modeling
|
||||
education, and system performance benchmark testing among other
|
||||
purposes.
|
||||
|
||||
Actively developed since 1979, BRL-CAD is a collection of more than
|
||||
400 tools, utilities, and applications comprising more than a million
|
||||
lines of source code. BRL-CAD supports a great variety of geometric
|
||||
representations including an extensive set of traditional CSG
|
||||
primitive implicit solids such as boxes, ellipsoids, cones, and tori,
|
||||
as well as explicit solids made from closed collections of Uniform
|
||||
B-Spline Surfaces, Non-Uniform Rational B-Spline (NURBS) surfaces,
|
||||
n-Manifold Geometry (NMG), and purely faceted mesh geometry. All
|
||||
geometric objects may be combined using boolean set-theoretic CSG
|
||||
operations including union, intersection, and difference.
|
||||
|
||||
BRL-CAD has been under active development for more than 20 years with
|
||||
a portability heritage that includes systems such as a DEC VAX-11/780
|
||||
running 4.3 BSD; DECStations running ULTRIX; Silicon Graphics 3030, 4D
|
||||
"IRIS", O2, Onyx, and Origin systems running various versions of IRIX;
|
||||
Sun Microsystems Sun-3 and Sun-4 Sparcs running SunOS; the Cray 1,
|
||||
Cray X-MP, Cray Y-MP, and Cray 2 running UNICOS; DEC Alpha AXP running
|
||||
OSF/1; Apple Macintosh II running A/UX; iPSC/860 Hypercube running
|
||||
NX/2; the Alliant FX/8, FX/80, and FX/2800; Gould/Encore SEL PowerNode
|
||||
6000/9000 and NP1; NeXT workstations; IBM RS/6000; HPPA 9000/700
|
||||
running HPUX; Ardent/Stardent; Encore Multi-Max; and much much more.
|
||||
BRL-CAD's extensive portability of course also includes a plethora of
|
||||
common desktop and server versions of BSD, IRIX, Solaris, Mac OS X,
|
||||
Linux, and Windows.
|
||||
|
||||
The BRL-CAD package is intentionally designed to be extensively
|
||||
cross-platform and is actively developed on and maintained for many
|
||||
common operating system environments including various BSD
|
||||
distributions, Linux, Solaris, Mac OS X, and Windows. The entire
|
||||
package is distributed in binary and source code form as free open
|
||||
source software (FOSS), provided under Open Source Initiative (OSI)
|
||||
approved license terms. BRL-CAD was released as open source in
|
||||
December 2004. See the COPYING file for more details.
|
||||
|
||||
.\" $Header$
|
||||
.\" groff -ms README | print-postscript
|
||||
.TL
|
||||
README
|
||||
.sp
|
||||
The BRL-CAD Package
|
||||
.br
|
||||
Release 6.0
|
||||
.br
|
||||
(October-2002)
|
||||
.RT
|
||||
.IP "VERSION"
|
||||
.sp
|
||||
This document is printed from the README file in the BRL-CAD distribution.
|
||||
The version in the printed manuals are usually somewhat older
|
||||
than the version on the actual distribution tape.
|
||||
When attempting to
|
||||
install the software, please refer to the documentation
|
||||
versions actually contained on the distribution tape.
|
||||
.sp
|
||||
.IP CONTENTS
|
||||
.sp
|
||||
This README file exists only to provide you a brief roadmap to
|
||||
the contents of the BRL-CAD distribution.
|
||||
The information on how to install and operate the software,
|
||||
and perform the benchmark tests have become sufficiently large
|
||||
that they are now each a standalone document.
|
||||
.sp
|
||||
Please note that
|
||||
this distribution package does \fInot\fR include
|
||||
the various military-specific model
|
||||
analysis tools such as MUVES, GIFT, SAR, SLAVE, VAST, etc., nor does it
|
||||
include any military databases.
|
||||
If you desire to have access to this material,
|
||||
please contact Sean Morrison at (410)-278-6678.
|
||||
.sp
|
||||
.IP "INSTALLATION"
|
||||
.sp
|
||||
To install the BRL-CAD Package see the instructions in doc/install.doc.
|
||||
This file includes directions on the best way to get started with the
|
||||
distribution, as well as details on how to configure and install the
|
||||
software. This file also includes directions on how to compile and run
|
||||
the benchmark tests.
|
||||
.sp
|
||||
.IP "BENCHMARK"
|
||||
.sp
|
||||
See the paper in doc/benchmark.doc for information on
|
||||
analyzing the results of the benchmark tests.
|
||||
Comparisons between various different computers are listed.
|
||||
.sp
|
||||
.IP "BACKGROUND MATERIAL"
|
||||
.sp
|
||||
For overview information on the whole package, consult
|
||||
the overview paper in the file papers/overview, and
|
||||
the brlcad(1) manual page in the file util/brlcad.1.
|
||||
For a discussion of the significance of this software,
|
||||
read the paper "Understanding the Preparation and Analysis of Solid
|
||||
Models", included in the file papers/solid-models.
|
||||
.sp
|
||||
.IP "DISTRIBUTION DETAILS"
|
||||
.sp
|
||||
This software is governed by a limited distribution agreement.
|
||||
To obtain a copy of the BRL-CAD Package distribution materials, there
|
||||
are two options:
|
||||
.sp
|
||||
1. Free distribution with no support privileges: Those users with
|
||||
online access to the InterNet may obtain the BRL-CAD Package via
|
||||
FTP file transfer, at no cost, after completing and returning a signed
|
||||
copy of the printed distribution agreement. A blank agreement form is
|
||||
available only via anonymous FTP from host ftp.arl.army.mil (address
|
||||
192.12.65.24) from file "brl-cad/agreement". No installation
|
||||
assistance or telephone support will be available.
|
||||
.sp
|
||||
2. Full service distribution: The Survivability/Vulnerability
|
||||
Information Analysis Center (SURVIAC) administers the supported BRL-CAD
|
||||
distributions and information exchange programs for ARL. Full service
|
||||
distributions a copy of the full distribution materials on your choice
|
||||
of magnetic tape media, or you may elect to obtain your copy via FTP.
|
||||
One printed set of BRL-CAD documentation will be mailed to you.
|
||||
Software upgrades will be provided at no additional charge,
|
||||
and you will have access to full technical assistance by phone, FAX,
|
||||
letter, or E-mail. Agencies of the Federal Government may acquire the
|
||||
full service distribution with a simple MIPR or OGA funds transfer.
|
||||
.sp
|
||||
.nf
|
||||
For further details, contact:
|
||||
.sp .5
|
||||
BRL-CAD Distribution
|
||||
SURVIAC Aberdeen Satellite Office
|
||||
4695 Millennium Drive
|
||||
Belcamp, MD 210017-1505 USA
|
||||
.fi
|
||||
.sp .5
|
||||
or call USA telephone (410)-273-7794, send
|
||||
E-mail to <cad-dist@arl.army.mil>, FAX your letter to USA (410)-272-6763,
|
||||
or write to the above address.
|
||||
.fi
|
||||
.sp
|
||||
.ne 1i
|
||||
.IP "COMMUNICATION"
|
||||
.sp
|
||||
You are invited to participate in the InterNet (aka "ARPANET")
|
||||
electronic mailing list on the BRL-CAD software, which is called
|
||||
.sp .5
|
||||
.ti +1i
|
||||
<CAD @ ARL.ARMY.MIL>.
|
||||
.sp .5
|
||||
Bug reports and discussions of new features
|
||||
are the main topics; volume of messages has been light (so far).
|
||||
Direct your bug reports to this address. Request a subscription by
|
||||
sending to
|
||||
.sp .5
|
||||
.ti +1i
|
||||
<CAD-REQUEST @ ARL.ARMY.MIL>.
|
||||
.sp .5
|
||||
If you find bugs, please report your experiences via E-mail.
|
||||
.sp
|
||||
A variety of information on BRL-CAD is available via the World-Wide-Web.
|
||||
Papers, documentation, and the software repository may be found at
|
||||
.sp .5
|
||||
.ti +1i
|
||||
http://ftp.arl.army.mil/brlcad/
|
||||
.sp
|
||||
.IP "FUTURE EVENTS"
|
||||
.sp
|
||||
It is expected that new releases of this software will be issued
|
||||
between once and twice a year.
|
||||
Information about new releases will be routinely provided
|
||||
by both paper and electronic mail
|
||||
to recipients of this software.
|
||||
If your address changes, please let us
|
||||
know, so we can update our records.
|
||||
.sp
|
||||
.KS
|
||||
.nf
|
||||
Best Wishes,
|
||||
The BRL-CAD Development Team
|
||||
devs@brlcad.org
|
||||
-Lee Butler
|
||||
.sp
|
||||
Leader, Advanced Computer Systems Team
|
||||
AMSRL-SL-BE
|
||||
U.S. Army Research Laboratory
|
||||
APG, MD 21005-5068 USA
|
||||
.sp
|
||||
E-mail: <BUTLER @ ARL.ARMY.MIL>
|
||||
.KE
|
||||
.fi
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* tab/Cakefile
|
||||
*/
|
||||
|
||||
#define SRCDIR anim
|
||||
#define PRODUCTS anim_cascade anim_fly anim_hardtrack anim_keyread \
|
||||
anim_lookat anim_offset anim_orient anim_script \
|
||||
anim_sort anim_time anim_track anim_turn chan_add \
|
||||
chan_mult chan_permute \
|
||||
|
||||
|
||||
#define SRCSUFF .c
|
||||
#define MANSECTION 1
|
||||
|
||||
#include "../Cakefile.defs"
|
||||
#include "../Cakefile.prog"
|
||||
|
||||
#define FILES anim_cascade anim_fly anim_hardtrack anim_keyread \
|
||||
anim_lookat anim_offset anim_orient anim_script anim_sort \
|
||||
anim-time anim_track anim_turn cattrack chan_add chan_mult \
|
||||
chan_permute
|
||||
|
||||
/* Explicit composition of each product */
|
||||
anim_cascade: anim_cascade.o LIBBN_DEP LIBBU_DEP
|
||||
CC LDFLAGS anim_cascade.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_cascade
|
||||
|
||||
anim_fly: anim_fly.o LIBBU_DEP
|
||||
CC LDFLAGS anim_fly.o LIBBU LIBBU_LIBES LIBES -o anim_fly
|
||||
|
||||
anim_hardtrack: anim_hardtrack.o LIBBN_DEP LIBBU_DEP
|
||||
CC LDFLAGS anim_hardtrack.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_hardtrack
|
||||
|
||||
anim_keyread: anim_keyread.o LIBBN_DEP LIBBU_DEP
|
||||
CC LDFLAGS anim_keyread.o LIBBN LIBBU LIBBU_LIBES LIBES -o anim_keyread
|
||||
|
||||
anim_lookat: anim_lookat.o LIBBN_DEP LIBBU_DEP
|
||||
CC LDFLAGS anim_lookat.o LIBBN LIBBU LIBBU_LIBES LIBES -o anim_lookat
|
||||
|
||||
anim_offset: anim_offset.o LIBBN_DEP LIBBU_DEP
|
||||
CC LDFLAGS anim_offset.o LIBBN LIBBU LIBBU_LIBES LIBES -o anim_offset
|
||||
|
||||
anim_orient: anim_orient.o LIBBN_DEP LIBBU_DEP
|
||||
CC LDFLAGS anim_orient.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_orient
|
||||
|
||||
anim_script: anim_script.o LIBBN_DEP LIBBU_DEP
|
||||
CC LDFLAGS anim_script.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_script
|
||||
|
||||
anim_sort: anim_sort.o LIBBU_DEP
|
||||
CC LDFLAGS anim_sort.o LIBBU LIBBU_LIBES LIBES -o anim_sort
|
||||
|
||||
anim_time: anim_time.o
|
||||
CC LDFLAGS anim_time.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_time
|
||||
|
||||
anim_track: anim_track.o cattrack.o LIBBN_DEP LIBBU_DEP
|
||||
CC LDFLAGS anim_track.o cattrack.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_track
|
||||
|
||||
anim_turn: anim_turn.o LIBBN_DEP LIBBU_DEP
|
||||
CC LDFLAGS anim_turn.o LIBRT LIBBN LIBBU LIBBU_LIBES LIBES -o anim_turn
|
||||
|
||||
chan_add: chan_add.o
|
||||
CC LDFLAGS chan_add.o LIBES -o chan_add
|
||||
|
||||
chan_mult: chan_mult.o
|
||||
CC LDFLAGS chan_mult.o LIBES -o chan_mult
|
||||
|
||||
chan_permute: chan_permute.o
|
||||
CC LDFLAGS chan_permute.o LIBES -o chan_permute
|
||||
|
||||
#include "../Cakefile.rules"
|
||||
@@ -0,0 +1,187 @@
|
||||
.TH ANIM_CASCADE 1 BRL/CAD
|
||||
.SH NAME
|
||||
anim_cascade - evaluate movement of an object relative to a moving frame of
|
||||
reference
|
||||
.SH SYNOPSIS
|
||||
.B anim_cascade [-s][-o(f|r|a)] [-(f|r|a)(c|y) # # #] <
|
||||
.B input.table >
|
||||
.B output.table
|
||||
.SH DESCRIPTION
|
||||
.I Anim_cascade
|
||||
is designed to enable the user to control the movement of objects relative to
|
||||
other objects. In the normal mode of operation, the user supplies
|
||||
the position and orientation of a (possibly moving) frame of reference and
|
||||
the position
|
||||
and orientation of an object relative to the frame of reference,
|
||||
and
|
||||
.I anim_cascade
|
||||
produces the absolute position and orientation of the object at each
|
||||
point in time.
|
||||
All orientations are specified as yaw, pitch, and roll.
|
||||
The columns of the input table are:
|
||||
.sp
|
||||
time fx fy fz fyaw fpitch froll rx ry rz ryaw rpitch rroll
|
||||
.sp
|
||||
and the columns of the output table are:
|
||||
.sp
|
||||
time ax ay az ayaw apitch aroll
|
||||
.sp
|
||||
Here "f" refers to the frame of reference, "r" refers to the position
|
||||
and orientation of the object relative to the frame, and "a"
|
||||
refers to the absolute position and orientation of the object.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-or
|
||||
Output the relative position and orientation.
|
||||
If this option is specified,
|
||||
.I anim_cascade
|
||||
will expect the absolute position and orientation of the frame of
|
||||
reference and the object as input,
|
||||
and will produce the position and orientation or the object relative to
|
||||
the frame as output. The
|
||||
input columns should be:
|
||||
.sp
|
||||
time fx fy fz fyaw fpitch froll ax ay az ayaw apitch aroll
|
||||
.sp
|
||||
and the output columns will be:
|
||||
.sp
|
||||
time rx ry rz ryaw rpitch rroll
|
||||
.sp
|
||||
.TP
|
||||
.B \-of
|
||||
Output the frame of reference.
|
||||
If this option is specified,
|
||||
.I anim_cascade
|
||||
will expect the absolute and relative positions and orientations of the
|
||||
object as input,
|
||||
and will produce the corresponding frame of reference as output.
|
||||
The input columns should be:
|
||||
.sp
|
||||
time ax ay az ayaw apitch aroll rx ry rz ryaw rpitch rroll
|
||||
.sp
|
||||
and the output columns will be:
|
||||
.sp
|
||||
time fx fy fz fyaw fpitch froll
|
||||
.sp
|
||||
.TP
|
||||
.B \-fc # # #
|
||||
Specify a constant position for the frame of reference. The
|
||||
columns fx, fy, and fz should be omitted from the input table, and the
|
||||
command-line arguments will be used instead.
|
||||
This has no effect if used
|
||||
in conjunction with
|
||||
.B -of
|
||||
.TP
|
||||
.B \-fy # # #
|
||||
Specify a constant orientation for the frame of reference. The
|
||||
columns fyaw, fpitch, and froll should be omitted from the input table,
|
||||
and the command-line arguments will be used instead.
|
||||
This has no effect if used
|
||||
in conjunction with
|
||||
.BR -of .
|
||||
.TP
|
||||
.B \-rc # # #
|
||||
Specify a constant position of the object relative to the frame
|
||||
of reference. The
|
||||
columns rx, ry, and rz should be omitted from the input table, and the
|
||||
command-line arguments will be used instead.
|
||||
This has no effect if used
|
||||
in conjunction with
|
||||
.BR -or .
|
||||
.TP
|
||||
.B \-ry # # #
|
||||
Specify a constant orientation of the object relative to the
|
||||
frame of reference. The
|
||||
columns ryaw, rpitch, and rroll should be omitted from the input table,
|
||||
and the command-line arguments will be used instead.
|
||||
This has no effect if used
|
||||
in conjunction with
|
||||
.BR -or .
|
||||
.TP
|
||||
.B \-ac # # #
|
||||
Specify a constant absolute position for the object. The
|
||||
columns ax, ay, and az should be omitted from the input table, and the
|
||||
command-line arguments will be used instead.
|
||||
This has no effect unless used
|
||||
in conjunction with
|
||||
.B -or
|
||||
or
|
||||
.BR -of .
|
||||
.TP
|
||||
.B \-ay # # #
|
||||
Specify a constant absolute orientation for the object. The
|
||||
columns ayaw, apitch, and aroll should be omitted from the input table,
|
||||
and the
|
||||
command-line arguments will be used instead.
|
||||
This has no effect unless used
|
||||
in conjunction with
|
||||
.B -or
|
||||
or
|
||||
.BR -of .
|
||||
.TP
|
||||
.B \-s
|
||||
Suppress time column. No time column is read or written.
|
||||
.sp
|
||||
Note: When all of the input columns are specified with command-line arguments,
|
||||
then standard input is not read and
|
||||
only one line of output is produced. The time value will be set to zero,
|
||||
unless it is suppressed.
|
||||
|
||||
.SH EXAMPLES
|
||||
1. Suppose that you want the virtual camera to pan in a circle around a
|
||||
moving vehicle, always staying a fixed distance from the vehicle.
|
||||
There should already exist an animation table with the time, position,
|
||||
and orientation of the vehicle in each frame. This will be the moving
|
||||
frame of reference. Next, you should create an animation table which
|
||||
describes how the camera would need to move if the vehicle stood still
|
||||
at the origin. The columns of the second animation table should be
|
||||
appended to the columns of the first table
|
||||
(using
|
||||
.IR paste ,
|
||||
for example), to create the
|
||||
input table.
|
||||
.I Anim_cascade
|
||||
will produce an absolute animation table for
|
||||
the camera, suitable to use as input to
|
||||
.IR anim_script :
|
||||
.sp
|
||||
anim_cascade < input.table | anim_script -v500 > view.script
|
||||
.sp
|
||||
2. Suppose that you have an animation path for an object and you want to
|
||||
know when it crosses a given oblique plane. You can use the
|
||||
.B -or
|
||||
option to
|
||||
find out what the position of the object is relative to the frame of
|
||||
reference of the plane. Suppose that the plane is defined by the
|
||||
equation:
|
||||
.sp
|
||||
x + z = 0
|
||||
.sp
|
||||
In a frame of reference located at the origin with a pitch of 45
|
||||
degrees, the x-axis is perpendicular to the given plane.
|
||||
To convert the absolute animation path into this frame of reference, the command
|
||||
would be:
|
||||
.sp
|
||||
anim_cascade -or -fc 0 0 0 -fy 0 45 0 < absolute.table > relative.table
|
||||
.sp
|
||||
Wherever the x coordinate in the output table is positive, the object
|
||||
lies above the plane.
|
||||
.sp
|
||||
3. Suppose that one object is situated at the point (1,2,3) with a yaw,
|
||||
pitch, and roll of (45, 25, 10). Suppose further that you want to
|
||||
position a camera so that to the camera, the first object seems to be 10
|
||||
units straight ahead, facing to the right. You could find the required
|
||||
position and orientation of the camera with the following command:
|
||||
.sp
|
||||
anim_cascade -s -of -ac 1 2 3 -ay 45 25 10 -rc 10 0 0 -ry -90 0 0
|
||||
.sp
|
||||
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1993-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
@@ -0,0 +1,301 @@
|
||||
/* A N I M _ C A S C A D E . C
|
||||
*
|
||||
* Purpose: Given position and orientation of main frame of reference,
|
||||
* along with the position and orientation of another frame with respect
|
||||
* to the main frame, give the absolute orientation and position of the
|
||||
* second frame.
|
||||
* For example, given the position and orientation of a tank, and of the
|
||||
* turret relative to the tank, you can get the absolute position and
|
||||
* orientation of the turret at each time.
|
||||
* Or, optionally, given position and orientation of main frame of
|
||||
* reference, and the absolute position and orientation of another frame,
|
||||
* find the position and orientation of the second frame in terms of the main
|
||||
* frame of reference. (-i option).
|
||||
*
|
||||
* Usage:
|
||||
* anim_cascade main.table < relative.table > absolute.table
|
||||
*
|
||||
* The format of the tables is:
|
||||
* time x y z yaw pitch roll
|
||||
* unless specified otherwise by options.
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "machine.h"
|
||||
#include "vmath.h"
|
||||
#include "bu.h"
|
||||
#include "bn.h"
|
||||
#include "anim.h"
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define RTOD 180.000/M_PI
|
||||
#endif
|
||||
|
||||
#define CASCADE_A 0
|
||||
#define CASCADE_R 1
|
||||
#define CASCADE_F 2
|
||||
|
||||
int get_args();
|
||||
|
||||
extern void anim_dy_p_r2mat();
|
||||
extern void anim_tran();
|
||||
extern int anim_mat2ypr();
|
||||
|
||||
extern int bu_optind;
|
||||
extern char *bu_optarg;
|
||||
|
||||
vect_t fcenter, fypr, rcenter, rypr, acenter, aypr;
|
||||
int cmd_fcen, cmd_fypr, cmd_rcen, cmd_rypr, cmd_acen, cmd_aypr;
|
||||
int output_mode, read_time, print_time;
|
||||
|
||||
int
|
||||
main (argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int val;
|
||||
fastf_t time, yaw1, pitch1, roll1, yaw2, pitch2, roll2;
|
||||
vect_t cen1, cen2, cen_ans, ang_ans, rad_ang_ans, rotated;
|
||||
mat_t m_rot1, m_rot2, m_ans;
|
||||
int one_time, read_cen1, read_cen2, read_rot1, read_rot2;
|
||||
|
||||
read_cen1 = read_cen2 = read_rot1 = read_rot2 = 1;
|
||||
|
||||
if (!get_args(argc,argv))
|
||||
fprintf(stderr,"anim_cascade: Argument error.");
|
||||
|
||||
switch (output_mode) {
|
||||
case CASCADE_A:
|
||||
if (cmd_fcen) {
|
||||
VMOVE(cen1, fcenter);
|
||||
read_cen1 = 0;
|
||||
}
|
||||
if (cmd_rcen) {
|
||||
VMOVE(cen2, rcenter);
|
||||
read_cen2 = 0;
|
||||
}
|
||||
if (cmd_fypr){
|
||||
anim_dy_p_r2mat(m_rot1, fypr[0], fypr[1], fypr[2]);
|
||||
read_rot1 = 0;
|
||||
}
|
||||
if (cmd_rypr){
|
||||
anim_dy_p_r2mat(m_rot2, rypr[0], rypr[1], rypr[2]);
|
||||
read_rot2 = 0;
|
||||
}
|
||||
break;
|
||||
case CASCADE_R:
|
||||
if (cmd_fcen) {
|
||||
VMOVE(cen1, fcenter);
|
||||
read_cen1 = 0;
|
||||
}
|
||||
if (cmd_acen) {
|
||||
VMOVE(cen2, acenter);
|
||||
read_cen2 = 0;
|
||||
}
|
||||
if (cmd_fypr){
|
||||
anim_dy_p_r2mat(m_rot1, fypr[0], fypr[1], fypr[2]);
|
||||
read_rot1 = 0;
|
||||
}
|
||||
if (cmd_aypr){
|
||||
anim_dy_p_r2mat(m_rot2, aypr[0], aypr[1], aypr[2]);
|
||||
read_rot2 = 0;
|
||||
}
|
||||
break;
|
||||
case CASCADE_F:
|
||||
if (cmd_acen) {
|
||||
VMOVE(cen1, acenter);
|
||||
read_cen1 = 0;
|
||||
}
|
||||
if (cmd_rcen) {
|
||||
VMOVE(cen2, rcenter);
|
||||
read_cen2 = 0;
|
||||
}
|
||||
if (cmd_aypr){
|
||||
anim_dy_p_r2mat(m_rot1, aypr[0], aypr[1], aypr[2]);
|
||||
read_rot1 = 0;
|
||||
}
|
||||
if (cmd_rypr){
|
||||
anim_dy_p_r2mat(m_rot2, rypr[0], rypr[1], rypr[2]);
|
||||
read_rot2 = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
one_time = (!(read_cen1||read_cen2||read_rot1||read_rot2));
|
||||
read_time = one_time ? 0 : print_time;
|
||||
time = 0.0;
|
||||
|
||||
val = 3;
|
||||
while(1){
|
||||
if (read_time) {
|
||||
val=scanf("%lf",&time);
|
||||
if (val < 1) break;
|
||||
}
|
||||
if (read_cen1)
|
||||
val =scanf("%lf %lf %lf",cen1, cen1+1, cen1+2);
|
||||
if (read_rot1) {
|
||||
val=scanf("%lf %lf %lf", &yaw1, &pitch1, &roll1);
|
||||
anim_dy_p_r2mat(m_rot1, yaw1, pitch1, roll1);
|
||||
}
|
||||
if (read_cen2) {
|
||||
val=scanf("%lf %lf %lf", cen2, cen2+1,cen2+2);
|
||||
}
|
||||
if (read_rot2) {
|
||||
val=scanf("%lf %lf %lf", &yaw2, &pitch2, &roll2);
|
||||
anim_dy_p_r2mat(m_rot2, yaw2, pitch2, roll2);
|
||||
}
|
||||
if (val<3) break;
|
||||
|
||||
if (output_mode==CASCADE_R) {
|
||||
anim_tran(m_rot1);
|
||||
VSUB2(rotated,cen2,cen1);
|
||||
MAT4X3PNT(cen_ans, m_rot1, rotated);
|
||||
bn_mat_mul(m_ans, m_rot1, m_rot2);
|
||||
} else if (output_mode==CASCADE_F) {
|
||||
anim_tran(m_rot2);
|
||||
bn_mat_mul(m_ans, m_rot1, m_rot2);
|
||||
MAT4X3PNT(rotated, m_ans, cen2);
|
||||
VSUB2(cen_ans, cen1, rotated);
|
||||
} else {
|
||||
MAT4X3PNT(rotated, m_rot1, cen2);
|
||||
VADD2(cen_ans, rotated, cen1);
|
||||
bn_mat_mul(m_ans, m_rot1, m_rot2);
|
||||
}
|
||||
anim_mat2ypr(rad_ang_ans, m_ans);
|
||||
VSCALE(ang_ans, rad_ang_ans, RTOD);
|
||||
|
||||
if (print_time){
|
||||
printf("%g",time);
|
||||
}
|
||||
printf("\t%.12g\t%.12g\t%.12g", cen_ans[0], cen_ans[1], cen_ans[2]);
|
||||
printf("\t%.12g\t%.12g\t%.12g", ang_ans[0], ang_ans[1], ang_ans[2]);
|
||||
printf("\n");
|
||||
|
||||
if (one_time) break;
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#define OPT_STR "so:f:r:a:"
|
||||
|
||||
int get_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c,d;
|
||||
|
||||
output_mode = CASCADE_A;
|
||||
cmd_fcen = cmd_fypr = cmd_rcen = cmd_rypr = cmd_acen = cmd_aypr = 0;
|
||||
print_time = 1;
|
||||
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
|
||||
switch(c){
|
||||
case 'f':
|
||||
d = *(bu_optarg);
|
||||
if (d == 'c'){
|
||||
sscanf(argv[bu_optind],"%lf",fcenter+0);
|
||||
sscanf(argv[bu_optind+1],"%lf",fcenter+1);
|
||||
sscanf(argv[bu_optind+2],"%lf",fcenter+2);
|
||||
bu_optind += 3;
|
||||
cmd_fcen = 1;
|
||||
break;
|
||||
} else if ( d =='y'){
|
||||
sscanf(argv[bu_optind],"%lf",fypr+0);
|
||||
sscanf(argv[bu_optind+1],"%lf",fypr+1);
|
||||
sscanf(argv[bu_optind+2],"%lf",fypr+2);
|
||||
bu_optind += 3;
|
||||
cmd_fypr = 1;
|
||||
break;
|
||||
} else {
|
||||
fprintf(stderr,"anim_cascade: unknown option -f%c\n", d);
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
d = *(bu_optarg);
|
||||
if (d == 'c'){
|
||||
sscanf(argv[bu_optind],"%lf",rcenter+0);
|
||||
sscanf(argv[bu_optind+1],"%lf",rcenter+1);
|
||||
sscanf(argv[bu_optind+2],"%lf",rcenter+2);
|
||||
bu_optind += 3;
|
||||
cmd_rcen = 1;
|
||||
break;
|
||||
} else if ( d =='y'){
|
||||
sscanf(argv[bu_optind],"%lf",rypr+0);
|
||||
sscanf(argv[bu_optind+1],"%lf",rypr+1);
|
||||
sscanf(argv[bu_optind+2],"%lf",rypr+2);
|
||||
bu_optind += 3;
|
||||
cmd_rypr = 1;
|
||||
break;
|
||||
} else {
|
||||
fprintf(stderr,"anim_cascade: unknown option -r%c\n", d);
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
d = *(bu_optarg);
|
||||
if (d == 'c'){
|
||||
sscanf(argv[bu_optind],"%lf",acenter+0);
|
||||
sscanf(argv[bu_optind+1],"%lf",acenter+1);
|
||||
sscanf(argv[bu_optind+2],"%lf",acenter+2);
|
||||
bu_optind += 3;
|
||||
cmd_acen = 1;
|
||||
break;
|
||||
} else if ( d =='y'){
|
||||
sscanf(argv[bu_optind],"%lf",aypr+0);
|
||||
sscanf(argv[bu_optind+1],"%lf",aypr+1);
|
||||
sscanf(argv[bu_optind+2],"%lf",aypr+2);
|
||||
bu_optind += 3;
|
||||
cmd_aypr = 1;
|
||||
break;
|
||||
} else {
|
||||
fprintf(stderr,"anim_cascade: unknown option -a%c\n", d);
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
d = *(bu_optarg);
|
||||
if (d == 'r'){
|
||||
output_mode = CASCADE_R;
|
||||
} else if (d == 'f') {
|
||||
output_mode = CASCADE_F;
|
||||
} else if (d == 'a') { /* default */
|
||||
output_mode = CASCADE_A;
|
||||
} else {
|
||||
fprintf(stderr,"anim_cascade: unknown option -i%c\n",d);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
print_time = 0;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"anim_cascade: unknown option: -%c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
Executable
+94
@@ -0,0 +1,94 @@
|
||||
.TH ANIM_FLY 1 BRL/CAD
|
||||
.SH NAME
|
||||
anim_fly - make animation table to simulate flying motion
|
||||
.SH SYNOPSIS
|
||||
.B anim_fly
|
||||
.B [-f factor]
|
||||
.B [-r]
|
||||
.B [-p integer]
|
||||
.B [-b max_bank_angle]
|
||||
.B [-s step]
|
||||
.B < in.table
|
||||
.B > out.table
|
||||
.SH DESCRIPTION
|
||||
This filter is designed to simulate the motion of an airplane.
|
||||
Given a four-column table specifying the desired 3D position of the
|
||||
airplane at each relevant time step,
|
||||
.I anim_fly
|
||||
produces a seven-column file
|
||||
which also includes the orientation of the plane in terms of yaw,
|
||||
pitch, and roll. The yaw and pitch are manipulated so that
|
||||
the plane faces the direction of motion, while the roll is used to do
|
||||
banking.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -f#
|
||||
This option specifies a factor to control the severity of the banking.
|
||||
The best factor is a subjective decision; a good starting point can best
|
||||
be obtained by using the -b option. Animations representing aircraft
|
||||
of different scales will need different factors.
|
||||
If the
|
||||
slightest curve throws the plane into a 90 degree bank, the factor is
|
||||
too large; if it doesn't bank enough, the factor is too small. The size
|
||||
of the best factor varies inversely with the size of the imagined
|
||||
aircraft plane.
|
||||
If a factor of 0 is used, there will
|
||||
be no banking. This would be appropriate for animating a ground
|
||||
vehicle.
|
||||
.TP
|
||||
.B -b#
|
||||
This option is used to estimate a good value for the -f option. The
|
||||
parameter is the maximum desired banking angle. Anim_fly then computes
|
||||
the factor necessary to keep the banking below the specified angle. This
|
||||
value is returned instead of anim_fly's usual output.
|
||||
.TP
|
||||
.B -r
|
||||
Suppress vertical loop smoothing.
|
||||
A special case occurs if the aircraft is to perform a vertical
|
||||
loop. Normally, the algorithm likes to keep the aircraft right-side up.
|
||||
This would cause the airplane to do an instantaneous 180 roll as it hits
|
||||
the vertical portion of the loop. To counter this, a capability was
|
||||
built in which prevents this sudden roll, allowing the aircraft to go
|
||||
upside-down in a loop situation. This feature can be suppressed with the
|
||||
.B -r
|
||||
flag.
|
||||
.TP
|
||||
.B -p
|
||||
Specify the ratio of input rows to output rows, which must be
|
||||
an integer. The default, of course, is one. The accuracy of the output
|
||||
depends on having a large number of input lines, which is not usually a
|
||||
problem in animations, which require a large number of frames per
|
||||
second, anyway. If a test animation with a small number of frames per
|
||||
second is being created, the user should still use an input table
|
||||
with a high number of input rows, reducing the frequency of the output
|
||||
with the
|
||||
.B -p
|
||||
option. For example, if
|
||||
.B in.table
|
||||
contains 30 rows for each
|
||||
second of the animation, then the command:
|
||||
.sp
|
||||
anim_fly -f0.001 -p10 < in.table > out.table
|
||||
.sp
|
||||
would produce an animation table containing 3 rows for each
|
||||
second of the animation.
|
||||
.TP
|
||||
.B -s
|
||||
Specify the minimum step size for the discrete-time differentiation. At any
|
||||
given point on the flight path, the yaw, pitch, and roll are calculated based
|
||||
on a past point, the current point, and a future point. Normally,
|
||||
these are consecutive points from the input table. If the time
|
||||
difference between the points falls below a certain threshold,
|
||||
then non-consecutive points are used to avoid
|
||||
numerical instability. The default time threshhold is 0.1 seconds - this
|
||||
can be raised or lowered using the -s option.
|
||||
Try raising the threshold if the output orientations experience random
|
||||
jiter.
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1993-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
Executable
+320
@@ -0,0 +1,320 @@
|
||||
/* A N I M _ F L Y . C
|
||||
*
|
||||
* Simulate flying motion, for an airplane or virtual camera.
|
||||
*
|
||||
* This filter operates on animation tables. Given the desired position
|
||||
* of the airplane in each frame, anim_fly produces a table including the
|
||||
* plane's position and orientation. A "magic factor" should be supplied
|
||||
* to control the severity of banking. Looping behavior can be toggled
|
||||
* with another option.
|
||||
*
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "machine.h"
|
||||
#include "externs.h"
|
||||
#include "bu.h"
|
||||
#include "vmath.h"
|
||||
#include "anim.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define MAXN 100
|
||||
|
||||
int estimate_f = 0;
|
||||
fastf_t max_bank = 0;
|
||||
fastf_t max_cross = 0;
|
||||
int loop = 1;
|
||||
int print_int = 1;
|
||||
fastf_t magic_factor = 1.0;
|
||||
fastf_t desired_step = 0.1;
|
||||
|
||||
int get_args();
|
||||
|
||||
#define PREP -1
|
||||
#define START 0
|
||||
#define MIDDLE 1
|
||||
#define WANE 2
|
||||
#define END 3
|
||||
#define STOP 4
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int count, status, num_read, enn, i, pp;
|
||||
fastf_t *points, *cur;
|
||||
fastf_t yaw, pch, rll, stepsize, first[4], second[4];
|
||||
fastf_t f_prm_0(), f_prm_1(), f_prm_2();
|
||||
void get_orientation();
|
||||
|
||||
yaw = pch = rll = 0.0;
|
||||
|
||||
if (!get_args(argc,argv))
|
||||
fprintf(stderr,"Anim_fly: Get_args error");
|
||||
|
||||
/* read first two lines of table to determine the time step used */
|
||||
/* (a constant time step is assumed throughout the rest of the file)*/
|
||||
scanf("%lf %lf %lf %lf", first, first+1, first+2, first+3);
|
||||
scanf("%lf %lf %lf %lf", second, second+1, second+2, second+3);
|
||||
stepsize = second[0]-first[0];
|
||||
|
||||
/* determine n, the number of points to store ahead and behind
|
||||
* the current point. 2n points are stored, minimum enn=2 */
|
||||
enn = (int) (desired_step/stepsize);
|
||||
if (enn>MAXN) enn=MAXN;
|
||||
if (enn<1) enn=1;
|
||||
|
||||
/* allocate storage */
|
||||
points = (fastf_t *) calloc((3*enn+1)*4, sizeof(fastf_t));
|
||||
|
||||
/* read the first 3n points into the storage array*/
|
||||
VMOVEN(points+4, first, 4);
|
||||
VMOVEN(points+8, second, 4);
|
||||
num_read=4; /* in order to pass test if n=1 */
|
||||
for (cur=points+12; cur<points+(4*(3*enn+1)); cur+=4){
|
||||
num_read=scanf("%lf %lf %lf %lf", cur,cur+1,cur+2,cur+3);
|
||||
}
|
||||
if (num_read<4){
|
||||
fprintf(stderr,"Anim_fly: Not enough lines in input table.\n");
|
||||
fprintf(stderr,"Increase number of lines or reduce the minimum stepsize with -s.\n");
|
||||
fprintf(stderr,"Currently the minumum step size is %g seconds.\n",desired_step);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
max_cross = 0;
|
||||
count = 0;
|
||||
pp = 0;
|
||||
status = START;
|
||||
while (status != STOP) {
|
||||
switch (status) {
|
||||
case START: /* first n points */
|
||||
pp += 4;
|
||||
get_orientation(points+pp,points+pp+4*enn,points+pp+4*2*enn, f_prm_0, &yaw, &pch, &rll);
|
||||
if (!(count%print_int)&&!estimate_f) {
|
||||
printf("%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\n",points[pp+0],points[pp+1],points[pp+2],points[pp+3],yaw,pch,rll);
|
||||
}
|
||||
if (pp >= 4*enn)
|
||||
status=MIDDLE;
|
||||
break;
|
||||
case MIDDLE: /* middle points (at least one)*/
|
||||
for (i=0; i<3*enn*4; i++){
|
||||
VMOVEN(points+(4*i), points+(4*(i+1)), 4);
|
||||
}
|
||||
num_read=scanf("%lf %lf %lf %lf", points+(4*(3*enn)),points+(4*(3*enn)+1),points+(4*(3*enn)+2),points+(4*(3*enn)+3));
|
||||
if (num_read < 4) {
|
||||
pp = 0;
|
||||
status = WANE;
|
||||
}
|
||||
get_orientation(points,points+(4*enn),points+4*(2*enn), f_prm_1, &yaw, &pch, &rll);
|
||||
if (!(count%print_int)&&!estimate_f) {
|
||||
printf("%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\n",points[4*(enn)+0],points[4*(enn)+1],points[4*(enn)+2],points[4*(enn)+3],yaw,pch,rll);
|
||||
}
|
||||
break;
|
||||
case WANE: /* last n - 1 middle points */
|
||||
pp += 4;
|
||||
if (pp >= 4*enn){
|
||||
status = END;
|
||||
count--;
|
||||
pp = 0;
|
||||
break;
|
||||
}
|
||||
get_orientation(points+pp,points+pp+4*enn,points+pp+4*2*enn, f_prm_1, &yaw, &pch, &rll);
|
||||
if (!(count%print_int)&&!estimate_f) {
|
||||
printf("%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\n",points[4*(enn)+0+pp],points[4*(enn)+1+pp],points[4*(enn)+2+pp],points[4*(enn)+3+pp],yaw,pch,rll);
|
||||
}
|
||||
break;
|
||||
case END: /* last n points */
|
||||
get_orientation(points+pp,points+pp+4*enn,points+pp+4*2*enn, f_prm_2, &yaw, &pch, &rll);
|
||||
if (!(count%print_int)&&!estimate_f) {
|
||||
printf("%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t%.10g\n",points[8*enn+pp+0],points[8*enn+pp+1],points[8*enn+pp+2],points[8*enn+pp+3],yaw,pch,rll);
|
||||
}
|
||||
pp += 4;
|
||||
if (pp >= 4*enn)
|
||||
status = STOP;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Return the factor needed to achieve the requested max_bank */
|
||||
if (estimate_f){
|
||||
if (max_cross < VDIVIDE_TOL) {
|
||||
printf("%.10g\n",0.0);
|
||||
} else {
|
||||
printf("%.10g\n", 1000.0 * max_bank/max_cross);
|
||||
}
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
void
|
||||
get_orientation(p0,p1,p2,function, p_yaw, p_pch, p_rll)
|
||||
fastf_t p0[4],p1[4],p2[4], *p_yaw, *p_pch, *p_rll;
|
||||
fastf_t (*function)();
|
||||
{
|
||||
int i;
|
||||
fastf_t step,vel[3],accel[3];
|
||||
fastf_t f_double_prm(),xyz2yaw(),xyz2pch(),bank();
|
||||
|
||||
static fastf_t last_yaw;
|
||||
static int not_first_time, upside_down;
|
||||
|
||||
step = p2[0] - p1[0];
|
||||
for (i=1;i<4;i++) {
|
||||
vel[i-1] = (*function)(p0[i],p1[i],p2[i],step);
|
||||
accel[i-1] = f_double_prm(p0[i],p1[i],p2[i],step);
|
||||
}
|
||||
*p_yaw = xyz2yaw(vel);
|
||||
*p_pch = xyz2pch(vel);
|
||||
*p_rll = bank(accel,vel);
|
||||
|
||||
if (fabs(*p_pch)==90.0) /* don't change yaw if velocity vertical */
|
||||
*p_yaw = last_yaw;
|
||||
|
||||
/* avoid sudden yaw changes in vertical loops */
|
||||
if (not_first_time&&loop){
|
||||
if ((fabs(last_yaw - *p_yaw)<181.0)&&(fabs(last_yaw - *p_yaw)>179.0))
|
||||
upside_down = (upside_down) ? 0 : 1;
|
||||
if (upside_down)
|
||||
(*p_rll) += 180;
|
||||
}
|
||||
|
||||
last_yaw = *p_yaw;
|
||||
not_first_time = 1;
|
||||
}
|
||||
|
||||
/* determine the yaw of the given direction vector */
|
||||
fastf_t xyz2yaw(d)
|
||||
fastf_t d[3];
|
||||
{
|
||||
fastf_t yaw;
|
||||
yaw = RTOD*atan2(d[1],d[0]);
|
||||
if (yaw < 0.0) yaw += 360.0;
|
||||
return yaw;
|
||||
}
|
||||
|
||||
/* determine the pitch of the given direction vector */
|
||||
fastf_t xyz2pch(d)
|
||||
fastf_t d[3];
|
||||
{
|
||||
fastf_t x;
|
||||
x = sqrt(d[0]*d[0] + d[1]*d[1]);
|
||||
return (RTOD*atan2(d[2],x));
|
||||
|
||||
}
|
||||
|
||||
/* given the 3-d velocity and acceleration of an imaginary aircraft,
|
||||
find the amount of bank the aircraft would need to undergo.
|
||||
Algorithm: the bank angle is proportional to the cross product
|
||||
of the horizontal velocity and horizontal acceleration, up to a
|
||||
maximum bank of 90 degrees in either direction. */
|
||||
fastf_t bank(acc,vel)
|
||||
fastf_t acc[3],vel[3];
|
||||
{
|
||||
fastf_t cross;
|
||||
|
||||
cross = vel[1]*acc[0] - vel[0]*acc[1];
|
||||
|
||||
if (estimate_f) {
|
||||
max_cross = ( fabs(cross) > max_cross) ? fabs(cross) : max_cross;
|
||||
}
|
||||
|
||||
cross *= magic_factor;
|
||||
|
||||
if (cross > 90) cross = 90;
|
||||
if (cross < -90) cross = -90;
|
||||
return cross;
|
||||
}
|
||||
|
||||
/* given f(t), f(t+h), f(t+2h), and h, calculate f'(t) */
|
||||
fastf_t f_prm_0(x0,x1,x2,h)
|
||||
fastf_t x0,x1,x2,h;
|
||||
{
|
||||
return -(3.0*x0 - 4.0*x1 + x2)/(2*h);
|
||||
}
|
||||
|
||||
/* given f(t), f(t+h), f(t+2h), and h, calculate f'(t+h) */
|
||||
fastf_t f_prm_1(x0,x1,x2,h)
|
||||
fastf_t x0,x1,x2,h;
|
||||
{
|
||||
return (x2 - x0)/(2*h);
|
||||
}
|
||||
|
||||
/* given f(t), f(t+h), f(t+2h), and h, calculate f'(t+2h) */
|
||||
fastf_t f_prm_2(x0,x1,x2,h)
|
||||
fastf_t x0,x1,x2,h;
|
||||
{
|
||||
return (x0 - 4.0*x1 + 3.0*x2)/(2*h);
|
||||
}
|
||||
|
||||
|
||||
/* given f(t), f(t+h), f(t+2*h), and h, calculate f'' */
|
||||
fastf_t f_double_prm(x0,x1,x2,h)
|
||||
fastf_t x0,x1,x2,h;
|
||||
{
|
||||
return (x0 - 2.0*x1 + x2)/(h*h);
|
||||
}
|
||||
|
||||
|
||||
/* code to read command line arguments*/
|
||||
#define OPT_STR "b:f:p:s:r"
|
||||
int get_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
|
||||
estimate_f = 0;
|
||||
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
|
||||
switch(c){
|
||||
case 'b':
|
||||
sscanf(bu_optarg,"%lf",&max_bank);
|
||||
estimate_f = 1;
|
||||
break;
|
||||
case 'f':
|
||||
sscanf(bu_optarg,"%lf",&magic_factor);
|
||||
magic_factor *= 0.001; /* to put factors in a more reasonable range */
|
||||
break;
|
||||
case 'p':
|
||||
sscanf(bu_optarg,"%d",&print_int);
|
||||
break;
|
||||
case 'r':
|
||||
loop = 0;
|
||||
break;
|
||||
case 's':
|
||||
sscanf(bu_optarg, "%lf", &desired_step);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -%c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
/* A N I M _ F L Y . C
|
||||
*
|
||||
* Simulate flying motion, for an airplane or virtual camera.
|
||||
*
|
||||
* This filter operates on animation tables. Given the desired position
|
||||
* of the airplane in each frame, anim_fly produces a table including the
|
||||
* plane's position and orientation. A "magic factor" should be supplied
|
||||
* to control the severity of banking. Looping behavior can be toggled
|
||||
* with another option.
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "machine.h"
|
||||
#include "vmath.h"
|
||||
#include "anim.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
extern int bu_optind;
|
||||
extern char *bu_optarg;
|
||||
|
||||
int loop = 1;
|
||||
int print_int = 1;
|
||||
fastf_t magic_factor = 1.0;
|
||||
|
||||
#define PREP -1
|
||||
#define START 0
|
||||
#define MIDDLE 1
|
||||
#define END 2
|
||||
#define STOP 3
|
||||
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int count, status, num_read;
|
||||
fastf_t point0[4],point1[4],point2[4],point3[4], yaw, pch, rll;
|
||||
fastf_t f_prm_0(), f_prm_1(), f_prm_2();
|
||||
|
||||
VSETALL(point0,0.0);
|
||||
VSETALL(point1,0.0);
|
||||
VSETALL(point2,0.0);
|
||||
VSETALL(point3,0.0);
|
||||
yaw = pch = rll = 0.0;
|
||||
|
||||
if (!get_args(argc,argv))
|
||||
fprintf(stderr,"Anim_fly: Get_args error");
|
||||
|
||||
count = -2;
|
||||
status = PREP;
|
||||
num_read = 4;
|
||||
while (status != STOP) {
|
||||
/* check for end of file status */
|
||||
if (num_read < 4) status = END;
|
||||
|
||||
/*wait twice to prime the pump before starting calculations*/
|
||||
if (!(count++)) status = START;
|
||||
|
||||
/* read one line of the table into point3, storing
|
||||
previous values in point0, point1, and point2. */
|
||||
if (status != END) {
|
||||
VMOVEN(point0,point1,4);
|
||||
VMOVEN(point1,point2,4);
|
||||
VMOVEN(point2,point3,4);
|
||||
num_read = scanf("%lf %lf %lf %lf", point3, point3+1, point3+2, point3+3);
|
||||
}
|
||||
|
||||
if (status==START) { /* do calculations for the first point*/
|
||||
get_orientation(point1,point2,point3, f_prm_0, &yaw, &pch, &rll);
|
||||
if (!(count%print_int)) {
|
||||
printf("%f %f %f %f %f %f %f\n",point1[0],point1[1],point1[2],point1[3],yaw,pch,rll);
|
||||
}
|
||||
status = MIDDLE;
|
||||
}
|
||||
else if (status==MIDDLE) {/*do calculations for all middle points*/
|
||||
get_orientation(point0,point1,point2, f_prm_1, &yaw, &pch, &rll);
|
||||
if (!(count%print_int)) {
|
||||
printf("%f %f %f %f %f %f %f\n",point1[0],point1[1],point1[2],point1[3],yaw,pch,rll);
|
||||
}
|
||||
}
|
||||
else if (status==END) { /*do calculations for the last point*/
|
||||
get_orientation(point0,point1,point2, f_prm_2, &yaw, &pch, &rll);
|
||||
if (!(count%print_int)) {
|
||||
printf("%f %f %f %f %f %f %f\n",point2[0],point2[1],point2[2],point2[3],yaw,pch,rll);
|
||||
}
|
||||
status = STOP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
get_orientation(p0,p1,p2,function, p_yaw, p_pch, p_rll)
|
||||
fastf_t p0[4],p1[4],p2[4], *p_yaw, *p_pch, *p_rll;
|
||||
fastf_t (*function)();
|
||||
{
|
||||
int i;
|
||||
fastf_t step,vel[3],accel[3];
|
||||
fastf_t f_double_prm(),xyz2yaw(),xyz2pch(),bank();
|
||||
|
||||
static fastf_t last_yaw, last_pch, last_rll;
|
||||
static int not_first_time, upside_down;
|
||||
|
||||
step = p2[0] - p1[0];
|
||||
for (i=1;i<4;i++) {
|
||||
vel[i-1] = (*function)(p0[i],p1[i],p2[i],step);
|
||||
accel[i-1] = f_double_prm(p0[i],p1[i],p2[i],step);
|
||||
}
|
||||
*p_yaw = xyz2yaw(vel);
|
||||
*p_pch = xyz2pch(vel);
|
||||
*p_rll = bank(accel,vel);
|
||||
|
||||
if (fabs(*p_pch)==90.0) /* don't change yaw if velocity vertical */
|
||||
*p_yaw = last_yaw;
|
||||
|
||||
/* avoid sudden yaw changes in vertical loops */
|
||||
if (not_first_time&&loop){
|
||||
if ((fabs(last_yaw - *p_yaw)<181.0)&&(fabs(last_yaw - *p_yaw)>179.0))
|
||||
upside_down = (upside_down) ? 0 : 1;
|
||||
if (upside_down)
|
||||
(*p_rll) += 180;
|
||||
}
|
||||
|
||||
last_yaw = *p_yaw;
|
||||
last_pch = *p_pch;
|
||||
last_rll = *p_rll;
|
||||
not_first_time = 1;
|
||||
}
|
||||
|
||||
/* determine the yaw of the given direction vector */
|
||||
fastf_t xyz2yaw(d)
|
||||
fastf_t d[3];
|
||||
{
|
||||
fastf_t yaw;
|
||||
yaw = RTOD*atan2(d[1],d[0]);
|
||||
if (yaw < 0.0) yaw += 360.0;
|
||||
return yaw;
|
||||
}
|
||||
|
||||
/* determine the pitch of the given direction vector */
|
||||
fastf_t xyz2pch(d)
|
||||
fastf_t d[3];
|
||||
{
|
||||
fastf_t x;
|
||||
x = sqrt(d[0]*d[0] + d[1]*d[1]);
|
||||
return (RTOD*atan2(d[2],x));
|
||||
|
||||
}
|
||||
|
||||
/* given the 3-d velocity and acceleration of an imaginary aircraft,
|
||||
find the amount of bank the aircraft would need to undergo.
|
||||
Algorithm: the bank angle is proportional to the cross product
|
||||
of the horizontal velocity and horizontal acceleration, up to a
|
||||
maximum bank of 90 degrees in either direction. */
|
||||
fastf_t bank(acc,vel)
|
||||
fastf_t acc[3],vel[3];
|
||||
{
|
||||
fastf_t cross;
|
||||
|
||||
cross = vel[1]*acc[0] - vel[0]*acc[1];
|
||||
cross *= magic_factor;
|
||||
if (cross > 90) cross = 90;
|
||||
if (cross < -90) cross = -90;
|
||||
return cross;
|
||||
}
|
||||
|
||||
/* given f(t), f(t+h), f(t+2h), and h, calculate f'(t) */
|
||||
fastf_t f_prm_0(x0,x1,x2,h)
|
||||
fastf_t x0,x1,x2,h;
|
||||
{
|
||||
return -(3.0*x0 - 4.0*x1 + x2)/(2*h);
|
||||
}
|
||||
|
||||
/* given f(t), f(t+h), f(t+2h), and h, calculate f'(t+h) */
|
||||
fastf_t f_prm_1(x0,x1,x2,h)
|
||||
fastf_t x0,x1,x2,h;
|
||||
{
|
||||
return (x2 - x0)/(2*h);
|
||||
}
|
||||
|
||||
/* given f(t), f(t+h), f(t+2h), and h, calculate f'(t+2h) */
|
||||
fastf_t f_prm_2(x0,x1,x2,h)
|
||||
fastf_t x0,x1,x2,h;
|
||||
{
|
||||
return (x0 - 4.0*x1 + 3.0*x2)/(2*h);
|
||||
}
|
||||
|
||||
|
||||
/* given f(t), f(t+h), f(t+2*h), and h, calculate f'' */
|
||||
fastf_t f_double_prm(x0,x1,x2,h)
|
||||
fastf_t x0,x1,x2,h;
|
||||
{
|
||||
return (x0 - 2.0*x1 + x2)/(h*h);
|
||||
}
|
||||
|
||||
|
||||
/* code to read command line arguments*/
|
||||
#define OPT_STR "f:p:r"
|
||||
int get_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
|
||||
switch(c){
|
||||
case 'f':
|
||||
sscanf(bu_optarg,"%lf",&magic_factor);
|
||||
magic_factor *= 0.001; /* to put factors in a more reasonable range */
|
||||
break;
|
||||
case 'p':
|
||||
sscanf(bu_optarg,"%d",&print_int);
|
||||
break;
|
||||
case 'r':
|
||||
loop = 0;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -%c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
Executable
+293
@@ -0,0 +1,293 @@
|
||||
.TH ANIM_HARDTRACK 1 BRL/CAD
|
||||
.SH NAME
|
||||
anim_hardtrack - make an animation script for the links and/or wheels of a
|
||||
tracked vehicle with rigid axles.
|
||||
.SH SYNOPSIS
|
||||
.B
|
||||
anim_hardtrack [-l num_links linkname] [-w wheelname] [options] wheelfile < in.table > out.script
|
||||
.SH DESCRIPTION
|
||||
.I Anim_hardtrack
|
||||
is designed to produce an animation script for the
|
||||
animation of a track and/or the wheels defining a track, where the wheels
|
||||
are rigidly fixed in place with respect to the vehicle. The main
|
||||
difference between
|
||||
.I anim_hardtrack
|
||||
and
|
||||
.I anim_track
|
||||
is that
|
||||
.I anim_track
|
||||
handles vehicles with dynamic axles. Both are designed to be use in
|
||||
conjunction with
|
||||
.I anim_script,
|
||||
to achieve the final result.
|
||||
.PP
|
||||
.B in.table
|
||||
is the file that will be used to animate the
|
||||
vehicle itself. By default, it is assumed that it contains a time column,
|
||||
three columns of translation information, and three columns specifying the
|
||||
vehicle's yaw, pitch, and roll. If it is desired that the vehicle be steered
|
||||
automatically, then the table should contain only time and position, and the
|
||||
.B -s
|
||||
option should be used.
|
||||
.PP
|
||||
The track's
|
||||
geometry is defined by
|
||||
.BR wheelfile ,
|
||||
a table which contains one row for each wheel defining the track. The
|
||||
first three columns of the table specify the x, y, and z coordinates of
|
||||
the wheel centers. The fourth column specifies the radius of each wheel.
|
||||
.PP
|
||||
The order in which the wheels are listed should be the order in which a
|
||||
link of the track would move around the wheels when the vehicle is moving
|
||||
forward. (clockwise, when looking from the right of the vehicle).
|
||||
The wheel centers should all lie in a plane perpendicular to the vehicle's
|
||||
left-right axis. If this is not the case,
|
||||
.I anim_hardtrack
|
||||
uses the first wheel as the standard and projects all the other wheels into
|
||||
the same plane as the first wheel. By default, it is assumed that the
|
||||
vehicle's left-right axis is the y-axis. If the modeled vehicle has some
|
||||
other orientation, this must be specified with the
|
||||
.B -b
|
||||
option.
|
||||
.PP
|
||||
By default, it is
|
||||
assumed that
|
||||
all of the link objects are modeled at the model origin,
|
||||
with the wheel-contacting surface centered on the origin and the
|
||||
ground-contacting surface facing up. The sides of each link which
|
||||
connect to other links should face the positive and negative x-axes.
|
||||
.I Anim_hardtrack
|
||||
prints the appropriate
|
||||
commands to move the links from
|
||||
the origin to the correct place around the wheels.
|
||||
.PP
|
||||
If the links are modeled in place around the wheels to begin with, the
|
||||
the
|
||||
.B -p
|
||||
and
|
||||
.B -i
|
||||
options are needed.
|
||||
|
||||
.SH OPTIONS:
|
||||
.PP
|
||||
One or both of the first two options should always be specified.
|
||||
.TP
|
||||
.B \-l num linkname
|
||||
Print animation scripts to animate the links of the track. Animation
|
||||
commands will be printed for
|
||||
.I num
|
||||
different links
|
||||
named
|
||||
.IR linkname .0, linkname .1,
|
||||
up through
|
||||
.IR linkname .( num -1).
|
||||
A typical example of a linkname might
|
||||
be "tank/righttrack/links/link". The full pathname must be specified,
|
||||
because anim_hardtrack's method is to roll the links around within
|
||||
the vehicle's tree structure so that when the whole vehicle "tank" is
|
||||
animated, the complete combination of rolling around and translating is
|
||||
achieved.
|
||||
.TP
|
||||
.B \-w wheelname
|
||||
Print animation
|
||||
scripts to rotate each wheel. The wheels are named wheelname.0, wheelname.1,
|
||||
and so on, where wheelname.0 is the first wheel listed in
|
||||
.BR wheelfile .
|
||||
As with the links, the full pathname for the wheels should be specified.
|
||||
.TP
|
||||
.B \-b # # #
|
||||
Specify the yaw, pitch, and roll of the vehicle's axes
|
||||
with respect to the world axes. By default, the vehicle is assumed to
|
||||
have a yaw, pitch, and roll of 0.
|
||||
.TP
|
||||
.B \-d # # #
|
||||
Specify (in world coordinates) the centroid of the vehicle
|
||||
of which the track is a part. By default, the vehicle is assumed
|
||||
centered at the origin.
|
||||
.PP
|
||||
When calling
|
||||
.I anim_script
|
||||
to handle the animation of the vehicle
|
||||
itself, the parameters following the
|
||||
.B -b
|
||||
and
|
||||
.B -d
|
||||
options should be identical
|
||||
to those used for
|
||||
.IR anim_hardtrack .
|
||||
.TP
|
||||
.B \-r #
|
||||
Specify the common radius of all wheels. In this case the fourth column
|
||||
should be omitted from the
|
||||
.BR wheelfile .
|
||||
.TP
|
||||
.B \-s
|
||||
Automatic steering. In this case,
|
||||
.B in.table
|
||||
specifies only the time and position
|
||||
of the vehicle. The orientation is calculated to always face the vehicle
|
||||
in the direction of motion.
|
||||
This should be used when the
|
||||
.B \-s
|
||||
option is used by
|
||||
.I anim_script
|
||||
to animate the vehicle.
|
||||
.PP
|
||||
.TP
|
||||
.B \-f#
|
||||
Specify the integer with which to begin numbering frames.
|
||||
Default is zero.
|
||||
.TP
|
||||
.B \-p
|
||||
Animate placed links, rather than links stored at the origin.
|
||||
In order for placed links to be animated, they must be equally spaced
|
||||
around the wheels defining the track. The track must be formed of arcs
|
||||
around the wheels and straight lines between the wheels, and the links
|
||||
must be numbered clockwise as seen from the right.
|
||||
By default, it is assumed that the
|
||||
center of the first link, linkname.0, is at the beginning of the
|
||||
straight track segment between wheel.(n-1) and wheel.0 . If this is
|
||||
not the case, the position of the first link must be identified with the
|
||||
.B \-i#
|
||||
option.
|
||||
.TP
|
||||
.B \-i#
|
||||
Specify the initial offset of the first link. If this option is
|
||||
not used, the initial position of linkname.0 is assumed to be the
|
||||
beginning of the straight track segment between wheel.(n-1) and wheel.0.
|
||||
If it is used, the argument specifies the distance clockwise around the
|
||||
track from the default position to the actual desired offset. If the
|
||||
links are modeled at the origin, the user can choose any offset. This
|
||||
can be useful for lining up the links with gears of a drive wheel, for
|
||||
example.
|
||||
If the
|
||||
.B -p
|
||||
option is being used to animated pre-placed links, then it is essential
|
||||
that the actual offset of the first pre-placed link be specified.
|
||||
.SS Output:
|
||||
.PP
|
||||
The output is a script containing as many frames as there
|
||||
are positions in
|
||||
.BR in.table .
|
||||
If there are
|
||||
.I n
|
||||
links and
|
||||
.I k
|
||||
wheels, each
|
||||
frame contains up to
|
||||
.IR n + k
|
||||
anim commands, either:
|
||||
.nf
|
||||
|
||||
anim linkname.i matrix lmul
|
||||
[... matrix ...] ;
|
||||
or
|
||||
anim wheelname.j matrix lmul
|
||||
[... matrix ...] ;
|
||||
|
||||
for 0<=i<n and 0<=j<k.
|
||||
|
||||
.fi
|
||||
.SH EXAMPLES
|
||||
Suppose you want to make an animation of a tank rolling across
|
||||
flat ground. A list of desired positions is created, perhaps by
|
||||
interpolating between a few key positions; this information is placed
|
||||
in a four column animation table, in.table. The model of the tank is stored in
|
||||
model.g as a combination named "tank". Its centroid is at the
|
||||
point (0,0,1000) and it faces the y-axis. An animation script for the
|
||||
tank itself is created as follows:
|
||||
.PP
|
||||
anim_script -s -d 0 0 1000 -b 90 0 0 /tank < in.table > tank.script
|
||||
.PP
|
||||
Suppose that there are two
|
||||
roadwheels and a drivewheel (tank/rwheel/wheel.i, 0<=i<3) which define
|
||||
the shape of the right track.
|
||||
A file called
|
||||
.B rwheelfile
|
||||
is created:
|
||||
.nf
|
||||
|
||||
1500 -2000 30 30
|
||||
1500 0 1000 35
|
||||
1500 2000 30 30
|
||||
|
||||
.fi
|
||||
This
|
||||
.B rwheelfile
|
||||
lists the position and
|
||||
radius of each of the three wheels.
|
||||
.PP
|
||||
There are eighty links which make up the right track
|
||||
(tank/rtrack/link.i, 0<=i<80).
|
||||
The links of the right track are all modeled
|
||||
at the origin with the outer, ground-contacting surface
|
||||
facing up and the inner, wheel-contacting surface centered at the
|
||||
origin.
|
||||
.PP
|
||||
The appropriate call to
|
||||
.I anim_hardtrack
|
||||
is now:
|
||||
.sp
|
||||
anim_hardtrack -d 0 0 1000 -b 90 0 0 -w tank/rwheel -l 80 tank/rtrack/link
|
||||
rwheelfile < in.table > rtrack.script
|
||||
.sp
|
||||
Suppose that the left track is similar to the right track,
|
||||
except that all the wheels are of radius 30 units, and the links, rather
|
||||
than being stored at the origin, are actually placed in position around
|
||||
the left wheels to begin with. The
|
||||
.B lwheelfile
|
||||
would be:
|
||||
.nf
|
||||
|
||||
-1500 -2000 30
|
||||
-1500 0 1000
|
||||
-1500 2000 30
|
||||
|
||||
.fi
|
||||
and the call would be:
|
||||
.sp
|
||||
anim_hardtrack -p -r 30 -d 0 0 1000 -b 90 0 0 -w tank/lwheel
|
||||
-l 80 tank/ltrack/link lwheelfile <in.table > ltrack.script
|
||||
.sp
|
||||
Here, it is assumed that tank/ltrack/link.0 is initially at the
|
||||
beginning of the straight track segment between lwheel.2 and lwheel.0,
|
||||
that is, at the point (2000,1500,-1000) in the vehicle's coordinates.
|
||||
If, instead, the first link is initially centered halfway between the
|
||||
two roadwheels, this must be specified with the
|
||||
.B -i#
|
||||
option. If the link's
|
||||
actual position is 2000 units farther around the track than expected:
|
||||
.sp
|
||||
anim_hardtrack -i 2000 -p -r 30 -d 0 0 1000 -b 90 0 0 -w tank/lwheel
|
||||
-l 80 tank/ltrack/link lwheelfile <in.table > ltrack.script
|
||||
.sp
|
||||
One final step may remain. The above procedure produces a script with rigid
|
||||
naming conventions, in order to make input simple. This may mean that
|
||||
the names in the script do not match the names in model.g. An editor
|
||||
should then be used at the end to replace all instances of the
|
||||
conventional name with the real name; for example, in this case it may
|
||||
be necessary to replace "rwheel.1" with "r_drivewheel".
|
||||
.PP
|
||||
.BR Tank.script ,
|
||||
.BR rtrack.script ,
|
||||
and
|
||||
.B ltrack.script
|
||||
can be combined
|
||||
with
|
||||
.I anim_sort
|
||||
to make the complete script.
|
||||
.PP
|
||||
.SH BUGS
|
||||
Tracks must have at least two wheels, and they must be listed in clockwise
|
||||
order, or the results are unpredictable.
|
||||
.SH SEE ALSO
|
||||
anim_script(1), anim_track(1)
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1993-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
|
||||
Executable
+517
@@ -0,0 +1,517 @@
|
||||
/* A N I M _ H A R D T R A C K . C
|
||||
*
|
||||
* Animate the links and wheels of a tracked vehicle. It is assumed
|
||||
* that the wheels do not translate with respect to the vehicle.
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#ifdef USE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "machine.h"
|
||||
#include "vmath.h"
|
||||
#include "bu.h"
|
||||
#include "bn.h"
|
||||
#include "anim.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifndef M_PI_2
|
||||
#define M_PI_2 (M_PI*0.5)
|
||||
#endif
|
||||
|
||||
#define NW num_wheels
|
||||
#define NEXT(i) (i+1)%NW
|
||||
#define PREV(i) (i+NW-1)%NW
|
||||
|
||||
#define TRACK_ANIM 0
|
||||
#define TRACK_ARCED 1
|
||||
|
||||
typedef double *pdouble;
|
||||
|
||||
struct wheel {
|
||||
vect_t pos; /* displacement of wheel from vehicle origin */
|
||||
fastf_t rad; /* radius of wheel */
|
||||
fastf_t ang0; /* angle where track meets wheel; 0 < a < 2pi */
|
||||
fastf_t ang1; /* angle where track leaves wheel; 0 < a < 2pi */
|
||||
fastf_t arc; /* arclength of contact between wheel and track */
|
||||
};
|
||||
|
||||
struct track {
|
||||
vect_t pos0; /* beginning point of track section */
|
||||
vect_t pos1; /* end point of track section */
|
||||
vect_t dir; /* unit vector: direction of track section */
|
||||
fastf_t len; /* length of track section */
|
||||
};
|
||||
|
||||
struct slope {
|
||||
vect_t dir; /* vector from previous to current axle */
|
||||
fastf_t len; /* length of vector described above */
|
||||
};
|
||||
|
||||
struct all {
|
||||
struct wheel w; /* parameters describing the track around a wheel */
|
||||
struct track t; /* track between this wheel and the previous wheel */
|
||||
struct slope s; /* vector between this axle and the previous axle */
|
||||
};
|
||||
|
||||
struct rlink {
|
||||
vect_t pos; /* reverse of initial position */
|
||||
fastf_t ang; /* initial angle */
|
||||
};
|
||||
|
||||
/* external variables */
|
||||
extern int bu_optind;
|
||||
extern char *bu_optarg;
|
||||
|
||||
/* variables describing track geometry - used by main, trackprep, get_link */
|
||||
struct all *x;
|
||||
struct rlink *r; /* reverse of initial locations of links */
|
||||
int num_links, num_wheels;
|
||||
fastf_t track_y, tracklen;
|
||||
|
||||
/* variables set by get_args */
|
||||
int wheel_nindex; /* argv[wheel_nindex] = wheelname*/
|
||||
int link_nindex; /* argv[link_nindex] = linkname*/
|
||||
int print_wheel; /* flag: do wheel animation */
|
||||
int print_link; /* flag: do link animation */
|
||||
int print_mode; /* anim for rt or arced for mged */
|
||||
int arced_frame; /* which frame to arced */
|
||||
int links_placed; /* flag: links are initially on the track */
|
||||
int axes, cent; /* flags: alternate axes, centroid specified */
|
||||
int steer; /* flag: vehicle automatically steered */
|
||||
int first_frame; /* integer with which to begin numbering frames */
|
||||
fastf_t radius; /* common radius of all wheels */
|
||||
fastf_t init_dist; /* initial distance of first link along track */
|
||||
vect_t centroid, rcentroid; /* alternate centroid and its reverse */
|
||||
mat_t m_axes, m_rev_axes; /* matrices to and from alternate axes */
|
||||
char link_cmd[10]; /* default is "rarc" */
|
||||
char wheel_cmd[10]; /* default is "lmul" */
|
||||
int get_circumf; /* flag: just return circumference of track */
|
||||
|
||||
int get_link();
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
void anim_dir2mat(), anim_y_p_r2mat(), anim_add_trans(),anim_mat_print();
|
||||
int get_args(), track_prep(), val, frame, go, i, count;
|
||||
fastf_t y_rot, distance, yaw, pitch, roll;
|
||||
vect_t p1, p2, p3, dir, dir2, wheel_now, wheel_prev;
|
||||
vect_t zero, position, vdelta, temp, to_track, to_front;
|
||||
mat_t mat_v, wmat, mat_x;
|
||||
FILE *stream;
|
||||
int last_frame;
|
||||
|
||||
VSETALL(zero,0.0);
|
||||
VSETALL(to_track,0.0);
|
||||
VSETALL(centroid,0.0);
|
||||
VSETALL(rcentroid,0.0);
|
||||
init_dist = y_rot = radius= 0.0;
|
||||
first_frame = num_wheels = steer = axes = cent = links_placed=0;
|
||||
num_wheels = num_links = last_frame = 0;
|
||||
MAT_IDN(mat_v);
|
||||
MAT_IDN(mat_x);
|
||||
MAT_IDN(wmat);
|
||||
MAT_IDN(m_axes);
|
||||
MAT_IDN(m_rev_axes);
|
||||
|
||||
if (!get_args(argc,argv)){
|
||||
fprintf(stderr,"anim_hardtrack: argument error.");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (axes || cent ){ /* vehicle has own reference frame */
|
||||
anim_add_trans(m_axes,centroid,zero);
|
||||
anim_add_trans(m_rev_axes,zero,rcentroid);
|
||||
}
|
||||
|
||||
/* get track information from specified file */
|
||||
|
||||
if (!(stream = fopen(*(argv+bu_optind),"r"))){
|
||||
fprintf(stderr,"Anim_hardtrack: Could not open file %s.\n",*(argv+bu_optind));
|
||||
return(0);
|
||||
}
|
||||
num_wheels = -1;
|
||||
if (radius) {
|
||||
while (!feof(stream)) {
|
||||
fscanf(stream,"%*f %*f %*f");
|
||||
num_wheels++;
|
||||
}
|
||||
} else {
|
||||
while (!feof(stream)) {
|
||||
fscanf(stream,"%*f %*f %*f %*f");
|
||||
num_wheels++;
|
||||
}
|
||||
}
|
||||
rewind(stream);
|
||||
|
||||
/*allocate memory for track information*/
|
||||
x = (struct all *) calloc(num_wheels,sizeof(struct all));
|
||||
/*read rest of track info */
|
||||
for (i=0;i<NW;i++){
|
||||
fscanf(stream,"%lf %lf %lf", temp, temp+1, temp+2);
|
||||
if (radius)
|
||||
x[i].w.rad = radius;
|
||||
else
|
||||
fscanf(stream,"%lf",& x[i].w.rad);
|
||||
MAT4X3PNT(x[i].w.pos,m_rev_axes,temp);
|
||||
if (i==0)
|
||||
track_y = x[0].w.pos[1];
|
||||
else
|
||||
x[i].w.pos[1] = track_y;
|
||||
}
|
||||
(void) fclose(stream);
|
||||
|
||||
(void) track_prep();
|
||||
|
||||
if (get_circumf) {
|
||||
printf("%.10g\n",tracklen);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* initialize to_track */
|
||||
VSET(to_track, 0.0, track_y, 0.0);
|
||||
VSET(to_front,1.0,0.0,0.0);
|
||||
|
||||
if ((!print_link)&&(!print_wheel)) {
|
||||
fprintf(stderr,"anim_hardtrack: no ouput requested. Use -l or -w.\n");
|
||||
exit(0);
|
||||
}
|
||||
/* main loop */
|
||||
distance = 0.0;
|
||||
if(!steer)
|
||||
frame = first_frame;
|
||||
else
|
||||
frame = first_frame-1;
|
||||
for (val = 3; val > 2; frame++) {
|
||||
go = 1;
|
||||
/*p2 is current position. p3 is next;p1 is previous*/
|
||||
VMOVE(p1,p2);
|
||||
VMOVE(p2,p3);
|
||||
scanf("%*f");/*time stamp*/
|
||||
val = scanf("%lf %lf %lf", p3, p3+1, p3 + 2);
|
||||
if(!steer){
|
||||
scanf("%lf %lf %lf",&yaw,&pitch,&roll);
|
||||
anim_dy_p_r2mat(mat_v,yaw,pitch,roll);
|
||||
anim_add_trans(mat_v,p3,rcentroid);
|
||||
}
|
||||
else { /* analyze positions for steering */
|
||||
/*get useful direction unit vectors*/
|
||||
if (frame == first_frame){ /* first frame*/
|
||||
VSUBUNIT(dir,p3,p2);
|
||||
VMOVE(dir2,dir);
|
||||
}
|
||||
else if (val < 3){ /*last frame*/
|
||||
VSUBUNIT(dir,p2,p1);
|
||||
VMOVE(dir2,dir);
|
||||
}
|
||||
else if (frame > first_frame){ /*normal*/
|
||||
VSUBUNIT(dir,p3,p1);
|
||||
VSUBUNIT(dir2,p2,p1);/*needed for vertical case*/
|
||||
}
|
||||
else go = 0;/*first time through loop;no p2*/
|
||||
|
||||
/*create matrix which would move vehicle*/
|
||||
anim_dir2mat(mat_v,dir,dir2);
|
||||
anim_add_trans(mat_v,p2,rcentroid);
|
||||
}
|
||||
|
||||
/*determine distance traveled*/
|
||||
VMOVE(wheel_prev,wheel_now);
|
||||
MAT4X3PNT(wheel_now,mat_v,to_track);
|
||||
if (frame > first_frame){ /* increment distance by distance moved */
|
||||
VSUB2(vdelta,wheel_now,wheel_prev);
|
||||
MAT3X3VEC(temp,mat_v,to_front);/*new front of vehicle*/
|
||||
distance += VDOT(temp,vdelta);/*portion of vdelta in line with track*/
|
||||
}
|
||||
|
||||
if (go){
|
||||
if (print_mode==TRACK_ANIM) {
|
||||
printf("start %d;\nclean;\n", frame);
|
||||
} else if (print_mode==TRACK_ARCED) {
|
||||
if (frame != arced_frame) continue;
|
||||
last_frame = 1;
|
||||
}
|
||||
if (print_link) {
|
||||
for (count=0;count<num_links;count++){
|
||||
(void) get_link(position,&y_rot,distance+tracklen*count/num_links+init_dist);
|
||||
anim_y_p_r2mat(wmat,0.0,y_rot+r[count].ang,0.0);
|
||||
anim_add_trans(wmat,position,r[count].pos);
|
||||
if ((axes || cent) && links_placed){ /* link moved from vehicle coords */
|
||||
bn_mat_mul(mat_x,wmat,m_rev_axes);
|
||||
bn_mat_mul(wmat,m_axes,mat_x);
|
||||
}
|
||||
else if (axes || cent){ /* link moved to vehicle coords */
|
||||
MAT_MOVE(mat_x,wmat);
|
||||
bn_mat_mul(wmat,m_axes,mat_x);
|
||||
}
|
||||
if (print_mode==TRACK_ANIM) {
|
||||
printf("anim %s.%d matrix %s\n", *(argv+link_nindex),count,link_cmd);
|
||||
anim_mat_printf(stdout,wmat,"%.10g ","\n",";\n");
|
||||
} else if (print_mode==TRACK_ARCED) {
|
||||
printf("arced %s.%d matrix %s ", *(argv+link_nindex),count,link_cmd);
|
||||
anim_mat_printf(stdout,wmat,"%.10g ","","\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (print_wheel){
|
||||
for (count = 0;count<num_wheels;count++){
|
||||
anim_y_p_r2mat(wmat,0.0,-distance/x[count].w.rad,0.0);
|
||||
VREVERSE(temp,x[count].w.pos);
|
||||
anim_add_trans(wmat,x[count].w.pos,temp);
|
||||
if (axes || cent){
|
||||
bn_mat_mul(mat_x,wmat,m_rev_axes);
|
||||
bn_mat_mul(wmat,m_axes,mat_x);
|
||||
}
|
||||
if (print_mode==TRACK_ANIM) {
|
||||
printf("anim %s.%d matrix %s\n",*(argv+wheel_nindex),count,wheel_cmd);
|
||||
anim_mat_printf(stdout,wmat,"%.10g ","\n",";\n");
|
||||
} else if (print_mode==TRACK_ARCED) {
|
||||
printf("arced %s.%d matrix %s ",*(argv+wheel_nindex),count,wheel_cmd);
|
||||
anim_mat_printf(stdout,wmat,"%.10g ","","\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (print_mode==TRACK_ANIM)
|
||||
printf("end;\n");
|
||||
}
|
||||
if (last_frame) break;
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
int track_prep()/*run once at the beginning to establish important track info*/
|
||||
{
|
||||
int i;
|
||||
fastf_t phi, costheta, link_angle, arc_angle;
|
||||
vect_t difference, link_cent;
|
||||
|
||||
/* first loop - get inter axle slopes and start/end angles */
|
||||
for (i=0;i<NW;i++){
|
||||
/*calculate current slope vector*/
|
||||
VSUB2(x[i].s.dir,x[i].w.pos,x[PREV(i)].w.pos);
|
||||
x[i].s.len = MAGNITUDE(x[i].s.dir);
|
||||
/*calculate end angle of previous wheel - atan2(y,x)*/
|
||||
phi = atan2(x[i].s.dir[2],x[i].s.dir[0]);/*absolute angle of slope*/
|
||||
costheta = (x[PREV(i)].w.rad - x[i].w.rad)/x[i].s.len;/*cosine of special angle*/
|
||||
x[PREV(i)].w.ang1 = phi + acos(costheta);
|
||||
while (x[PREV(i)].w.ang1 < 0.0)
|
||||
x[PREV(i)].w.ang1 += 2.0*M_PI;
|
||||
x[i].w.ang0 = x[PREV(i)].w.ang1;
|
||||
}
|
||||
|
||||
/* second loop - handle concavities */
|
||||
for (i=0;i<NW;i++){
|
||||
arc_angle = x[i].w.ang0 - x[i].w.ang1;
|
||||
while (arc_angle < 0.0)
|
||||
arc_angle += 2.0*M_PI;
|
||||
if (arc_angle > M_PI) { /* concave */
|
||||
x[i].w.ang0 = 0.5*(x[i].w.ang0 + x[i].w.ang1);
|
||||
x[i].w.ang1 = x[i].w.ang0;
|
||||
x[i].w.arc = 0.0;
|
||||
}
|
||||
else { /* convex - angles are already correct */
|
||||
x[i].w.arc = arc_angle;
|
||||
}
|
||||
}
|
||||
|
||||
/* third loop - calculate geometry of track segments */
|
||||
tracklen = 0.0;
|
||||
for (i=0;i<NW;i++){
|
||||
/*calculate endpoints of track segment*/
|
||||
x[i].t.pos1[0] = x[i].w.pos[0] + x[i].w.rad*cos(x[i].w.ang0);
|
||||
x[i].t.pos1[1] = x[i].w.pos[1];
|
||||
x[i].t.pos1[2] = x[i].w.pos[2] + x[i].w.rad*sin(x[i].w.ang0);
|
||||
x[i].t.pos0[0] = x[PREV(i)].w.pos[0] + x[PREV(i)].w.rad*cos(x[PREV(i)].w.ang1);
|
||||
x[i].t.pos0[1] = x[PREV(i)].w.pos[1];
|
||||
x[i].t.pos0[2] = x[PREV(i)].w.pos[2] + x[PREV(i)].w.rad*sin(x[PREV(i)].w.ang1);
|
||||
/*calculate length and direction*/
|
||||
VSUB2(difference,x[i].t.pos1,x[i].t.pos0);
|
||||
x[i].t.len = MAGNITUDE(difference);
|
||||
VSCALE((x[i].t.dir),difference,(1.0/x[i].t.len));
|
||||
|
||||
/*calculate arclength and total track length*/
|
||||
tracklen += x[i].t.len;
|
||||
tracklen += x[i].w.arc*x[i].w.rad;
|
||||
}
|
||||
|
||||
/* for a track with links already placed, get initial positions*/
|
||||
r = (struct rlink *) calloc(num_links, sizeof(struct rlink));
|
||||
if (links_placed)
|
||||
for (i=0;i<num_links;i++){
|
||||
get_link(link_cent,&link_angle,init_dist + tracklen*i/num_links);
|
||||
VREVERSE(r[i].pos,link_cent);
|
||||
r[i].ang = -link_angle;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int get_link(pos,angle_p,dist)
|
||||
fastf_t *angle_p, dist;
|
||||
vect_t pos;
|
||||
{
|
||||
int i;
|
||||
vect_t temp;
|
||||
while (dist >= tracklen) /*periodicize*/
|
||||
dist -= tracklen;
|
||||
while (dist < 0.0)
|
||||
dist += tracklen;
|
||||
for (i=0;i<NW;i++){
|
||||
if ( (dist -= x[i].t.len) < 0 ){
|
||||
VSCALE(temp,(x[i].t.dir),dist);
|
||||
VADD2(pos,x[i].t.pos1,temp);
|
||||
*angle_p = atan2(x[i].t.dir[2],x[i].t.dir[0]);
|
||||
return(2*i);
|
||||
}
|
||||
if ((dist -= x[i].w.rad*x[i].w.arc) < 0){
|
||||
*angle_p = dist/x[i].w.rad;
|
||||
*angle_p = x[i].w.ang1 - *angle_p;/*from x-axis to link*/
|
||||
pos[0] = x[i].w.pos[0] + x[i].w.rad*cos(*angle_p);
|
||||
pos[1] = x[i].w.pos[1];
|
||||
pos[2] = x[i].w.pos[2] + x[i].w.rad*sin(*angle_p);
|
||||
*angle_p -= M_PI_2; /*angle of clockwise tangent to circle*/
|
||||
return(2*i+1);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define OPT_STR "b:d:f:i:l:pr:w:sg:m:c"
|
||||
int get_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
fastf_t yaw, pch, rll;
|
||||
void anim_dx_y_z2mat(), anim_dz_y_x2mat();
|
||||
int c, i;
|
||||
axes = cent = links_placed = print_wheel = print_link = 0;
|
||||
get_circumf = 0;
|
||||
print_mode = TRACK_ANIM;
|
||||
strcpy(link_cmd, "rarc");
|
||||
strcpy(wheel_cmd, "lmul");
|
||||
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
|
||||
i=0;
|
||||
switch(c){
|
||||
case 'b':
|
||||
bu_optind -= 1;
|
||||
sscanf(argv[bu_optind+(i++)],"%lf", &yaw );
|
||||
sscanf(argv[bu_optind+(i++)],"%lf", &pch );
|
||||
sscanf(argv[bu_optind+(i++)],"%lf", &rll );
|
||||
bu_optind += 3;
|
||||
anim_dx_y_z2mat(m_axes, rll, -pch, yaw);
|
||||
anim_dz_y_x2mat(m_rev_axes, -rll, pch, -yaw);
|
||||
axes = 1;
|
||||
break;
|
||||
case 'd':
|
||||
bu_optind -= 1;
|
||||
sscanf(argv[bu_optind+(i++)],"%lf",centroid);
|
||||
sscanf(argv[bu_optind+(i++)],"%lf",centroid+1);
|
||||
sscanf(argv[bu_optind+(i++)],"%lf",centroid+2);
|
||||
bu_optind += 3;
|
||||
VREVERSE(rcentroid,centroid);
|
||||
cent = 1;
|
||||
break;
|
||||
case 'f':
|
||||
sscanf(bu_optarg,"%d",&first_frame);
|
||||
break;
|
||||
case 'i':
|
||||
sscanf(bu_optarg,"%lf",&init_dist);
|
||||
break;
|
||||
case 'p':
|
||||
links_placed = 1;
|
||||
break;
|
||||
case 'r':
|
||||
sscanf(bu_optarg,"%lf",&radius);
|
||||
break;
|
||||
case 'w':
|
||||
wheel_nindex = bu_optind - 1;
|
||||
/*sscanf(bu_optarg,"%s",wheel_name);*/
|
||||
print_wheel = 1;
|
||||
break;
|
||||
case 'l':
|
||||
sscanf(bu_optarg,"%d", &num_links);
|
||||
link_nindex = bu_optind;
|
||||
bu_optind += 1;
|
||||
print_link = 1;
|
||||
break;
|
||||
case 's':
|
||||
steer = 1;
|
||||
break;
|
||||
case 'g':
|
||||
sscanf(bu_optarg,"%d",&arced_frame);
|
||||
print_mode = TRACK_ARCED;
|
||||
break;
|
||||
case 'm':
|
||||
switch (*bu_optarg) {
|
||||
case 'l':
|
||||
strncpy(link_cmd,argv[bu_optind], 10);
|
||||
break;
|
||||
case 'w':
|
||||
strncpy(wheel_cmd,argv[bu_optind], 10);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -m%c\n",*bu_optarg);
|
||||
return(0);
|
||||
}
|
||||
bu_optind += 1;
|
||||
break;
|
||||
case 'c':
|
||||
get_circumf = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -%c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
void show_info(which)/* for debugging - -1:track 0:both 1:link*/
|
||||
int which;
|
||||
{
|
||||
int i;
|
||||
if (which <=0){
|
||||
fprintf(stderr,"track length: %f\n",tracklen);
|
||||
fprintf(stderr,"link length: %f\n",tracklen/num_links);
|
||||
for (i=0;i<NW;i++){
|
||||
fprintf(stderr,"wheel %d: %f %f %f %f %f %f\n",i,x[i].w.pos[0],x[i].w.pos[1],x[i].w.pos[2],x[i].w.rad,x[i].w.ang1,x[i].w.arc);
|
||||
fprintf(stderr,"track %d: %f %f %f %f %f %f %f\n",i,x[i].t.pos1[0],x[i].t.pos1[1],x[i].t.pos1[2],x[i].t.dir[0],x[i].t.dir[1],x[i].t.dir[2],x[i].t.len);
|
||||
fprintf(stderr,"slope %d: %f %f %f %f\n",i,x[i].s.dir[0],x[i].s.dir[1],x[i].s.dir[2],x[i].s.len);
|
||||
}
|
||||
}
|
||||
/* if (which >= 0){
|
||||
fprintf(stderr,"%d %f %f %f %f\n",count,position[0],position[1],position[2],y_rot);
|
||||
}*/
|
||||
}
|
||||
|
||||
Executable
+114
@@ -0,0 +1,114 @@
|
||||
.TH ANIM_KEYREAD 1 BRL/CAD
|
||||
.SH NAME
|
||||
anim_keyread - prepares key frames from the mged savekey command for interpolation
|
||||
.SH SYNOPSIS
|
||||
.B anim_keyread
|
||||
.B [-y|z]
|
||||
.B < key.file
|
||||
.B > key.table
|
||||
.SH DESCRIPTION
|
||||
.I Anim_keyread
|
||||
takes as input a file containing a series of keyframes
|
||||
generated by the
|
||||
.I mged
|
||||
command `savekey', and produces a table containing
|
||||
the same information, except that the view orientation matrix is
|
||||
changed to a form that can be interpolated. The default form for the
|
||||
orientation information is the quaternion.
|
||||
For each such keyframe in the input file,
|
||||
.I anim_keyread
|
||||
will produce a
|
||||
row in the output file containing the time, the viewsize, the position
|
||||
of the camera, and the orientation of the camera, specified as a unit
|
||||
quaternion in the order x, y, z, and w.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -y
|
||||
Specify the orientation in terms of yaw, pitch, and roll.
|
||||
.TP
|
||||
.B -z
|
||||
Specify the orientation as a rotation about the z-axis, y-axis,
|
||||
and then x-axis, where the columns are in the order: x,y,z.
|
||||
.SH EXAMPLES
|
||||
The following is an example of a typical keyframe generated by the
|
||||
`savekey' command. The time is 0, the viewsize is ten, the camera is at the
|
||||
point (2.5,2.5,3.53) and the camera orientation is specified by a
|
||||
matrix.
|
||||
.nf
|
||||
|
||||
0.000000
|
||||
1.000000000e+01
|
||||
2.500000000e+00 2.500000000e+00 3.535533906e+00
|
||||
-7.071067812e-01 7.071067812e-01 0.000000000e+00 0.000000000e+00
|
||||
-5.000000000e-01 -5.000000000e-01 7.071067812e-01 0.000000000e+00
|
||||
5.000000000e-01 5.000000000e-01 7.071067812e-01 0.000000000e+00
|
||||
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00
|
||||
|
||||
.fi
|
||||
For the key frame shown above, the output would
|
||||
be:
|
||||
.sp
|
||||
0.000000 10.000000 2.500000 2.500000 3.535534 0.146447 0.353553 0.853553 0.353553
|
||||
.sp
|
||||
The last four numbers define the desired orientation as a
|
||||
quaternion.
|
||||
.PP
|
||||
With the
|
||||
.B -y
|
||||
option, the output would be:
|
||||
.sp
|
||||
0.000000 10.000000 2.500000 2.500000 3.535534 -135.000000 -45.000000 0.000000
|
||||
.sp
|
||||
Here, the last three numbers are the yaw, pitch, and roll,
|
||||
which can be interpreted as follows: Imagine a camera at the origin
|
||||
originally facing the positive x-direction, with the z-axis going up
|
||||
and the y-axis positive to the left. The camera should be rotated
|
||||
+roll degrees about the x-axis, -pitch degrees about the y-axis,
|
||||
and +yaw degrees about the z-axis. In this case, the camera ends up
|
||||
pointing down and to the right of its original position.
|
||||
.PP
|
||||
With the -z option, the output would be:
|
||||
.sp
|
||||
0.000000 10.000000 2.500000 2.500000 3.535534 -35.264390 30.000000 144.735610
|
||||
.sp
|
||||
The last three numbers are x, y, and z rotation angles.
|
||||
The camera is considered to be originally on the z-axis, looking toward
|
||||
the origin with the x-axis to the right and the y-axis going up. The
|
||||
camera is rotated 144.7 degrees about the model's z-axis, then 30
|
||||
degrees about the model's y-axis, and finally -35.2 degrees about the
|
||||
model x-axis.
|
||||
.SH DIAGNOSTICS
|
||||
Problems arise when using Eulers angles, because
|
||||
certain orientations do not have a uniqe representation, and the program
|
||||
must arbitrarily select among an infinite number of possibilities. For
|
||||
example, when using yaw, pitch and roll, the yaw and roll
|
||||
become indistinguishable when the pitch is 90 degrees.
|
||||
.PP
|
||||
When this happens, the roll is set to 0, and the following
|
||||
messages appear on standard error:
|
||||
.nf
|
||||
|
||||
Warning: roll arbitrarily set to 0.0; yaw set to -0.585334 radians.
|
||||
Warning: yaw and roll arbitrarily defined at time = 1.000000.
|
||||
|
||||
.fi
|
||||
A similar effect occurs in xyz format when the rotation about
|
||||
the y-axis is 90 degrees.
|
||||
.nf
|
||||
|
||||
Warning: x arbitrarily set to 0.0; z set to 0.000000.
|
||||
Warning: x and z rotations arbitrarily defined at time = 9.000000.
|
||||
|
||||
.fi
|
||||
One nice thing about quaternions is that you don't run into such
|
||||
problems.
|
||||
.SH SEE ALSO
|
||||
mged(1), tabsub(1), anim_script(1), tabinterp(1)
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1993-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
Executable
+162
@@ -0,0 +1,162 @@
|
||||
/* A N I M _ K E Y R E A D . C
|
||||
*
|
||||
* Convert an list of mged-style 'savekey' keyframes into an
|
||||
* animation table
|
||||
*
|
||||
* The output table specifies the orientation in one of three ways:
|
||||
*
|
||||
* default - quaternions in the order x, y, z, w.
|
||||
*
|
||||
* -z option - Eulers angles, in the order xyz. The model axes are
|
||||
* considered to be rotated about the camera's z, y, and
|
||||
* x axes (in that order).
|
||||
*
|
||||
* -y option - Eulers angles in the form yaw, pitch, roll.
|
||||
*
|
||||
* This is more or less a special case of anim_orient.c
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "machine.h"
|
||||
#include "vmath.h"
|
||||
#include "bu.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define YPR 0
|
||||
#define XYZ 1
|
||||
#define QUATERNION 2
|
||||
|
||||
#define DEGREES 0
|
||||
#define RADIANS 1
|
||||
|
||||
#define NORMAL 0
|
||||
#define ERROR1 1
|
||||
#define ERROR2 2
|
||||
|
||||
#define DTOR M_PI/180.0
|
||||
#define RTOD 180.0/M_PI
|
||||
|
||||
int mode;
|
||||
int units;
|
||||
|
||||
extern int bu_optind;
|
||||
extern char *bu_optarg;
|
||||
|
||||
int get_args();
|
||||
extern void anim_v_unpermute();
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
fastf_t time, viewsize;
|
||||
|
||||
fastf_t eyept[3], viewrot[16], angle[3], quat[4];
|
||||
int anim_mat2ypr(), anim_mat2zyx(), anim_mat2quat();
|
||||
|
||||
if (!get_args(argc,argv))
|
||||
fprintf(stderr,"anim_keyread: get_args error");
|
||||
|
||||
while (!feof(stdin)){ /* read one keyframe */
|
||||
scanf("%lf", &time);
|
||||
scanf("%lf", &viewsize);
|
||||
scanf("%lf %lf %lf", eyept, eyept+1, eyept+2);
|
||||
/* read in transposed matrix */
|
||||
scanf("%lf %lf %lf %lf", viewrot+0, viewrot+4, viewrot+8, viewrot+12);
|
||||
scanf("%lf %lf %lf %lf", viewrot+1, viewrot+5, viewrot+9, viewrot+13);
|
||||
scanf("%lf %lf %lf %lf", viewrot+2, viewrot+6, viewrot+10, viewrot+14);
|
||||
scanf("%lf %lf %lf %lf", viewrot+3, viewrot+7, viewrot+11, viewrot+15);
|
||||
|
||||
if (feof(stdin)) break;
|
||||
|
||||
printf("%.10g\t%.10g\t%.10g\t%.10g\t%.10g\t", time, viewsize,
|
||||
eyept[0], eyept[1], eyept[2]);
|
||||
|
||||
|
||||
if (mode==YPR) {
|
||||
anim_v_unpermute(viewrot);
|
||||
c = anim_mat2ypr(angle,viewrot);
|
||||
if (c==ERROR1)
|
||||
fprintf(stderr,"Warning: yaw and roll arbitrarily defined at time = %f.\n",time);
|
||||
else if (c==ERROR2)
|
||||
fprintf(stderr,"Keyread: can't interpret matrix at time = %f.\n",time);
|
||||
if (units == DEGREES)
|
||||
VSCALE(angle,angle,RTOD);
|
||||
printf("%.10g\t%.10g\t%.10g\n",angle[0],angle[1],angle[2]);
|
||||
}
|
||||
else if (mode==XYZ) {
|
||||
c = anim_mat2zyx(angle,viewrot);
|
||||
if (c==ERROR1)
|
||||
fprintf(stderr,"Warning: x and z rotations arbitrarily defined at time = %f.\n",time);
|
||||
else if (c==ERROR2)
|
||||
fprintf(stderr,"Keyread: can't interpret matrix at time = %f\n.",time);
|
||||
if (units == DEGREES)
|
||||
VSCALE(angle,angle,RTOD);
|
||||
printf("%.10g\t%.10g\t%.10g\n",angle[X],angle[Y],angle[Z]);
|
||||
}
|
||||
else if (mode==QUATERNION){
|
||||
anim_mat2quat(quat,viewrot);
|
||||
printf("%.10g\t%.10g\t%.10g\t%.10g\n",quat[X],quat[Y],quat[Z],quat[W]);
|
||||
}
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
|
||||
#define OPT_STR "yzqr"
|
||||
|
||||
int get_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
|
||||
int c;
|
||||
|
||||
mode = QUATERNION; /* default */
|
||||
units = DEGREES;
|
||||
|
||||
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
|
||||
switch(c){
|
||||
case 'y':
|
||||
mode = YPR;
|
||||
break;
|
||||
case 'z':
|
||||
mode = XYZ;
|
||||
break;
|
||||
case 'q':
|
||||
mode = QUATERNION;
|
||||
break;
|
||||
case 'r':
|
||||
units = RADIANS;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -%c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
.TH ANIM_LOOKAT 1 BRL/CAD
|
||||
.SH NAME
|
||||
anim_lookat - create a view animation script or table which looks from an eye point to
|
||||
a specified point.
|
||||
.SH SYNOPSIS
|
||||
.B anim_lookat
|
||||
.B [\-f #]
|
||||
.B \[-v]
|
||||
.B < in.table
|
||||
.B > out.script
|
||||
.PP
|
||||
.B anim_lookat
|
||||
.B \-[y|q]
|
||||
.B \[-v]
|
||||
.B < in.table
|
||||
.B > out.table
|
||||
|
||||
.SH DESCRIPTION
|
||||
This program takes as input a seven-column animation table
|
||||
consisting of time, an eye point, and a "look-at point", and prints a
|
||||
view animation script to control the virtual camera.
|
||||
The camera always remains "right-side up"; that is, it yaws and pitches but
|
||||
doesn't roll. In cases where the camera looks vertically up or down, the
|
||||
yaw from the previous frame is retained. This avoids sudden jumps as much
|
||||
as possible.
|
||||
.PP
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-f#
|
||||
Specify an integer with which to begin
|
||||
numbering frames. The default is 0.
|
||||
.TP
|
||||
.B \-y
|
||||
The output will be an animation table rather
|
||||
than a view animation script. The output table has 7 columns:
|
||||
a time column, three
|
||||
columns representing position, and three columns representing yaw,
|
||||
pitch, and roll.
|
||||
.TP
|
||||
.B \-q
|
||||
The output will be an animation table rather than a view animation script.
|
||||
The output table has eight columns:
|
||||
a time column, three position columns, and four columns
|
||||
representing the x,y,z, and w coordinates of an orientation quaternion.
|
||||
.TP
|
||||
.B \-v
|
||||
Include the viewsize in the output script or table. The viewsize is
|
||||
calculated in every frame as twice the distance from the eye point to
|
||||
the lookat point. If the output is a table, then the viewsize is printed
|
||||
in the second column.
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1993-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
Executable
+159
@@ -0,0 +1,159 @@
|
||||
/* A N I M _ L O O K A T . C
|
||||
*
|
||||
* Given animation tables for the position of the virtual camera
|
||||
* and a point to look at at each time, this program produces an animation
|
||||
* script to control the camera. The view is kept rightside up, whenever
|
||||
* possible. When looking vertically up or down, the exact orientation
|
||||
* depends on the previous orientation.
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "machine.h"
|
||||
#include "vmath.h"
|
||||
#include "anim.h"
|
||||
#include "bu.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
#ifndef RTOD
|
||||
#define RTOD (180/M_PI)
|
||||
#endif
|
||||
|
||||
|
||||
#define LOOKAT_SCRIPT 0
|
||||
#define LOOKAT_YPR 1
|
||||
#define LOOKAT_QUAT 2
|
||||
|
||||
|
||||
extern int bu_optind;
|
||||
extern char *bu_optarg;
|
||||
|
||||
int frame = 0;
|
||||
int print_mode = LOOKAT_SCRIPT;
|
||||
int print_viewsize = 0;
|
||||
|
||||
int get_args();
|
||||
extern void anim_dirn2mat();
|
||||
extern int anim_mat2ypr();
|
||||
extern int anim_mat2quat();
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
fastf_t time, vsize=0.0;
|
||||
vect_t eye,look,dir, angles, norm, temp;
|
||||
quat_t quat;
|
||||
mat_t mat;
|
||||
int val = 0;
|
||||
|
||||
VSETALL(look,0.0);
|
||||
VSETALL(eye,0.0);
|
||||
|
||||
if (argc > 1)
|
||||
get_args(argc,argv);
|
||||
|
||||
VSET(norm, 0.0, 1.0, 0.0);
|
||||
while (!feof(stdin)){
|
||||
val=scanf("%lf %lf %lf %lf %lf %lf %lf",&time,eye,eye+1,eye+2,look,look+1,look+2);
|
||||
if (val < 7){
|
||||
break;
|
||||
}
|
||||
|
||||
if (print_viewsize) {
|
||||
VSUB2(temp, eye, look);
|
||||
vsize = MAGNITUDE(temp);
|
||||
vsize *= 2.0;
|
||||
}
|
||||
|
||||
VSUBUNIT(dir,look,eye);
|
||||
anim_dirn2mat(mat,dir,norm);
|
||||
VSET(norm, mat[1],mat[5], 0.0);
|
||||
switch (print_mode) {
|
||||
case LOOKAT_SCRIPT:
|
||||
printf("start %d;\n",frame++);
|
||||
printf("clean;\n");
|
||||
if (print_viewsize)
|
||||
printf("viewsize %.10g;\n",vsize);
|
||||
printf("eye_pt %.10g %.10g %.10g;\n",eye[0],eye[1],eye[2]);
|
||||
printf("viewrot %.10g\t%.10g\t%.10g\t0\n", -mat[1], -mat[5], -mat[9]);
|
||||
printf("%.10g\t%.10f\t%.10g\t0\n", mat[2], mat[6], mat[10]);
|
||||
printf("%.10g\t%.10g\t%.10g\t0\n", -mat[0], -mat[4], -mat[8]);
|
||||
printf("0\t0\t0\t1;\n");
|
||||
printf("end;\n");
|
||||
break;
|
||||
case LOOKAT_YPR:
|
||||
anim_mat2ypr(angles,mat);
|
||||
angles[0] *= RTOD;
|
||||
angles[1] *= RTOD;
|
||||
angles[2] *= RTOD;
|
||||
printf("%.10g",time);
|
||||
if (print_viewsize)
|
||||
printf("\t%.10g",vsize);
|
||||
printf("\t%.10g\t%.10g\t%.10g",eye[0],eye[1],eye[2]);
|
||||
printf("\t%.10g\t%.10g\t%.10g\n",angles[0],angles[1],angles[2]);
|
||||
break;
|
||||
case LOOKAT_QUAT:
|
||||
anim_mat2quat(quat,mat);
|
||||
printf("%.10g",time);
|
||||
if (print_viewsize)
|
||||
printf("\t%.10g",vsize);
|
||||
printf("\t%.10g\t%.10g\t%.10g",eye[0],eye[1],eye[2]);
|
||||
printf("\t%.10g\t%.10g\t%.10g\t%.10g\n",quat[0],quat[1],quat[2],quat[3]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#define OPT_STR "f:yqv"
|
||||
|
||||
int get_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
|
||||
switch(c){
|
||||
case 'f':
|
||||
sscanf(bu_optarg,"%d",&frame);
|
||||
break;
|
||||
case 'y':
|
||||
print_mode = LOOKAT_YPR;
|
||||
break;
|
||||
case 'q':
|
||||
print_mode = LOOKAT_QUAT;
|
||||
break;
|
||||
case 'v':
|
||||
print_viewsize = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -%c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
.TH ANIM_OFFSET 1 BRL/CAD
|
||||
.SH NAME
|
||||
anim_offset - create an animation table for an object rigidly attached to
|
||||
another object.
|
||||
.SH SYNOPSIS
|
||||
.B anim_offset
|
||||
.B -o # # #
|
||||
.B [-r]
|
||||
.B < in.table
|
||||
.B > out.table
|
||||
.SH DESCRIPTION
|
||||
This filter operates on animation tables of the type used by
|
||||
.I tabsub
|
||||
and
|
||||
.I anim_script.
|
||||
Given a table specifying the position and
|
||||
orientation of one object at every applicable time,
|
||||
.I anim_offset
|
||||
calculates
|
||||
the position of another object which is rigidly attached to it.
|
||||
.PP
|
||||
The columns of the input table should be time, three columns of
|
||||
position, followed by yaw, pitch, and roll. The output will be
|
||||
normally be a four-column file specifying time and position. If the
|
||||
.B -r
|
||||
option is used, the output is a seven-column file in which the last
|
||||
three columns are copies of the orientation information from the input
|
||||
file.
|
||||
.PP
|
||||
The position of the object relative to the rigid body should be
|
||||
given on the command line in the order x, y, z, with the
|
||||
.B -o # # #
|
||||
option. These offset values
|
||||
should be as measured from the centroid of the rigid body.
|
||||
.SH EXAMPLES
|
||||
This filter could be used, for example, to do an animation where
|
||||
the camera is placed inside a moving vehicle.
|
||||
.PP
|
||||
Suppose that truck.table contains the desired position of the
|
||||
center of the front axle of the truck as well as its orientation at each
|
||||
time. One row of the table might look like this:
|
||||
.nf
|
||||
|
||||
35.2 12450 -140 600 90.0 0.0 0.0
|
||||
|
||||
.fi
|
||||
Thus 35.2 seconds into the animation, the center of the front axle will
|
||||
be at (12450, -140, 600), and the truck will be pointed in the positive
|
||||
y direction. (yaw = 90).
|
||||
.PP
|
||||
Now, suppose we want the camera to ride along in the cab, above
|
||||
and behind the front axle and somewhat to the left. To specify this
|
||||
offset, we use the coordinate frame of the truck, with the origin at the
|
||||
center of the front axle, the x-axis to the front, y to the left, and z
|
||||
pointing up. Let the exact offset from the axle to the desired camera
|
||||
position in this case be (-600, 900, 1200), in units of mm. Now we use
|
||||
the routine:
|
||||
.nf
|
||||
|
||||
anim_offset -o -600 900 1200 < truck.table > camera.table
|
||||
|
||||
.fi
|
||||
The result is a four-column table giving the desired position of the
|
||||
virtual camera at each time. The row corresponding to the sample row
|
||||
above would be:
|
||||
.nf
|
||||
|
||||
35.2 11550 -740 1800
|
||||
|
||||
.fi
|
||||
With the
|
||||
.B -r
|
||||
option, the output would have been:
|
||||
.nf
|
||||
|
||||
35.2 11550 -740 1800 90.0 0.0 0.0
|
||||
|
||||
.fi
|
||||
Now
|
||||
.I tabsub
|
||||
and/or
|
||||
.I anim_script
|
||||
can be used to process these two animation
|
||||
tables into an animation script.
|
||||
.SH BUGS
|
||||
The program will only use orientations specified as yaw,
|
||||
pitch, and roll. You can get around this using
|
||||
.IR anim_orient ,
|
||||
which converts between different orientation representations.
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1993-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
Executable
+110
@@ -0,0 +1,110 @@
|
||||
/* A N I M _ O F F S E T . C
|
||||
*
|
||||
* Animate an object which is rigidly attached to another.
|
||||
*
|
||||
* Given an animation table specifying the position and orientation of
|
||||
* one object, anim_offset produces a similar table specifying the
|
||||
* position of an object rigidly attached to it.
|
||||
*
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "machine.h"
|
||||
#include "vmath.h"
|
||||
#include "bu.h"
|
||||
#include "anim.h"
|
||||
|
||||
extern int bu_optind;
|
||||
extern char *bu_optarg;
|
||||
|
||||
int full_print = 0;
|
||||
vect_t offset;
|
||||
|
||||
int get_args();
|
||||
extern void anim_dy_p_r2mat();
|
||||
extern void anim_add_trans();
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int val;
|
||||
fastf_t yaw, pitch, roll, time;
|
||||
vect_t temp,point,zero;
|
||||
mat_t mat;
|
||||
|
||||
VSETALL( temp , 0.0 );
|
||||
VSETALL( point , 0.0 );
|
||||
VSETALL( zero , 0.0 );
|
||||
|
||||
(void) get_args(argc,argv);
|
||||
|
||||
|
||||
while (1) {
|
||||
/*read line from table */
|
||||
val = scanf("%lf%*[^-0123456789]",&time); /*read time,ignore garbage*/
|
||||
val = scanf("%lf %lf %lf", point, point+1, point +2);
|
||||
val = scanf("%lf %lf %lf", &yaw, &pitch, &roll);
|
||||
if (val < 3) {
|
||||
break;
|
||||
}
|
||||
|
||||
anim_dy_p_r2mat(mat,yaw, pitch,roll);
|
||||
anim_add_trans(mat,point,zero);
|
||||
MAT4X3PNT(temp,mat,offset);
|
||||
|
||||
printf("%.10g\t%.10g\t%.10g\t%.10g",time, temp[0], temp[1], temp[2]);
|
||||
if (full_print)
|
||||
printf("\t%.10g\t%.10g\t%.10g", yaw, pitch, roll);
|
||||
printf("\n");
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#define OPT_STR "ro:"
|
||||
|
||||
int get_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
|
||||
switch(c){
|
||||
case 'r':
|
||||
full_print = 1;
|
||||
break;
|
||||
case 'o':
|
||||
sscanf(argv[bu_optind-1],"%lf",offset+0);
|
||||
sscanf(argv[bu_optind],"%lf",offset+1);
|
||||
sscanf(argv[bu_optind+1],"%lf",offset+2);
|
||||
bu_optind += 2;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -%c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Executable
+217
@@ -0,0 +1,217 @@
|
||||
.TH ANIM_ORIENT 1 BRL/CAD
|
||||
.SH NAME
|
||||
anim_orient - convert between orientation formats
|
||||
.SH SYNOPSIS
|
||||
.B anim_orient
|
||||
.B [q|y|a|z|m][vri]
|
||||
.B [q|y|a|z|m][vriu]
|
||||
.B < in.table
|
||||
.B > out.table
|
||||
.SH DESCRIPTION
|
||||
.I Anim_orient
|
||||
is a filter which translates a table of orientation
|
||||
information from one format to another. The method used is to convert
|
||||
the input format to a matrix, then convert the matrix to the desired
|
||||
output format. The input format is specified in the first argument, and
|
||||
the output format is specified in the second.
|
||||
The orientation formats
|
||||
must be one of the following:
|
||||
.B q
|
||||
(quaternion),
|
||||
.B y
|
||||
(yaw,pitch, and roll),
|
||||
.B a
|
||||
(azimuth, elevation, and twist),
|
||||
.B z
|
||||
(x-y-z angles), or
|
||||
.B m
|
||||
(rotation matrix).
|
||||
In addition, the output format may be modified by the
|
||||
.B u
|
||||
option, and the input and output formats may be modified by the
|
||||
.BR r ,
|
||||
.BR i ,
|
||||
and
|
||||
.B v
|
||||
options. The
|
||||
.B r
|
||||
option specifies that angles are read or written in radians, rather
|
||||
than degrees. The
|
||||
.BR i , v ,
|
||||
and
|
||||
.B u
|
||||
options are explained below.
|
||||
.PP
|
||||
To clearly understand the operation of anim_orient, it is important to
|
||||
examine the difference between orientation and rotation.
|
||||
The matrices, quaternions, and angles
|
||||
used by anim_orient specify rotations. These are transformations
|
||||
which, when applied to an object, preserve its shape but change its
|
||||
orientation with respect to a fixed set of axes. Given the initial
|
||||
orientation of an object, a rotation defines the final orientation, but
|
||||
different initial orientations will yield different final orientations.
|
||||
In order
|
||||
to represent orientations with rotations, we
|
||||
must define a default initial orientation for the object.
|
||||
Then a given matrix, quaternion, or set of angles represents the orientation
|
||||
resulting from applying the rotation to the initial object orientation.
|
||||
.PP
|
||||
If no modifying codes are specified, anim_orient assumes that the
|
||||
default orientation of the object in question faces the positive
|
||||
x-direction, with the world y-axis pointing to the object's left and the
|
||||
z-axis pointing up. This is the orientation in which many
|
||||
.I brlcad
|
||||
objects
|
||||
are modeled, and the default assumed by other animation routines such as
|
||||
anim_script. If the
|
||||
.B v
|
||||
code is specified, then the default orientation
|
||||
is taken to be facing the negative z-direction, with the world x-axis
|
||||
pointing to the object's right and the y-axis pointing up. This is the
|
||||
default orientation of the eye in
|
||||
.I mged
|
||||
and
|
||||
.IR rt .
|
||||
Some common uses of the v
|
||||
option are demonstrated in the examples section.
|
||||
.PP
|
||||
The input and output format codes are:
|
||||
.TP
|
||||
.BR q :
|
||||
Quaternions, in the order x,y,z,w. This is the default input and
|
||||
output format. The output will
|
||||
always be unit quaternions. For a unit quaternion, the
|
||||
xyz-vector represents an axis of rotation and and w represents
|
||||
cos(omega/2), where
|
||||
omega is the angle to be rotated about the given axis.
|
||||
.TP
|
||||
.BR z :
|
||||
x-y-z angles, in the order x, y, z. They represent a rotation
|
||||
of z degrees around the z-axis, followed by y degrees around the y-axis,
|
||||
followed by x degrees around the x-axis. If the code
|
||||
.B zr
|
||||
is used
|
||||
then the angles will be read or written in radians
|
||||
rather than degrees.
|
||||
.TP
|
||||
.BR y :
|
||||
yaw-pitch-roll format, in that order. They represent
|
||||
a rotation of +roll degrees about the x-axis, -pitch degrees about
|
||||
the y-axis, followed by +yaw degrees about the z-axis. If the code
|
||||
.B yr
|
||||
is used, angles are in radians rather than degrees.
|
||||
.TP
|
||||
.BR a :
|
||||
azimuth, elevation, twist, in that order. They represent a rotation of
|
||||
-twist degrees about the x-axis, +elevation degrees about the y-axis,
|
||||
and +azimuth + 180 degrees about the z-axis. Alternatively, they can
|
||||
be thought of as a 180 degree rotation about the z-axis followed by a
|
||||
rotation of +twist degrees about the x-axis, -elevation degrees about
|
||||
the y-axis, and +azimuth degrees about the z-axis.
|
||||
.TP
|
||||
.BR m :
|
||||
pre-multiplication rotation matrix. Sixteen
|
||||
numbers form a 4x4 matrix, although only the nine elements in the upper
|
||||
left corner are actually used. This is the format used at the interior of
|
||||
the conversion routine. It is a transformation from initial orientation to
|
||||
a new orientation.
|
||||
.PP
|
||||
The input and ouput modification codes are:
|
||||
.TP
|
||||
.B i
|
||||
This code is used in conjunction with any of the format codes to represent
|
||||
the inverse transformation. Under the
|
||||
.B i
|
||||
code, a matrix, quaternion, or
|
||||
set of angles represents the inverse of the rotation that it normally
|
||||
represents.
|
||||
For example, normally, the orientation
|
||||
corresponding to a given matrix is the orientation that the default
|
||||
object ends up in after the matrix is applied to it. With the
|
||||
.B i
|
||||
code,
|
||||
a given matrix represents the orientation an object should be placed
|
||||
in so that the applying the matrix puts it back in the default
|
||||
orientation.
|
||||
|
||||
One common use of the
|
||||
.B i
|
||||
option is for handling "Viewrot" matrices used
|
||||
by
|
||||
.I mged
|
||||
and
|
||||
.IR rt .
|
||||
The viewrot matrix is a model-to-view matrix, which is
|
||||
the transpose (inverse) of the matrix which would conceptually be
|
||||
applied to an eye object to put it in the desired place in the model.
|
||||
.TP
|
||||
.B v
|
||||
When this option is specified, the corresponding rotation is considered
|
||||
applied to the default view orientation, rather than the default object
|
||||
orientation, as explained above.
|
||||
.TP
|
||||
.B u
|
||||
This option forces the output orientation to be upright, or "right-side
|
||||
up", where the z-axis is the up direction. In terms of yaw, pitch, and
|
||||
roll, this means that the roll is forced to zero. Because this is a
|
||||
one-way operation, it can only be applied to the output orientation, not
|
||||
the input.
|
||||
|
||||
.SH EXAMPLES
|
||||
.sp
|
||||
Normalize a table of quaternions to unit magnitude. (quaternions are the
|
||||
default format).
|
||||
.sp
|
||||
anim_orient < in.table > out.table
|
||||
.sp
|
||||
change xyz angles to a rotation matrix
|
||||
.sp
|
||||
anim_orient z m < in.table > out.table
|
||||
.sp
|
||||
change azimuth,elevation, and twist to a matrix suitable for the
|
||||
.I rt
|
||||
viewrot command
|
||||
.sp
|
||||
anim_orient a miv < in.table > out.table
|
||||
.sp
|
||||
transpose matrices
|
||||
.sp
|
||||
anim_orient m mi < in.table > out.table
|
||||
.sp
|
||||
change radian xyz angles to yaw-pitch-roll in degrees
|
||||
.sp
|
||||
anim_orient zr y < in.table > out.table
|
||||
.sp
|
||||
given a quaternion being applied to an object facing the x-axis,
|
||||
find the quaternion needed
|
||||
to turn the virtual camera in the same direction using
|
||||
.IR rt 's
|
||||
orientation command
|
||||
.sp
|
||||
anim_orient q qv < in.table > out.table
|
||||
.sp
|
||||
Given the yaw, pitch, and roll of an object, find the yaw, pitch, and
|
||||
roll which would bring it back to the default position.
|
||||
.sp
|
||||
anim_orient y yi < in.table > out.table
|
||||
.sp
|
||||
Force a table of view quaternions to represent "right-side up"
|
||||
orientations.
|
||||
.sp
|
||||
anim_orient qv qvu < in.table > out.table
|
||||
.SH BUGS
|
||||
There are built-in trouble spots which occur, in ypr, xyz, or aet
|
||||
formats, when the pitch, y-rotation, or elevation is an odd multiple of 90
|
||||
degrees, because at this point the other two angles become
|
||||
indistinguishable. The program makes the arbitrary assumption that the
|
||||
roll is zero or that the x-rotation is zero, depending on the format,
|
||||
and gives a warning to that effect on standard error.
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1993-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
|
||||
Executable
+290
@@ -0,0 +1,290 @@
|
||||
/* A N I M _ O R I E N T . C
|
||||
*
|
||||
* Convert between different orientation formats. The formats are:
|
||||
* quaternion, yaw-pitch-roll, azimuth-elevation-twist, xyz angles,
|
||||
* pre-multiplication rotation matrices, and transposed matrices (inverses).
|
||||
* By default, the information is assumed to represent a transformation
|
||||
* which should be an object which initially faces the x-axis, with the
|
||||
* z-axis going up. Alternatively, the information can be interpreted as
|
||||
* transformations which should be applied to an object initially facing the
|
||||
* negative z-axis, with the y-axis going up.
|
||||
* The conversion is done by converting each input form to a matrix,
|
||||
* and then converting that matrix to the desired output form.
|
||||
* Angles may be specified in radians or degrees.
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "machine.h"
|
||||
#include "vmath.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define YPR 0
|
||||
#define XYZ 1
|
||||
#define AET 2
|
||||
#define QUAT 3
|
||||
#define MAT 4
|
||||
|
||||
#define DEGREES 0
|
||||
#define RADIANS 1
|
||||
|
||||
#define ANIM_NORMAL 0
|
||||
#define ANIM_ERROR1 1
|
||||
#define ANIM_ERROR2 2
|
||||
|
||||
#define DTOR M_PI/180.0
|
||||
#define RTOD 180.0/M_PI
|
||||
|
||||
int parse_args();
|
||||
extern void anim_y_p_r2mat();
|
||||
extern void anim_tran();
|
||||
extern void anim_v_unpermute();
|
||||
extern void anim_dirn2mat();
|
||||
extern void anim_v_permute();
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
int upright;
|
||||
int input_mode, output_mode, length, input_units, output_units;
|
||||
int input_perm, output_perm, input_inv, output_inv;
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int num_read;
|
||||
fastf_t temp[3], temp2[3],angle[3],quat[4],matrix[16];
|
||||
void anim_zyx2mat(),anim_ypr2mat(),anim_quat2mat(), anim_mat_print();
|
||||
int anim_mat2ypr(),anim_mat2zyx(),anim_mat2quat();
|
||||
|
||||
if(!parse_args(argc,argv)) {
|
||||
fprintf(stderr,"Get_args error.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* read data */
|
||||
num_read = length;
|
||||
while (1){
|
||||
|
||||
switch (input_mode) {
|
||||
case YPR:
|
||||
case XYZ:
|
||||
case AET:
|
||||
num_read = scanf("%lf %lf %lf",angle,angle+1,angle+2);
|
||||
/* convert to radians if in degrees */
|
||||
if (input_units==DEGREES) {
|
||||
VSCALE(angle,angle,DTOR);
|
||||
}
|
||||
break;
|
||||
case QUAT:
|
||||
num_read = scanf("%lf %lf %lf %lf", quat,quat+1,quat+2,quat+3);
|
||||
break;
|
||||
case MAT:
|
||||
num_read = 0;
|
||||
num_read += scanf("%lf %lf %lf %lf",matrix,matrix+1,matrix+2,matrix+3);
|
||||
num_read += scanf("%lf %lf %lf %lf",matrix+4,matrix+5,matrix+6,matrix+7);
|
||||
num_read += scanf("%lf %lf %lf %lf",matrix+8,matrix+9,matrix+10,matrix+11);
|
||||
num_read += scanf("%lf %lf %lf %lf",matrix+12,matrix+13,matrix+14,matrix+15);
|
||||
break;
|
||||
}
|
||||
|
||||
if (num_read < length)
|
||||
break;
|
||||
|
||||
/* convert to (object) matrix form */
|
||||
switch (input_mode) {
|
||||
case YPR:
|
||||
anim_ypr2mat(matrix,angle);
|
||||
break;
|
||||
case AET:
|
||||
anim_y_p_r2mat(matrix, angle[0]+M_PI, -angle[1],-angle[2]);
|
||||
break;
|
||||
case XYZ:
|
||||
anim_zyx2mat(matrix,angle);
|
||||
break;
|
||||
case QUAT:
|
||||
anim_quat2mat(matrix,quat);
|
||||
break;
|
||||
}
|
||||
|
||||
if (input_inv){
|
||||
anim_tran(matrix);
|
||||
}
|
||||
if (input_perm){
|
||||
anim_v_unpermute(matrix);
|
||||
}
|
||||
/* end of input conversion, begin output conversion*/
|
||||
|
||||
if (upright) { /* force right-side up */
|
||||
VSET(temp, matrix[0], matrix[4], matrix[8]);
|
||||
VSET(temp2, matrix[1], matrix[5], matrix[9]);
|
||||
anim_dirn2mat(matrix,temp,temp2);
|
||||
}
|
||||
if (output_perm){
|
||||
anim_v_permute(matrix);
|
||||
}
|
||||
if (output_inv){
|
||||
anim_tran(matrix);
|
||||
}
|
||||
|
||||
/* convert from matrix form and print result*/
|
||||
switch (output_mode) {
|
||||
case YPR:
|
||||
anim_mat2ypr(angle,matrix);
|
||||
if (output_units==DEGREES)
|
||||
VSCALE(angle,angle,RTOD);
|
||||
printf("%.12g\t%.12g\t%.12g\n",angle[0],angle[1],angle[2]);
|
||||
break;
|
||||
case AET:
|
||||
anim_mat2ypr(angle,matrix);
|
||||
if (angle[0] > 0.0) {
|
||||
angle[0] -= M_PI;
|
||||
} else {
|
||||
angle[0] += M_PI;
|
||||
}
|
||||
angle[1] = -angle[1];
|
||||
angle[2] = -angle[2];
|
||||
if (output_units==DEGREES)
|
||||
VSCALE(angle,angle,RTOD);
|
||||
printf("%.12g\t%.12g\t%.12g\n",angle[0],angle[1],angle[2]);
|
||||
break;
|
||||
case XYZ:
|
||||
anim_mat2zyx(angle,matrix);
|
||||
if (output_units==DEGREES)
|
||||
VSCALE(angle,angle,RTOD);
|
||||
printf("%.12g\t%.12g\t%.12g\n",angle[0],angle[1],angle[2]);
|
||||
break;
|
||||
case QUAT:
|
||||
anim_mat2quat(quat,matrix);
|
||||
printf("%.12g\t%.12g\t%.12g\t%.12g\n",quat[0],quat[1],quat[2],quat[3]);
|
||||
break;
|
||||
case MAT:
|
||||
anim_mat_print(stdout,matrix,0);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
int parse_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
char *cp;
|
||||
|
||||
/* defaults */
|
||||
upright = 0;
|
||||
input_mode = QUAT;
|
||||
output_mode = QUAT;
|
||||
input_units = DEGREES;
|
||||
output_units = DEGREES;
|
||||
input_perm = 0;
|
||||
output_perm = 0;
|
||||
input_inv = 0;
|
||||
output_inv = 0;
|
||||
length = 4;
|
||||
|
||||
if (argc > 2) { /*read output mode */
|
||||
cp = argv[2];
|
||||
while ( (c=*cp++) ) {
|
||||
switch (c) {
|
||||
case 'q':
|
||||
output_mode = QUAT;
|
||||
break;
|
||||
case 'y':
|
||||
output_mode = YPR;
|
||||
break;
|
||||
case 'a':
|
||||
output_mode = AET;
|
||||
break;
|
||||
case 'z':
|
||||
output_mode = XYZ;
|
||||
break;
|
||||
case 'm':
|
||||
output_mode = MAT;
|
||||
break;
|
||||
case 'i':
|
||||
output_inv = 1;
|
||||
break;
|
||||
case 'r':
|
||||
output_units = RADIANS;
|
||||
break;
|
||||
case 'v':
|
||||
output_perm = 1;
|
||||
break;
|
||||
case 'u':
|
||||
upright = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"anim_orient: unknown output option: %c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (argc > 1) { /*read input mode */
|
||||
cp = argv[1];
|
||||
while ( (c=*cp++) ) {
|
||||
switch (c) {
|
||||
case 'q':
|
||||
input_mode = QUAT;
|
||||
length = 4;
|
||||
break;
|
||||
case 'y':
|
||||
input_mode = YPR;
|
||||
length = 3;
|
||||
break;
|
||||
case 'a':
|
||||
input_mode = AET;
|
||||
length = 3;
|
||||
break;
|
||||
case 'z':
|
||||
input_mode = XYZ;
|
||||
length = 3;
|
||||
break;
|
||||
case 'm':
|
||||
input_mode = MAT;
|
||||
length = 16;
|
||||
break;
|
||||
case 'i':
|
||||
input_inv = 1;
|
||||
break;
|
||||
case 'r':
|
||||
input_units = RADIANS;
|
||||
break;
|
||||
case 'v':
|
||||
input_perm = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"anim_orient: unknown input option: %c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
Executable
+339
@@ -0,0 +1,339 @@
|
||||
.TH ANIM_SCRIPT 1 BRL/CAD
|
||||
.SH NAME
|
||||
anim_script - make an animation script for one object
|
||||
.SH SYNOPSIS
|
||||
.B anim_script
|
||||
.B [-v #]
|
||||
.B [-r|t|s]
|
||||
.B [-q][-p]
|
||||
.B [-a|b # # #]
|
||||
.B [-c|d # # #]
|
||||
.B [-f #]
|
||||
.B [-m cmd]
|
||||
.B [objectname]
|
||||
.B < in.table
|
||||
.B > out.script
|
||||
.SH DESCRIPTION
|
||||
.I Anim_script
|
||||
is designed to produce an animation script for the
|
||||
animation of the virtual camera or one
|
||||
.I brlcad
|
||||
object at a time. It is
|
||||
complementary to
|
||||
.I tabsub
|
||||
in that it performs a similar
|
||||
function, but with a different philosophy.
|
||||
.PP
|
||||
Both
|
||||
.I anim_script
|
||||
and
|
||||
.I tabsub
|
||||
use one row of an animation table to
|
||||
produce one frame of an animation script. With
|
||||
.I tabsub,
|
||||
the user supplies
|
||||
a template file which controls the form of the animation frames. This
|
||||
allows the maximum user control, but also requires a good understanding
|
||||
of the script format. With
|
||||
.I anim_script,
|
||||
the user supplies all the necessary
|
||||
information on the command line. The range of possible output scripts is
|
||||
limited, but the user does not have to deal directly with the details.
|
||||
Both routines have special features which make certain common situations
|
||||
easy to do. One of the most important special features of
|
||||
.I anim_script
|
||||
is the
|
||||
ability to specify a reference position and orientation, as explained
|
||||
below.
|
||||
.PP
|
||||
The objectname is the name of the object which is to be
|
||||
animated, as it will appear in the ouput script. For example, if
|
||||
"hatch1"
|
||||
is a member of "turret" which is a member of "tank" which is one of the
|
||||
objects specified on the command line of the call to
|
||||
.I rt,
|
||||
then the objectname "tank/turret/hatch1" or simply "turret/hatch1" would be used to
|
||||
animate the hatch. The tank itself would be referred to by the name,
|
||||
"/tank". Note that toplevel objects should be preceeded by a slash.
|
||||
If view animation is being performed, no objectname
|
||||
should be included.
|
||||
.PP
|
||||
.B in.table
|
||||
should be a seven-column animation table,
|
||||
specifying the time, 3d position, yaw, pitch and roll of the
|
||||
object (or camera), although this changes if the
|
||||
.BR -r ,
|
||||
.BR -t ,
|
||||
.BR -s ,
|
||||
or
|
||||
.B -v#
|
||||
options are used.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-r
|
||||
.B in.table
|
||||
is a four-column file including time and rotation
|
||||
information only. No translation will occur.
|
||||
.TP
|
||||
.B \-t
|
||||
.B in.table
|
||||
is a four-column file including time and translation
|
||||
information only. No rotation will occur.
|
||||
.TP
|
||||
.B \-s
|
||||
.B in.table
|
||||
is a four-column file including time and translation
|
||||
information only. The vehicle will be rotated (steered) to face the
|
||||
direction of motion.
|
||||
.TP
|
||||
.B \-q
|
||||
Quaternion orientation. Any orientation information in
|
||||
.B in.table
|
||||
will be in quaternion form, in the order x,y,z,w. The identity quaternion
|
||||
representing no orientation change is (0,0,0,1).
|
||||
.TP
|
||||
.B \-p
|
||||
Permuted orientation. This option indicates that transformations defined by
|
||||
the quaternions should be applied to an object which has first been placed
|
||||
in
|
||||
.IR rt 's
|
||||
default eye orientation. Thus, the identity quaternion represents yawing the
|
||||
object 90 degrees to the left and then pitching it 90 degrees downward.
|
||||
The quaternions produced by
|
||||
.IR mged 's
|
||||
saveview command and used by
|
||||
.IR rt 's
|
||||
orientation command
|
||||
are quaternions of this type. See
|
||||
.I anim_orient
|
||||
for more information.
|
||||
.TP
|
||||
.B \-v#
|
||||
The desired output is a view animation script, rather
|
||||
than an object animation script. No object should be specified. The
|
||||
argument can be any floating point number. If
|
||||
the argument
|
||||
is positive, the command:
|
||||
.sp
|
||||
viewsize #;
|
||||
.sp
|
||||
will be placed at the beginning of the ouput file. If it is
|
||||
zero, the `viewsize' command is omitted from the output script. If it is
|
||||
negative, then the
|
||||
viewsize for each frame is expected to be in the first column after the
|
||||
time in
|
||||
.BR in.table .
|
||||
A `viewsize' command would then be
|
||||
included immediately after the `start' command of each frame.
|
||||
.TP
|
||||
.B \-f#
|
||||
Specify the integer with which to begin
|
||||
numbering the frames of the output script. The default is 0.
|
||||
.PP
|
||||
The remaining options give information about the object which is
|
||||
to be animated.
|
||||
.TP
|
||||
.B \-a # # #
|
||||
or
|
||||
.TP
|
||||
.B \-b # # #
|
||||
These options take three arguments, which are the
|
||||
yaw, pitch, and roll of the object's axes with respect to the
|
||||
world axes. With
|
||||
.B \-a,
|
||||
rotations specified in the infile will be applied
|
||||
with respect to the object's axes. With the
|
||||
.B \-b
|
||||
option, the object is
|
||||
rotated so that its axes coincide with the world axes, and then all
|
||||
rotations and translations are carried out with respect to the world
|
||||
axes. The
|
||||
.B \-b
|
||||
option is particularly useful in conjunction with the
|
||||
.B \-s
|
||||
option, because it tells
|
||||
.I anim_script
|
||||
which way the front of the vehicle faces. See
|
||||
the examples below.
|
||||
.TP
|
||||
.B \-c # # #
|
||||
or
|
||||
.TP
|
||||
.B \-d # # #
|
||||
These options take three arguments, which are the x, y,
|
||||
and z coordinates of the point which is to be considered the "centroid"
|
||||
of the object. All rotations will occur about this point. If
|
||||
.B \-c
|
||||
is used,
|
||||
translations from the input table will be considered to be relative
|
||||
displacements from this point. If
|
||||
.B \-d
|
||||
is used, the translations in the
|
||||
input table will be interpreted as absolute displacement from the world
|
||||
origin. The direction of translation in both cases is along the world
|
||||
axes, unless the
|
||||
.B \-a
|
||||
option has been used, in which case the
|
||||
translations are with respect to the object's axes. See the examples below.
|
||||
.PP
|
||||
When the
|
||||
.B \-v
|
||||
option is used, the virtual camera is the object
|
||||
being animated, and so the meaning of the preceeding four options
|
||||
changes somewhat. The
|
||||
.B \-c
|
||||
and
|
||||
.B \-a
|
||||
options are not useful in this context.
|
||||
The
|
||||
.B \-d
|
||||
option can be thought of as specifying the position and
|
||||
orientation of a virtual
|
||||
tripod with respect to the camera lens. The translations and rotations
|
||||
specified in
|
||||
the input table will be applied to the tripod, to which the camera is
|
||||
rigidly attached. For example, the option
|
||||
.B \-d 10 0 \-2
|
||||
in conjunction with
|
||||
the
|
||||
.B \-v#
|
||||
option means that the virtual tripod is 10 units in front of the
|
||||
camera and 2
|
||||
units below the camera's line of sight. The option
|
||||
.B \-b -90 0 0
|
||||
in this
|
||||
context would mean that the front of the virtual tripod faces 90 degrees
|
||||
to the right of the virtual camera. As translation and rotation
|
||||
information are read in from in.table, they are applied to the virtual
|
||||
tripod, with the virtual camera rigidly attached. See below for examples
|
||||
of how this might be used.
|
||||
.TP
|
||||
.B -m cmd
|
||||
Specify a matrix command to use in, object animation. The default value
|
||||
is "lmul", which means that matrices in the output script are
|
||||
multiplied onto the
|
||||
left of the matrix between the object being animated and its parent.
|
||||
The matrix residing between the object and its parent is referred to as
|
||||
the current arc. The possible matrix commands are the following:
|
||||
.nf
|
||||
|
||||
lmul - left-multiply the matrix onto the current arc
|
||||
rmul - right-multiply the matrix onto the current arc
|
||||
rarc - replace the current arc with the matrix
|
||||
rstack - replace the stack of ancestor matrices with the matrix
|
||||
rboth - replace the current arc with the matrix and replace the
|
||||
stack of ancestor matrices with the identity matrix.
|
||||
|
||||
.fi
|
||||
This option is intended primarily to give expert users additional
|
||||
flexibility, and shouldn't be needed by most animators.
|
||||
.SH EXAMPLES
|
||||
To animate a truck which is modeled with the front facing the positive
|
||||
x-direction, the position of the center of the truck and its orientation at
|
||||
each time should be in
|
||||
.BR truck.table .
|
||||
If the center of the modeled truck is at
|
||||
the point (234,0,1200) then the following command could be used:
|
||||
.sp
|
||||
anim_script -d 234 0 1200 /truck < truck.table > truck.script.
|
||||
.sp
|
||||
If the front of the model truck faces (for some reason)
|
||||
halfway
|
||||
between the x and y axes, a
|
||||
.B \-b
|
||||
option is added, to show the relationship
|
||||
between world and truck axes:
|
||||
.sp
|
||||
anim_script -b 45 0 0 -d 234 0 1200 /truck < truck.table > truck.script.
|
||||
.sp
|
||||
To steer the truck automatically to face the direction of motion,
|
||||
the
|
||||
.B \-s
|
||||
option is added, and the orientation columns should be removed from
|
||||
.BR truck.table .
|
||||
.sp
|
||||
anim_script -s -b 45 0 0 -d 234 0 1200 /truck < truck.table > truck.script.
|
||||
.sp
|
||||
.sp
|
||||
Animating a steering wheel: Suppose the steering wheel is stored
|
||||
in the database so that the axis it turns on is at an yaw of -135
|
||||
degrees and an pitch of 30 degrees. It passes through the point
|
||||
(700,800,2400). Then we select "rotation only" with
|
||||
.B \-r
|
||||
and specify the
|
||||
relationship between the steering wheels axes and the world with the
|
||||
.B \-a
|
||||
and
|
||||
.B \-c
|
||||
options. In
|
||||
.B roll.table
|
||||
we put the time, two zero columns, and a
|
||||
column specifying the roll of the wheel (How much it is to be twisted).
|
||||
.sp
|
||||
anim_script -r -a -135 30 0 -c 700 800 2400 truck/steering_column/wheel <
|
||||
roll.table > steer.table
|
||||
.sp
|
||||
Alternativly, if the turning of the wheel was stored in the yaw
|
||||
(second) column of a file,
|
||||
.BR turn.table ,
|
||||
a different set of axes would be
|
||||
used to achieve the same effect:
|
||||
.sp
|
||||
anim_script -r -a 45 60 0 -c 700 800 2400 truck/steering_column/wheel <
|
||||
turn.table > steer.table
|
||||
.sp
|
||||
.PP
|
||||
To animate seven little men doing simultaneous backflips in different
|
||||
places, you would want to use relative motion. That is, a translation
|
||||
vector of (0,0,1) means move one unit upward, instead of move to the
|
||||
point (0,0,1). For each little man, we specify his position in the
|
||||
model using the
|
||||
.B \-c
|
||||
option. Then we can use the same backflip instuctions
|
||||
for each of the little men.
|
||||
.sp
|
||||
anim_script -c 12 34 5 /little.man.one < generic.backflip.table >
|
||||
little.man.one.script
|
||||
.sp
|
||||
anim_script -c -3 13 5 /little.man.two < generic.backflip.table >
|
||||
little.man.two.script
|
||||
.sp
|
||||
and so on.
|
||||
.sp
|
||||
.sp
|
||||
.SS Camera examples
|
||||
If we know the desired postion of the camera and its orientation
|
||||
at each time, it's very simple. The
|
||||
.B -v#
|
||||
option indicates that the view is
|
||||
being animated; no object is specified.
|
||||
.sp
|
||||
anim_script -v0 < view.table > view.script
|
||||
.sp
|
||||
To follow a truck, so that the camera is always ten units behind and 4
|
||||
units above it, we specify a virtual tripod in front of and below the
|
||||
camera:
|
||||
.sp
|
||||
anim_script -v0 -d 10 0 -4 < truck.table > view.script
|
||||
.sp
|
||||
To do the same thing but with the camera turned to look at the right
|
||||
side of the truck, we specify that the virtual tripod originally faces
|
||||
to the right, so that the camera faces its right side. Thus when the
|
||||
virtual tripod is placed in the same position and orientation as the
|
||||
truck, the camera will be looking at the right side of the
|
||||
truck.
|
||||
.sp
|
||||
anim_script -v0 -d 10 0 -4 -b -90 0 0 < truck.table > view.script
|
||||
.SH BUGS
|
||||
The reading of command line options which take more than one
|
||||
argument are somewhat finicky. For example, it understands the
|
||||
option "-d 1 1 1" but not "-d1 1 1".
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1993-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
|
||||
Executable
+272
@@ -0,0 +1,272 @@
|
||||
/* A N I M _ S C R I P T . C
|
||||
*
|
||||
* Turn an animation table into an animation script suitable for
|
||||
* use by rt. Anim_script.c makes a script for one object at a time (or the
|
||||
* virtual camera). Some of the available options include rotation
|
||||
* only, translation only, automatic steering, and specifying reference
|
||||
* coordinates.
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#ifdef USE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "machine.h"
|
||||
#include "vmath.h"
|
||||
#include "bu.h"
|
||||
#include "bn.h"
|
||||
#include "anim.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
int get_args();
|
||||
extern int anim_steer_mat();
|
||||
extern void anim_quat2mat();
|
||||
extern void anim_v_unpermute();
|
||||
extern void anim_mat_print();
|
||||
|
||||
extern int bu_optind;
|
||||
extern char *bu_optarg;
|
||||
|
||||
/* info from command line args */
|
||||
int relative_a, relative_c, axes, translate, quaternion, rotate;/*flags*/
|
||||
int steer, view, readview, permute; /* flags*/
|
||||
int first_frame;
|
||||
fastf_t viewsize;
|
||||
vect_t centroid, rcentroid, front;
|
||||
mat_t m_axes, m_rev_axes; /* rotational analogue of centroid */
|
||||
char mat_cmd[10]; /* default is lmul */
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
void anim_dx_y_z2mat(), anim_add_trans();
|
||||
fastf_t yaw, pitch, roll;
|
||||
vect_t point, zero;
|
||||
quat_t quat;
|
||||
mat_t a, m_x;
|
||||
int val, go, frame, last_steer;
|
||||
|
||||
frame=last_steer=go=view=relative_a=relative_c=axes=0;
|
||||
VSETALL(centroid,0);
|
||||
VSETALL(rcentroid,0);
|
||||
VSETALL(front,0);
|
||||
VSETALL(point,0);
|
||||
VSETALL(zero,0);
|
||||
yaw = pitch = roll = 0.0;
|
||||
MAT_IDN(m_axes);
|
||||
MAT_IDN(m_rev_axes);
|
||||
MAT_IDN(a);
|
||||
|
||||
|
||||
if (!get_args(argc,argv))
|
||||
fprintf(stderr,"anim_script: Get_args error\n");
|
||||
|
||||
frame = (steer) ? first_frame -1 : first_frame;
|
||||
|
||||
if (view && (viewsize > 0.0))
|
||||
printf("viewsize %.10g;\n", viewsize);
|
||||
|
||||
|
||||
while (1) {
|
||||
/* read one line of table */
|
||||
val = scanf("%*f"); /*ignore time */
|
||||
if (readview)
|
||||
scanf("%lf",&viewsize);
|
||||
if(translate)
|
||||
val=scanf("%lf %lf %lf", point, point+1, point+2);
|
||||
if(rotate&&quaternion){
|
||||
val = scanf("%lf %lf %lf %lf", quat,quat+1,quat+2,quat+3);
|
||||
val -= 1;
|
||||
} else if (rotate) {
|
||||
val=scanf("%lf %lf %lf",&yaw,&pitch,&roll);
|
||||
}
|
||||
|
||||
if (val < 3){ /* ie. scanf not completely successful */
|
||||
/* with steering option, must go extra loop after end of file */
|
||||
if (steer && !last_steer)
|
||||
last_steer = 1;
|
||||
else break;
|
||||
}
|
||||
|
||||
/* calculate basic rotation matrix a */
|
||||
if (steer)
|
||||
go = anim_steer_mat(a,point,last_steer); /* warning: point changed by anim_steer_mat */
|
||||
else if (quaternion) {
|
||||
anim_quat2mat(a,quat);
|
||||
go = 1;
|
||||
} else {
|
||||
anim_dx_y_z2mat(a,roll,-pitch,yaw);/* make ypr matrix */
|
||||
go = 1;
|
||||
}
|
||||
|
||||
/* if input orientation (presumably from quaternion) was
|
||||
* designed to manipulate the view, first move the object
|
||||
* to the default object position */
|
||||
if (permute)
|
||||
anim_v_unpermute(a);
|
||||
|
||||
/* make final matrix, including translation etc */
|
||||
if (axes){ /* add pre-rotation from original axes */
|
||||
bn_mat_mul(m_x,a,m_rev_axes);
|
||||
MAT_MOVE(a,m_x);
|
||||
}
|
||||
anim_add_trans(a,point,rcentroid); /* add translation */
|
||||
if (axes && relative_a){ /* add post-rotation back to original axes */
|
||||
bn_mat_mul(m_x,m_axes,a);
|
||||
MAT_MOVE(a,m_x);
|
||||
}
|
||||
if (relative_c)
|
||||
anim_add_trans(a,centroid,zero); /* final translation */
|
||||
|
||||
|
||||
/* print one frame of script */
|
||||
if (go && view){
|
||||
printf("start %d;\n", frame);
|
||||
printf("clean;\n");
|
||||
if (readview)
|
||||
printf("viewsize %.10g;\n", viewsize);
|
||||
printf("eye_pt %.10g %.10g %.10g;\n",a[3],a[7],a[11]);
|
||||
/* implicit anim_v_permute */
|
||||
printf("viewrot %.10g %.10g %.10g 0\n",-a[1],-a[5],-a[9]);
|
||||
printf("%.10g %.10g %.10g 0\n", a[2], a[6], a[10]);
|
||||
printf("%.10g %.10g %.10g 0\n", -a[0], -a[4],-a[8]);
|
||||
printf("0 0 0 1;\n");
|
||||
printf("end;\n");
|
||||
}
|
||||
else if (go){
|
||||
printf("start %d;\n", frame);
|
||||
printf("clean;\n");
|
||||
printf("anim %s matrix %s\n", *(argv+bu_optind), mat_cmd);
|
||||
anim_mat_print(stdout,a,1);
|
||||
printf("end;\n");
|
||||
}
|
||||
frame++;
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#define OPT_STR "a:b:c:d:f:m:pqrstv:"
|
||||
|
||||
int get_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
|
||||
int c, i, yes;
|
||||
double yaw,pch,rll;
|
||||
void anim_dx_y_z2mat(), anim_dz_y_x2mat();
|
||||
rotate = translate = 1; /* defaults */
|
||||
quaternion = permute = 0;
|
||||
strcpy(mat_cmd, "lmul");
|
||||
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
|
||||
i=0;
|
||||
switch(c){
|
||||
case 'a':
|
||||
bu_optind -= 1;
|
||||
sscanf(argv[bu_optind+(i++)],"%lf", &yaw );
|
||||
sscanf(argv[bu_optind+(i++)],"%lf", &pch );
|
||||
sscanf(argv[bu_optind+(i++)],"%lf", &rll );
|
||||
bu_optind += 3;
|
||||
anim_dx_y_z2mat(m_axes, rll, -pch, yaw);
|
||||
anim_dz_y_x2mat(m_rev_axes, -rll, pch, -yaw);
|
||||
axes = 1;
|
||||
relative_a = 1;
|
||||
break;
|
||||
case 'b':
|
||||
bu_optind -= 1;
|
||||
sscanf(argv[bu_optind+(i++)],"%lf", &yaw );
|
||||
sscanf(argv[bu_optind+(i++)],"%lf", &pch );
|
||||
sscanf(argv[bu_optind+(i++)],"%lf", &rll );
|
||||
bu_optind += 3;
|
||||
anim_dx_y_z2mat(m_axes, rll, -pch, yaw);
|
||||
anim_dz_y_x2mat(m_rev_axes, -rll, pch, -yaw);
|
||||
axes = 1;
|
||||
relative_a = 0;
|
||||
break;
|
||||
case 'c':
|
||||
bu_optind -= 1;
|
||||
sscanf(argv[bu_optind+(i++)],"%lf",centroid);
|
||||
sscanf(argv[bu_optind+(i++)],"%lf",centroid+1);
|
||||
sscanf(argv[bu_optind+(i++)],"%lf",centroid+2);
|
||||
bu_optind += 3;
|
||||
VREVERSE(rcentroid,centroid);
|
||||
relative_c = 1;
|
||||
break;
|
||||
case 'd':
|
||||
bu_optind -= 1;
|
||||
sscanf(argv[bu_optind+(i++)],"%lf",centroid);
|
||||
sscanf(argv[bu_optind+(i++)],"%lf",centroid+1);
|
||||
sscanf(argv[bu_optind+(i++)],"%lf",centroid+2);
|
||||
bu_optind += 3;
|
||||
VREVERSE(rcentroid,centroid);
|
||||
relative_c = 0;
|
||||
break;
|
||||
case 'f':
|
||||
sscanf(bu_optarg,"%d",&first_frame);
|
||||
break;
|
||||
case 'm':
|
||||
strncpy(mat_cmd,bu_optarg, 10);
|
||||
break;
|
||||
case 'p':
|
||||
permute = 1;
|
||||
break;
|
||||
case 'q':
|
||||
quaternion = 1;
|
||||
break;
|
||||
case 'r':
|
||||
rotate = 1;
|
||||
translate = 0;
|
||||
break;
|
||||
case 's':
|
||||
steer = 1;
|
||||
relative_a = 0;
|
||||
rotate = 0;
|
||||
translate = 1;
|
||||
break;
|
||||
case 't':
|
||||
translate = 1;
|
||||
rotate = 0;
|
||||
break;
|
||||
case 'v':
|
||||
yes = sscanf(bu_optarg,"%lf",&viewsize);
|
||||
if (!yes) viewsize = 0.0;
|
||||
if (viewsize < 0.0)
|
||||
readview = 1;
|
||||
view = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -%c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
Executable
+143
@@ -0,0 +1,143 @@
|
||||
.TH ANIM_SORT 1 BRL/CAD
|
||||
.SH NAME
|
||||
anim_sort - combine concatenated animation scripts into one script
|
||||
.SH SYNOPSIS
|
||||
.B anim_sort
|
||||
.B [-ic]
|
||||
.B < mixed.script
|
||||
.B > ordered.script
|
||||
.SH DESCRIPTION
|
||||
Note:
|
||||
.I anim_sort
|
||||
has been preempted in release 5.0 by
|
||||
.IR scriptsort ,
|
||||
which sorts scripts much faster.
|
||||
.PP
|
||||
.I Anim_sort
|
||||
allows the user to combine several animation scripts
|
||||
into a single script suitable for input to
|
||||
.IR rt .
|
||||
A convenient way to
|
||||
prepare a complicated animation script is to develop each part
|
||||
separately and then use
|
||||
.I anim_sort
|
||||
to combine the various parts. For
|
||||
example, suppose that
|
||||
.B view.script
|
||||
is an animation script controlling the
|
||||
movement of the virtual camera and the lighting,
|
||||
.B mill.script
|
||||
rotates
|
||||
the blades of a windmill, and
|
||||
.B quixote.script
|
||||
controlls the movement of a
|
||||
knight. These scripts should first be concatenated together:
|
||||
.sp
|
||||
cat view.script mill.script quixote.script > mixed.script
|
||||
.sp
|
||||
Calling
|
||||
.I anim_sort
|
||||
with
|
||||
.B mixed.script
|
||||
on standard input would
|
||||
reorder the commands in
|
||||
.B mixed.script
|
||||
to make a viable script on standard
|
||||
output.
|
||||
.sp
|
||||
Each of the input files to be concatenated is expected to be a
|
||||
viable
|
||||
.I rt
|
||||
animation script, containing a series of frames of the
|
||||
following form:
|
||||
.sp
|
||||
.nf
|
||||
start framenumber;
|
||||
any number of semi-colon terminated commands for rt;
|
||||
end;
|
||||
any number of post-raytracing commands
|
||||
.fi
|
||||
.sp
|
||||
.I Anim_sort
|
||||
reads the framenumber of the first start command, and uses
|
||||
this to as the first frame number of the output file. The commands of
|
||||
all frames in
|
||||
.B mixed.script
|
||||
with that framenumber are combined in the
|
||||
ouput frame. The post-raytracing commands following all frames with that
|
||||
framenumber are placed after the
|
||||
.B end;
|
||||
command of the output frame. This process is continued for each
|
||||
successive integer,
|
||||
until anim_sort reaches a framenumber which is not included in any of
|
||||
the original scripts.
|
||||
.sp
|
||||
For example, if
|
||||
.B view.script
|
||||
contained frames numbered from 5 to
|
||||
20,
|
||||
.B mill.script
|
||||
contained frames from 0 to 10, and
|
||||
.B quixote.script
|
||||
contained frames numbered from 15 to 25, the output script would start
|
||||
at frame 5 (since
|
||||
.B view.script
|
||||
comes first in
|
||||
.B mixed.script
|
||||
) and end with
|
||||
frame 25 (since frames 5 through 25 can be found somewhere in
|
||||
.B mixed.script
|
||||
). If the user wanted to include frames 0 through 4, which
|
||||
are found only in
|
||||
.B mill.script
|
||||
, then
|
||||
.B mill.script
|
||||
should be concatenated
|
||||
onto the beginning of
|
||||
.B mixed.script
|
||||
instead of the middle. In the
|
||||
majority of animation situations, all of the input scripts would have
|
||||
identical frame numbers anyway.
|
||||
.sp
|
||||
The first input script may also contain some lines preceeding
|
||||
the first start command, which are copied to the beginning of the output
|
||||
script. This is useful for commands such as 'viewsize', which are often
|
||||
specified before the sequence of animations begins.
|
||||
.sp
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-i
|
||||
Incremental mode. The frames of the output script are printed in a scrambled
|
||||
order which incrementally increases the time resolution of the animation.
|
||||
For example, the frames of an eight-frame script would be printed in the
|
||||
order: 0 4 2 6 1 3 5 7.
|
||||
|
||||
.TP
|
||||
.B \-c
|
||||
For most animation purposes, it is desirable to have a
|
||||
.B clean
|
||||
command immediately following the
|
||||
.B start
|
||||
command of each frame. The
|
||||
default behavior of
|
||||
.I anim_sort
|
||||
is to include one
|
||||
.B clean
|
||||
command following the
|
||||
.B start
|
||||
command of each frame.
|
||||
.B clean
|
||||
commands from the input files are ignored. If the
|
||||
.B -c
|
||||
flag is activated, then no clean
|
||||
commands are printed.
|
||||
.SH SEE ALSO
|
||||
rt(1), tabsub(1), anim_script(1)
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1993-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
Executable
+188
@@ -0,0 +1,188 @@
|
||||
/* A N I M _ S O R T . C
|
||||
*
|
||||
* Combine multiple animation scripts on standard input into a
|
||||
* single script on standard output. The output can be in natural order
|
||||
* or in a scrambled order for incrementally increasing time
|
||||
* resolution (-i option).
|
||||
*
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "machine.h"
|
||||
#include "externs.h"
|
||||
#include "bu.h"
|
||||
|
||||
#define MAXLEN 50 /*maximum length of lines to be read */
|
||||
#define MAXLINES 30 /* maximum length of lines to be stored*/
|
||||
|
||||
int suppressed; /* flag: suppress printing of 'clean;' commands */
|
||||
int incremental; /* flag: order for incremental time resolution */
|
||||
|
||||
int get_args();
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int length,frame_number, number, success, maxnum;
|
||||
int first_frame,spread,reserve;
|
||||
long last_pos;
|
||||
char line[MAXLEN];
|
||||
char pbuffer[MAXLEN*MAXLINES];
|
||||
|
||||
|
||||
if (!get_args(argc,argv))
|
||||
fprintf(stderr,"Get_args error\n");
|
||||
|
||||
/* copy any lines preceeding the first "start" command */
|
||||
last_pos = ftell(stdin);
|
||||
while (fgets(line,MAXLEN,stdin)!=NULL){
|
||||
if (strncmp(line,"start",5)){
|
||||
printf("%s",line);
|
||||
last_pos = ftell(stdin);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* read the frame number of the first "start" command */
|
||||
sscanf( strpbrk(line,"0123456789"),"%d", &frame_number);
|
||||
|
||||
/* find the highest frame number in the file */
|
||||
maxnum = 0;
|
||||
while(fgets(line,MAXLEN,stdin)!=NULL){
|
||||
if(!strncmp(line,"start",5)){
|
||||
sscanf(strpbrk(line,"0123456789"),"%d",&number);
|
||||
maxnum = (maxnum>number)?maxnum:number;
|
||||
}
|
||||
}
|
||||
|
||||
length = maxnum - frame_number + 1;
|
||||
/* spread should initially be the smallest power of two larger than
|
||||
* or equal to length */
|
||||
spread = 2;
|
||||
while (spread < length)
|
||||
spread = spread<<1;
|
||||
|
||||
first_frame = frame_number;
|
||||
success = 1;
|
||||
while (length--){
|
||||
number = -1;
|
||||
success = 0; /* tells whether or not any frames have been found which have the current frame number*/
|
||||
if (incremental){
|
||||
fseek(stdin, 0L, 0);
|
||||
} else {
|
||||
fseek(stdin, last_pos, 0);
|
||||
}
|
||||
|
||||
reserve = MAXLEN*MAXLINES;
|
||||
pbuffer[0] = '\0'; /* delete old pbuffer */
|
||||
|
||||
/* inner loop: search through the entire file for frames */
|
||||
/* which have the current frame number */
|
||||
while (!feof(stdin)){
|
||||
|
||||
/*read to next "start" command*/
|
||||
while (fgets(line,MAXLEN,stdin)!=NULL){
|
||||
if (!strncmp(line,"start",5)){
|
||||
sscanf( strpbrk(line,"0123456789"),"%d", &number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (number==frame_number){
|
||||
if (!success){ /*first successful match*/
|
||||
printf("%s",line);
|
||||
if (!suppressed) printf("clean;\n");
|
||||
success = 1;
|
||||
last_pos = ftell(stdin);
|
||||
}
|
||||
/* print contents until next "end" */
|
||||
while (fgets(line,MAXLEN,stdin)!=NULL){
|
||||
if (!strncmp(line,"end;",4))
|
||||
break;
|
||||
else if (strncmp(line,"clean",5))
|
||||
printf("%s",line);
|
||||
}
|
||||
/* save contents until next "start" */
|
||||
while (fgets(line,MAXLEN,stdin)!=NULL){
|
||||
if(!strncmp(line,"start",5))
|
||||
break;
|
||||
else {
|
||||
reserve -= strlen(line);
|
||||
reserve -= 1;
|
||||
if (reserve > 0){
|
||||
strncat(pbuffer,line,MAXLEN);
|
||||
strcat(pbuffer,"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (success)
|
||||
printf("end;\n");
|
||||
/* print saved-up post-raytracing commands, if any */
|
||||
printf("%s",pbuffer);
|
||||
|
||||
/* get next frame number */
|
||||
if (incremental){
|
||||
frame_number = frame_number + 2*spread;
|
||||
while (frame_number > maxnum){
|
||||
spread = spread>>1;
|
||||
frame_number = first_frame + spread;
|
||||
}
|
||||
} else {
|
||||
frame_number += 1;
|
||||
}
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#define OPT_STR "ci"
|
||||
|
||||
int get_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
|
||||
int c;
|
||||
suppressed = 0;
|
||||
|
||||
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
|
||||
switch(c){
|
||||
case 'c':
|
||||
suppressed = 1;
|
||||
break;
|
||||
case 'i':
|
||||
incremental = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -%c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
.TH ANIM_TIME 1 BRL/CAD
|
||||
.SH NAME
|
||||
anim_time - estimate appropriate time parameters for path
|
||||
.SH SYNOPSIS
|
||||
.B anim_time
|
||||
.B [-s start_speed (absolute)]
|
||||
.B [-e end_speed (absolute)]
|
||||
.B [-i initial_speed (relative)]
|
||||
.B [-f final_speed (relative)]
|
||||
.B [-m max_len]
|
||||
.B [-v|q]
|
||||
.B < in.table
|
||||
.B > out.table
|
||||
.SH DESCRIPTION
|
||||
This filter is designed to estimate appropriate time parameters for
|
||||
an animation curve in 3D space. Given a four-column table specifying
|
||||
time and 3D position for an object,
|
||||
.I anim_time
|
||||
ignores all but the first and last time specifications and
|
||||
calculates reasonable time values for each intermediate point in the table.
|
||||
The
|
||||
output time values are based on the distances between points and the
|
||||
calculated speed of the object. Various options allow the user to
|
||||
control the assumptions on the object's initial and final speeds, and the
|
||||
form of the output.
|
||||
|
||||
.I Anim_time
|
||||
is intended to be used in situations where the user knows what key points
|
||||
an object should pass through and how long the entire motion should take,
|
||||
but doesn't care exactly when the object
|
||||
reaches each point. It is also useful for getting objects to accelerate
|
||||
smoothly to and from rest.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BR -m #
|
||||
Specify the maximum number of points to be read. This default to 64, so
|
||||
you must use this option if you want to use tables with more than 64
|
||||
points.
|
||||
.TP
|
||||
.BR -s #
|
||||
Specify the starting speed of the object. If this option is not
|
||||
specified, then the object is assumed to be initially travelling on a
|
||||
pace to negotiate the entire path in the given time at a constant rate.
|
||||
The argument must be positive and no greater than three times the speed
|
||||
needed to traverse the path at a constant rate.
|
||||
.TP
|
||||
.BR -e #
|
||||
Specify the final speed of the object. If this option is not specified,
|
||||
then the object is assumed to end up travelling on a pace to negotiate
|
||||
the entire path in the given time at a constant rate. The argument must
|
||||
be positive and no greater than three times the speed needed to traverse
|
||||
the path at a constant rate.
|
||||
.TP
|
||||
.BR -i #
|
||||
Specify the initial speed of the object, relative to the speed that
|
||||
would negotiate the given path at a constant rate. For example, an
|
||||
argument of 2.0 means twice the speed needed to traverse the path at a
|
||||
constant rate. Must lie between 0.0 and 3.0.
|
||||
.TP
|
||||
.BR -f #
|
||||
Specify the final speed of the object, relative to the speed that would
|
||||
negotiate the given path at a constant rate. Must lie between 0.0 and
|
||||
3.0.
|
||||
.TP
|
||||
.B -v
|
||||
Verbose option. The output table will contain a time column and three
|
||||
position columns. If this option is not specified, only the new time
|
||||
column will be printed.
|
||||
.TP
|
||||
.B -q
|
||||
Query the total distance. If this option is specified, the only output
|
||||
will be a number representing the total length of the input path.
|
||||
.SH BUGS
|
||||
The algorithm fits a cubic polynomial to the distance vs time graph, and then
|
||||
uses Newton's method to find the times corresponding to each given distance.
|
||||
If for some reason convergence is not reached,
|
||||
.I anim_time
|
||||
will print a warning on standard error. If the
|
||||
.B -d
|
||||
option is specified, the results of each iteration will be printed.
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1996-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
@@ -0,0 +1,287 @@
|
||||
/* A N I M _ T I M E . C
|
||||
*
|
||||
* Given an animation path consiting of time stamps and 3-d points,
|
||||
* estimate new time stamps based on the distances between points, the
|
||||
* given starting and ending times, and optionally specified starting
|
||||
* and ending velocities.
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "machine.h"
|
||||
#include "externs.h"
|
||||
#include "vmath.h"
|
||||
#include "bu.h"
|
||||
#include "raytrace.h"
|
||||
|
||||
extern int bu_optind;
|
||||
extern char *bu_optarg;
|
||||
|
||||
|
||||
#define MAXLEN 64
|
||||
#define DIVIDE_TOL (1.0e-10)
|
||||
#define MAXITS 100
|
||||
#define DELTA (1.0e-6)
|
||||
#define TIME_NONE 0
|
||||
#define TIME_ABSOLUTE 1
|
||||
#define TIME_RELATIVE 2
|
||||
|
||||
/* command line variables */
|
||||
fastf_t inv0,inv1;
|
||||
int v0_set = TIME_NONE;
|
||||
int v1_set = TIME_NONE;
|
||||
int query = 0;
|
||||
int verbose = 0;
|
||||
int maxlines = 0;
|
||||
int domem = 0;
|
||||
int debug = 0;
|
||||
|
||||
int get_args();
|
||||
|
||||
fastf_t
|
||||
gettime(dist, a, b, c, init)
|
||||
fastf_t dist;
|
||||
fastf_t a;
|
||||
fastf_t b;
|
||||
fastf_t c;
|
||||
fastf_t init;
|
||||
{
|
||||
|
||||
fastf_t old,new,temp;
|
||||
int countdown,success;
|
||||
countdown = MAXITS;
|
||||
|
||||
old = init;
|
||||
success = 0;
|
||||
while(countdown-->0){
|
||||
temp = (3.0*a*old+2.0*b)*old+c;
|
||||
if (temp<DIVIDE_TOL){
|
||||
new = 0.75*old;
|
||||
} else {
|
||||
new = old - (((a*old+b)*old+c)*old-dist)/temp;
|
||||
}
|
||||
if (((new-old)<DELTA)&&((old-new)<DELTA)){
|
||||
success = 1;
|
||||
break;
|
||||
}
|
||||
if (debug)
|
||||
printf("c: %d %f\t%f\n",countdown,new,new-old);
|
||||
old = new;
|
||||
}
|
||||
if (!success) fprintf(stderr,"warning - max iterations reached\n");
|
||||
return (new);
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
fastf_t *l, *x, *y, *z;
|
||||
fastf_t temp0,temp1,temp2,start=0.0,end,v0,v1;
|
||||
int i,j , num,plen;
|
||||
|
||||
|
||||
fastf_t time,dist,slope,a,b,c;
|
||||
|
||||
|
||||
plen = 0;
|
||||
|
||||
if (!get_args(argc,argv))
|
||||
fprintf(stderr,"Usage: anim_time [-s#] [-e#] [-d] < in.table\n");
|
||||
|
||||
if (!domem) {
|
||||
maxlines = MAXLEN;
|
||||
}
|
||||
|
||||
l = (fastf_t *) bu_malloc(maxlines*sizeof(fastf_t),"l[]");
|
||||
if (verbose) {
|
||||
x = (fastf_t *) bu_malloc(maxlines*sizeof(fastf_t),"x[]");
|
||||
y = (fastf_t *) bu_malloc(maxlines*sizeof(fastf_t),"y[]");
|
||||
z = (fastf_t *) bu_malloc(maxlines*sizeof(fastf_t),"z[]");
|
||||
} else {
|
||||
x = (fastf_t *) bu_malloc(2*sizeof(fastf_t),"x[]");
|
||||
y = (fastf_t *) bu_malloc(2*sizeof(fastf_t),"y[]");
|
||||
z = (fastf_t *) bu_malloc(2*sizeof(fastf_t),"z[]");
|
||||
}
|
||||
l[0] = 0.0;
|
||||
|
||||
while(plen<maxlines){
|
||||
i = (verbose) ? plen : plen%2;
|
||||
j = (verbose) ? (plen-1) : (plen+1)%2;
|
||||
num = scanf("%lf %lf %lf %lf",&end,x+i,y+i,z+i);
|
||||
if (num<4)
|
||||
break;
|
||||
if(plen){
|
||||
temp0 = x[i]-x[j];
|
||||
temp1 = y[i]-y[j];
|
||||
temp2 = z[i]-z[j];
|
||||
l[plen] = sqrt(temp0*temp0+temp1*temp1+temp2*temp2);
|
||||
l[plen] += l[plen-1];
|
||||
} else {
|
||||
start = end;
|
||||
}
|
||||
|
||||
plen++;
|
||||
}
|
||||
|
||||
time = end - start;
|
||||
dist = l[plen-1];
|
||||
|
||||
if (query){
|
||||
printf("%f\n",dist);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (time < DIVIDE_TOL){
|
||||
fprintf(stderr,"anim_time: time too small. Only %f s.\n",time);
|
||||
exit(-1);
|
||||
}
|
||||
if (dist < DIVIDE_TOL){
|
||||
fprintf(stderr,"anim_time: pathlength too small. Only %f\n",dist);
|
||||
exit(-1);
|
||||
}
|
||||
slope = dist/time;
|
||||
|
||||
switch (v0_set) {
|
||||
case TIME_ABSOLUTE:
|
||||
v0 = inv0;
|
||||
break;
|
||||
case TIME_RELATIVE:
|
||||
v0 = slope*inv0;
|
||||
break;
|
||||
default:
|
||||
case TIME_NONE:
|
||||
v0 = slope;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (v1_set) {
|
||||
case TIME_ABSOLUTE:
|
||||
v1 = inv1;
|
||||
break;
|
||||
case TIME_RELATIVE:
|
||||
v1 = slope*inv1;
|
||||
break;
|
||||
default:
|
||||
case TIME_NONE:
|
||||
v1 = slope;
|
||||
break;
|
||||
}
|
||||
if (v0<0.0) {
|
||||
fprintf(stderr,"anim_time: Start velocity must be non-negative.\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (v1<0.0) {
|
||||
fprintf(stderr,"anim_time: End velocity must be non-negative.\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (v0>3*slope) {
|
||||
fprintf(stderr,"anim_time: Start velocity must be not be greater than %f units/s for this path.\n", 3.0*slope);
|
||||
exit (-1);
|
||||
}
|
||||
if (v1>3*slope) {
|
||||
fprintf(stderr,"anim_time: End velocity must not be greater than %f for this path.\n", 3.0*slope);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
a = ((v1+v0) - 2.0*slope)/(time*time);
|
||||
b = (3*slope - (v1+2.0*v0))/time;
|
||||
c = v0;
|
||||
|
||||
temp2 = 1.0/slope;
|
||||
if (verbose) {
|
||||
printf("%.12e\t%.12e\t%.12e\t%.12e\n",start,x[0],y[0],z[0]);
|
||||
for (i=1; i<plen-1; i++){
|
||||
temp0 = gettime(l[i],a,b,c,l[i]*temp2);
|
||||
printf("%.12e\t%.12e\t%.12e\t%.12e\n",temp0+start,x[i],y[i],z[i]);
|
||||
}
|
||||
printf("%.12e\t%.12e\t%.12e\t%.12e\n",end,x[plen-1],y[plen-1],z[plen-1]);
|
||||
} else {
|
||||
printf("%.12e\n",start);
|
||||
for (i=1; i<plen-1; i++){
|
||||
temp0 = gettime(l[i],a,b,c,l[i]*temp2);
|
||||
printf("%.12e\n",temp0+start);
|
||||
}
|
||||
printf("%.12e\n",end);
|
||||
}
|
||||
|
||||
bu_free((char *) l, "l[]");
|
||||
bu_free((char *) x, "x[]");
|
||||
bu_free((char *) y, "y[]");
|
||||
bu_free((char *) z, "z[]");
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* code to read command line arguments*/
|
||||
#define OPT_STR "ds:e:i:f:qm:v"
|
||||
int get_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
|
||||
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
|
||||
switch(c){
|
||||
case 's':
|
||||
sscanf(bu_optarg,"%lf",&inv0);
|
||||
v0_set = TIME_ABSOLUTE;
|
||||
break;
|
||||
case 'e':
|
||||
sscanf(bu_optarg,"%lf",&inv1);
|
||||
v1_set = TIME_ABSOLUTE;
|
||||
break;
|
||||
case 'i':
|
||||
sscanf(bu_optarg,"%lf",&inv0);
|
||||
v0_set = TIME_RELATIVE;
|
||||
if ((inv0>3.0)||(inv0<0.0)) {
|
||||
fprintf(stderr,"anim_time: -i argument must lie between 0.0 and 3.0\n");
|
||||
exit(-1);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
sscanf(bu_optarg,"%lf",&inv1);
|
||||
v1_set = TIME_RELATIVE;
|
||||
if ((inv1>3.0)||(inv1<0.0)) {
|
||||
fprintf(stderr,"anim_time: -f argument must lie between 0.0 and 3.0\n");
|
||||
exit(-1);
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
query = 1;
|
||||
break;
|
||||
case 'm':
|
||||
sscanf(bu_optarg,"%d",&maxlines);
|
||||
domem = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -%c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
Executable
+435
@@ -0,0 +1,435 @@
|
||||
.TH ANIM_TRACK 1 BRL/CAD
|
||||
.SH NAME
|
||||
anim_track - make an script to model or animate the pads and wheels of a
|
||||
tracked vehicle.
|
||||
.SH SYNOPSIS
|
||||
.B
|
||||
anim_track [options] wheelfile < in.table > out.script
|
||||
.SH DESCRIPTION
|
||||
.I anim_track
|
||||
is designed to produce an animation script for the
|
||||
animation of the track pads and/or the wheels which define the track.
|
||||
Alternatively, track can output a file which produces a track model
|
||||
when sourced by mged.
|
||||
.PP
|
||||
A track consists of a number of identical pads which
|
||||
are wrapped in a chain around two or more ordered wheels. Normally, the
|
||||
track is linear between the wheels. The exeption is that between the
|
||||
first and last wheels, any extra track length is taken up in a hanging
|
||||
caternary arc.
|
||||
.PP
|
||||
Anim_track requires two input files. The first, referred to above as
|
||||
.BR wheelfile ,
|
||||
is a table which
|
||||
defines the initial track geometry by describing the wheels around which
|
||||
the track is to be wrapped. The first three columns of the table give
|
||||
the center point of the wheels, and the fourth column gives the radius
|
||||
of each wheel. The table contains one line for each wheel; the
|
||||
wheels should be listed in clockwise order as viewed from the right of
|
||||
the vehicle. This is the direction that the track pads move around the
|
||||
wheels when the vehicle is moving forward.
|
||||
.PP
|
||||
The track is part of a vehicle which has a front, back, left, right, up,
|
||||
and down. By default these directions are +x, -x, +y, -y, +z, and -z,
|
||||
respectively, but any orientation can be specified by the user with the
|
||||
.B -b
|
||||
option.
|
||||
The track is always confined to a plane which has no left to right
|
||||
variation; that is, the wheels can be in front of, behind, above, and
|
||||
below each other, but may not be to the left or right of each other. If
|
||||
the wheel positions specified in
|
||||
.B wheelfile
|
||||
do not lie in such a plane, then the first wheel defines the plane into
|
||||
which all of the other wheels are projected.
|
||||
.PP
|
||||
The track pads are spread evenly along the entire length of the track.
|
||||
The track segments between wheels are always linear, except for the
|
||||
segment between the first and last wheels. If there is any extra track
|
||||
length, it is taken up in a caternary arc which hangs down between the
|
||||
first and last wheels. Thus if the the first wheel in
|
||||
.B wheelfile
|
||||
should be the top front wheel of the vehicle, and the last wheel in
|
||||
.B wheelfile
|
||||
should be the top back wheel of the vehicle. Depending on the track
|
||||
length mode specified with the
|
||||
.B -l
|
||||
option, the caternary segment may or may not appear.
|
||||
.PP
|
||||
The second input file required by
|
||||
.IR anim_track ,
|
||||
referred to above as
|
||||
.BR in.table ,
|
||||
describes the state of the track in every frame of the animation. The
|
||||
format of this second file can vary greatly according to the command-line
|
||||
options. The first column of the file is ignored, but is expected to
|
||||
contain the time values corresponding to each frame. Next come one or
|
||||
more columns which specify directly or indirectly the distance that the
|
||||
track has rolled around the wheels in each frame (see the
|
||||
.BR -u ,
|
||||
.BR -y ,
|
||||
and
|
||||
.B -s
|
||||
options). Finally, the file may specify new wheel position for every
|
||||
frame (see the
|
||||
.B -v
|
||||
option).
|
||||
.PP
|
||||
.SH MODEL REQUIREMENTS
|
||||
Certain model conventions are needed in order for the animation to work
|
||||
properly. First of all, if the wheels are to be animated, they must
|
||||
all be named
|
||||
.IR wheelname . i ,
|
||||
where
|
||||
.I i
|
||||
ranges from 0 to one less than the number of wheels.
|
||||
.I wheelname
|
||||
is an arbitrary string.
|
||||
.IR wheelname 0
|
||||
must be
|
||||
the top front wheel in a given track and
|
||||
.IR wheelname (n-1)
|
||||
must be the top
|
||||
back wheel. The central axes of all the wheels should be parallel to
|
||||
each other and perpendicular to a plane containing all of the wheel
|
||||
centers.
|
||||
.PP
|
||||
The pads of the track should be identical instances or copies of a
|
||||
prototype pad object, and they all should be named
|
||||
.IR padname i,
|
||||
where
|
||||
.I i
|
||||
ranges from 0 to one less than the number of pads.
|
||||
The prototype pad should be centered on the origin in the x and y
|
||||
directions. In the z direction, the inner, wheel-contacting surface of
|
||||
the pad should lie on the z=0 plane. The outer, ground-contacting
|
||||
surface should face the positive z-direction. The side of the pad which
|
||||
would connect with the pad in front of it should face the positive x
|
||||
direction, and the side which would connect with the pad behind it
|
||||
should face the negative x direction. If the pads are a part of a higher
|
||||
level combination, as they typically are, then the matrix between each
|
||||
pad and the higher combination may be modified at will as long as the
|
||||
prototype pad is not disturbed.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -p num_pads parent/basename
|
||||
Animate the track pads. This option takes two arguments; the number of
|
||||
pads in the track and a slash-separated path to the pad basename.
|
||||
For
|
||||
example, if there is a combination named "lpads" containing 80 track
|
||||
pads with names ranging from "pad.0" to "pad.79", then the correct
|
||||
arguments would be:
|
||||
.sp
|
||||
.B -p 79 lpads/pad.
|
||||
.sp
|
||||
Each frame of the output animation script will contain an animation
|
||||
command for each of the track pads.
|
||||
.TP
|
||||
.B -w parent/basename
|
||||
Animate the track wheels. This option takes one argument: a
|
||||
slash-separated path to the wheel basename. The number of wheels is
|
||||
obtained from the number of lines in the
|
||||
.BR wheelfile .
|
||||
If there is, for example, a combination named "rwheels" containing 4
|
||||
wheels named wheel_0, wheel_1, wheel_2, and wheel_3, then the correct
|
||||
argument is:
|
||||
.sp
|
||||
.B -w rwheels/wheel_
|
||||
.sp
|
||||
Each frame of the output animation script will contain an animation
|
||||
command for each of the wheels.
|
||||
.TP
|
||||
.B \-b # # #
|
||||
Specify the yaw, pitch, and roll of the vehicle's axes
|
||||
with respect to the world axes. By default, the vehicle is assumed to
|
||||
have a yaw, pitch, and roll of 0, and the track is therefore put into a
|
||||
xz plane.
|
||||
.TP
|
||||
.B \-d # # #
|
||||
Specify (in world coordinates) the centroid of the vehicle
|
||||
of which the track is a part. By default, the vehicle is assumed
|
||||
centered at the origin.
|
||||
.TP
|
||||
.B -u
|
||||
User-specified track distance. The user
|
||||
should provide, in the second column of
|
||||
.IR in.table ,
|
||||
the distance that the track should be rolled around the wheels in each
|
||||
frame. This is the default.
|
||||
.TP
|
||||
.B -y
|
||||
Derive the track distance from a table of position, yaw, pitch, and
|
||||
roll. The second column through the seventh columns of the
|
||||
.I in.table
|
||||
should contain the position and orientation of the vehicle in every
|
||||
frame. The distance that the track should be rolled around the wheels is
|
||||
automatically calculated in every frame. If
|
||||
.I anim_script
|
||||
is being used with the same table to create the animaion script for the
|
||||
vehicle itself, the
|
||||
.B -b
|
||||
and
|
||||
.B -d
|
||||
options to
|
||||
.I anim_script
|
||||
and
|
||||
.I anim_track
|
||||
should be the same.
|
||||
.TP
|
||||
.B -s
|
||||
Derive the track distance from a table of positions, using automatic
|
||||
steering. The second column through the fourth column of the
|
||||
.I in.table
|
||||
should contain the position of the vehicle in every frame. The distance
|
||||
that the track should be rolled around the wheels is automatically
|
||||
calculated in every frame, based on the assumption that the vehicle is
|
||||
always steered to face the direction of motion.
|
||||
If
|
||||
.I anim_script
|
||||
is being used with the same table to create the animaion script for the
|
||||
vehicle itself, the
|
||||
.B -b
|
||||
and
|
||||
.B -d
|
||||
options to
|
||||
.I anim_script
|
||||
and
|
||||
.I anim_track
|
||||
should be the same.
|
||||
.TP
|
||||
.B -a
|
||||
Enable anti-strobing measures. When the track is rolling fast enough, track
|
||||
animations exhibit a strobing effect which may make the track appear to
|
||||
slow down or rotate backwards. This is an artifact of the discrete time
|
||||
nature of the animations, and occurs when the distance traveled by the
|
||||
track in one frame is close to the pad length. If the
|
||||
.B -a
|
||||
option is selected,
|
||||
.I anim_track
|
||||
adds random jitter to the track's motion when the track speed is high
|
||||
enough to cause strobing. This causes a motion blur effect rather than
|
||||
strobing.
|
||||
.TP
|
||||
.B -v
|
||||
Specify new wheel positions in every frame. This option allows dynamic
|
||||
suspensions to be animated. If there are n wheels, then the last 2n
|
||||
columns of
|
||||
.I in.table
|
||||
should contain the front-back and up-down coordinates of each wheel,
|
||||
relative to the vehicle center and orientation specified with
|
||||
.B -d
|
||||
and
|
||||
.BR -b .
|
||||
The columns should be in pairs: The front-back coordinate of the first
|
||||
wheel, followed by its up-down coordinate, followed by the front-back
|
||||
coordinate of the second wheel, and so on.
|
||||
.sp
|
||||
If this option is not specified, then the wheel positions are fixed
|
||||
throughout the animation.
|
||||
.TP
|
||||
.B -c
|
||||
Calculate the track circumference, that is, the length of the shortest
|
||||
track that can wrap around a given set of wheels. If the -v option is
|
||||
specified, then
|
||||
the output is a table containing the frame number and the track
|
||||
circumference in each frame. Otherwise, a single value representing the
|
||||
constant track circumference is returned.
|
||||
.TP
|
||||
.B -lm
|
||||
Minimize the track length. With this option the length of the track is
|
||||
set to the track circumference in every frame, ie the track shrinks to
|
||||
fit the wheels.
|
||||
.TP
|
||||
.B -lf #
|
||||
Specify a fixed track length. The argument specifies the track length, which
|
||||
remains constant throughout the animation. If at any time the track
|
||||
circumference exceeds the track length, the program is aborted and a
|
||||
message is printed on standard error.
|
||||
.TP
|
||||
.B -ls #
|
||||
Specify a stretchable track. The argument specifies the initial track
|
||||
length. If at any time the track circumference exceeds the track length,
|
||||
the track length is increased to meet the need. The track length never
|
||||
decreases once it has been increased.
|
||||
.TP
|
||||
.B -le #
|
||||
Specify an elastic track. The argument specifies the initial track
|
||||
length. If at any time the track circumference exceeds the track length,
|
||||
the track length is increased to meet the need. When the track
|
||||
circumference decreases again, the track length also decreases, but it
|
||||
never gets shorter than its original length.
|
||||
.TP
|
||||
.B -i #
|
||||
Specify the initial offset of the track. By default, the first track pad
|
||||
is initially placed at the point where the caternary arc meets the first
|
||||
wheel. If an offset is specified, it represents the distance clockwise
|
||||
around the track to from this point to the desired initiall point of
|
||||
the first pad. This option is typically used to align the track pads
|
||||
with drive wheel teeth.
|
||||
.TP
|
||||
.B -f #
|
||||
Specify the integer with which to begin numbering the frames of the
|
||||
animation script. The default is zero.
|
||||
.TP
|
||||
.B -r #
|
||||
Specify the common radius of all the wheels. In this case, the fourth column
|
||||
should be omitted from the
|
||||
.BR wheelfile .
|
||||
.TP
|
||||
.B -g #
|
||||
Instead of an animation script, create a file which can be sourced by
|
||||
.I mged
|
||||
to edit the track geometry. This will actually wrap the modeled pad
|
||||
instances around the wheels.
|
||||
The argument is the number of the frame which is to be emulated. For
|
||||
example, to model the pads in the positions they will have in the first
|
||||
frame of an animation, the specified frame number would be zero.
|
||||
.TP
|
||||
.B -mp command
|
||||
Specify the animation matrix command to apply to the pads. The default
|
||||
value is "rarc", meaning that the matrix between the pad and its parent
|
||||
is replaced by a new matrix. See the
|
||||
.I anim_script
|
||||
man page for more information.
|
||||
.TP
|
||||
.B -mw command
|
||||
Specify the animation matrix command to apply to the wheels. The default
|
||||
value is "lmul", meaning that the new matrix is multiplied onto the left
|
||||
of the old matrix between the pad and its parent combination. See the
|
||||
.I anim_script
|
||||
man page for more information.
|
||||
|
||||
.SH EXAMPLES
|
||||
A typical use of
|
||||
.I anim_track
|
||||
would be to make an animation of a tank rolling across
|
||||
bumpy ground. By some method (such as physical simulation)
|
||||
you obtain the position of the center of
|
||||
the tank and its orientation at each time. You also nead to obtain the
|
||||
position of the each wheel relative to the vehicle center at each time.
|
||||
All of this information is placed in
|
||||
.BR in.table .
|
||||
The model of the tank is stored in
|
||||
model.g as a combination named "tank". Its centroid is at the
|
||||
point (0,0,1005) and it faces the y-axis. An animation script for the
|
||||
tank itself is created as follows:
|
||||
.PP
|
||||
anim_script -d 0 0 1005 -b 90 0 0 /tank < tank.table > tank.script
|
||||
.PP
|
||||
Here
|
||||
.B tank.table
|
||||
specifies the position and orientation of the tank in each frame; the
|
||||
.B \-d
|
||||
and
|
||||
.B \-b
|
||||
options specify the original position and orientation of the tank in the
|
||||
database.
|
||||
.PP
|
||||
To create the model of the track, a prototype track pad is created,
|
||||
centered on the origin in the x and y directions, with the
|
||||
wheel-contacting surface face-down on the origin. The pad is 100mm
|
||||
long and 5mm thick. Ninety-six instances of the pad are created, with names "rpad.0"
|
||||
through "rpad.95", and grouped together in a combination called "rtrack".
|
||||
.PP
|
||||
Now, a file called
|
||||
.B rwheelfile
|
||||
is created, describing the positions and radii of the four wheels in the
|
||||
right track:
|
||||
.nf
|
||||
|
||||
1300 2000 1005 60
|
||||
1300 1500 55 50
|
||||
1300 -1500 55 50
|
||||
1300 -2000 1005 60
|
||||
|
||||
.fi
|
||||
Two roadwheels both have radius 50mm, while the idler and drivewheels
|
||||
have a 60mm radius, and the wheels are named wh.0, wh.1, wh.2, and wh.3.
|
||||
.PP
|
||||
The following call checks the circumference of the track:
|
||||
.nf
|
||||
|
||||
%> anim_track -c rwheelfile
|
||||
9502.448956
|
||||
|
||||
.fi
|
||||
The 96 100mm-long pads should be sufficient to wrap around the wheels,
|
||||
leaving a shallow caternary arc between the idler and driver wheels.
|
||||
.PP
|
||||
The following call creates a file which can be used by
|
||||
.I mged
|
||||
to wrap the pads around the wheels in the model.
|
||||
.nf
|
||||
|
||||
%> anim_track -g 0 -b 90 0 0 -d 0 0 100 -lf 9600 -p 96 rtrack/rpad.
|
||||
rwheelfile <<EOF > rtrack.src
|
||||
? 0 0
|
||||
? EOF
|
||||
|
||||
.fi
|
||||
In this case,
|
||||
.I in.table
|
||||
consisted of only one row and two columns. The two columns represented
|
||||
time and the distance the track should be rolled from it's initial
|
||||
position. The
|
||||
.B -g
|
||||
option was set to 0 since frame zero was the only frame in the
|
||||
input table.
|
||||
The changes are applied to the geometry in
|
||||
.I mged
|
||||
with the following command:
|
||||
.nf
|
||||
|
||||
mged> source rtrack.src
|
||||
|
||||
.fi
|
||||
The pads are now permanently modeled in their new positions.
|
||||
.PP
|
||||
In order to animate the pads and wheels, the following command would be
|
||||
appropriate:
|
||||
.PP
|
||||
anim_track -p 96 rtrack/rpad. -w rwheel/wh. -d 0 0 1005 -b 90 0 0 -y -v -lf
|
||||
9600 rwheelfile < in.table > rtrack.script
|
||||
.PP
|
||||
The in.table contains 15 columns specifying the time, the 3D position and
|
||||
yaw, pitch, and roll of the vehicle, and the front-back and up-down
|
||||
coordinates of each of the four wheels relative to the vehicle center.
|
||||
For example, one row of
|
||||
.B in.table
|
||||
could be:
|
||||
.PP
|
||||
0.5 234.0 1415.6 1005 45 0 0 2000 0 1500 -950 -1500 -950 -2000 -10
|
||||
.PP
|
||||
This would specify the new position of the vehicle half of a second into
|
||||
the animation, and indicate that
|
||||
the first three wheels remained in their original positions
|
||||
while the fourth wheel had dropped 10mm.
|
||||
Note that the previous step (modeling) wasn't necessary in order for the
|
||||
animation to work.
|
||||
.PP
|
||||
.B rtrack.script
|
||||
by itself causes the wheels to move and rotate and the
|
||||
pads to roll around them. When the entire tank, including to track,
|
||||
is moved along across the ground by
|
||||
.BR track.script ,
|
||||
the full effect is acheived. The two scripts
|
||||
could be combined
|
||||
with a script for the left track, using
|
||||
.IR script_sort ,
|
||||
to make the complete script.
|
||||
.PP
|
||||
.SH BUGS
|
||||
Tracks must have at least two wheels. The front edge of wheel.(n-1) must
|
||||
stay behind the back edge of wheel.0, or the results are unpredictable.
|
||||
(Usually a lot of NaN's on the output).
|
||||
.SH SEE ALSO
|
||||
anim_script(1)
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1996-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
|
||||
Executable
+694
@@ -0,0 +1,694 @@
|
||||
/* A N I M _ T R A C K . C
|
||||
*
|
||||
* Animate the links and wheels of a tracked vehicle. Handles tracks that
|
||||
* change in shape during the animation.
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#ifdef USE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "machine.h"
|
||||
#include "externs.h"
|
||||
#include "vmath.h"
|
||||
#include "raytrace.h"
|
||||
#include "anim.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifndef M_PI_2
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#endif
|
||||
|
||||
#define GIVEN 0
|
||||
#define CALCULATED 1
|
||||
#define STEERED 2
|
||||
|
||||
#define PRINT_ANIM 0
|
||||
#define PRINT_ARCED 1
|
||||
|
||||
#define TRACK_MIN 0
|
||||
#define TRACK_FIXED 1
|
||||
#define TRACK_STRETCH 2
|
||||
#define TRACK_ELASTIC 3
|
||||
|
||||
#define NW num_wheels
|
||||
#define NEXT(i) (i+1)%NW
|
||||
#define PREV(i) (i+NW-1)%NW
|
||||
typedef double *pdouble;
|
||||
|
||||
struct wheel {
|
||||
vect_t pos; /* displacement of wheel from vehicle origin */
|
||||
fastf_t rad; /* radius of wheel */
|
||||
fastf_t ang0; /* angle where track meets wheel 0<a<2pi*/
|
||||
fastf_t ang1; /* angle where track leaves wheel 0<a<p2i */
|
||||
fastf_t arc; /* radian length of contact between wheel and track 0<a<pi*/
|
||||
};
|
||||
|
||||
struct track {
|
||||
vect_t pos0; /* beginning point of track section */
|
||||
vect_t pos1; /* end of track section */
|
||||
vect_t dir; /* unit vector:direction of track section ending here*/
|
||||
fastf_t len; /* length of track section ending here*/
|
||||
};
|
||||
|
||||
struct slope {
|
||||
vect_t dir; /* vector from previous to current axle*/
|
||||
fastf_t len; /* length of vector above*/
|
||||
};
|
||||
|
||||
struct all {
|
||||
struct wheel w; /* parameters describing the track around a wheel */
|
||||
struct track t; /* track between this wheel and the previous wheel */
|
||||
struct slope s; /* vector between this axle and the previous axle */
|
||||
};
|
||||
|
||||
/* external variables */
|
||||
extern int bu_optind;
|
||||
extern char *bu_optarg;
|
||||
|
||||
/* variables describing track geometry - used by main, trackprep, get_link*/
|
||||
struct all *x;
|
||||
|
||||
fastf_t curve_a, curve_b, curve_c, s_start;
|
||||
int num_links, num_wheels;
|
||||
fastf_t track_y, tracklen, first_tracklen;
|
||||
|
||||
/* variables set by get_args */
|
||||
int wheel_nindex; /* argv[wheel_nindex] = wheelname*/
|
||||
int link_nindex; /* argv[link_nindex] = linkname*/
|
||||
int print_wheel; /* flag: do wheel animation */
|
||||
int print_link; /* flag: do link animation */
|
||||
int print_mode; /* anim for rt or arced for mged */
|
||||
int arced_frame; /* which frame to arced */
|
||||
int axes, cent; /* flags: alternate axes, centroid specified */
|
||||
int dist_mode; /* given, steered, or calculated */
|
||||
int first_frame; /* integer to begin numbering frames */
|
||||
fastf_t init_dist; /* initial distance of first link along track */
|
||||
int one_radius; /* flag: common radius specified */
|
||||
fastf_t radius; /* common radius of all wheels */
|
||||
vect_t centroid, rcentroid; /* alternate centroid and its reverse */
|
||||
mat_t m_axes, m_rev_axes; /* matrices to and from alternate axes */
|
||||
char link_cmd[10]; /* default is "rarc" */
|
||||
char wheel_cmd[10]; /* default is "lmul" */
|
||||
int get_circumf; /* flag: just return circumference of track */
|
||||
int read_wheels; /* flag: read new wheel positions each frame */
|
||||
int len_mode; /* mode for track_len */
|
||||
int anti_strobe; /* flag: take measures against strobing effect */
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
void anim_y_p_r2mat(), anim_add_trans(), anim_mat_print();
|
||||
int get_args(), get_link(), track_prep(), val, frame, i, count;
|
||||
int go;
|
||||
fastf_t y_rot, distance, yaw, pch, roll;
|
||||
vect_t cent_pos, wheel_now, wheel_prev;
|
||||
vect_t zero, position, vdelta, temp, to_track, to_front;
|
||||
mat_t wmat, mat_x;
|
||||
FILE *stream;
|
||||
struct wheel *wh;
|
||||
int last_steer, last_frame;
|
||||
int rndtabi=0;
|
||||
fastf_t halfpadlen, delta, prev_dist;
|
||||
|
||||
VSETALL(zero,0.0);
|
||||
VSETALL(to_track,0.0);
|
||||
VSETALL(centroid,0.0);
|
||||
VSETALL(rcentroid,0.0);
|
||||
y_rot = 0.0;
|
||||
num_wheels = 0;
|
||||
last_steer = last_frame = 0;
|
||||
MAT_IDN(mat_x);
|
||||
MAT_IDN(wmat);
|
||||
MAT_IDN(m_axes);
|
||||
MAT_IDN(m_rev_axes);
|
||||
|
||||
if (!get_args(argc,argv))
|
||||
fprintf(stderr,"Anim_track: Argument error.\n");
|
||||
|
||||
if (axes || cent ){ /* vehicle has own reference frame */
|
||||
anim_add_trans(m_axes,centroid,zero);
|
||||
anim_add_trans(m_rev_axes,zero,rcentroid);
|
||||
}
|
||||
|
||||
/* get track information from specified file */
|
||||
|
||||
if (!(stream = fopen(*(argv+bu_optind),"r"))){
|
||||
fprintf(stderr,"Track: Could not open file %s.\n",*(argv+bu_optind));
|
||||
return(0);
|
||||
}
|
||||
num_wheels = -1;
|
||||
if (one_radius) {
|
||||
while (!feof(stream)) {
|
||||
fscanf(stream,"%*f %*f %*f");
|
||||
num_wheels++;
|
||||
}
|
||||
} else {
|
||||
while (!feof(stream)) {
|
||||
fscanf(stream,"%*f %*f %*f %*f");
|
||||
num_wheels++;
|
||||
}
|
||||
}
|
||||
rewind(stream);
|
||||
|
||||
|
||||
/*allocate memory for track information*/
|
||||
/* x: contains track geometry for the current frame */
|
||||
x = (struct all *) calloc(num_wheels,sizeof(struct all));
|
||||
/* wh: contains geometry of wheels in mged database */
|
||||
wh = (struct wheel *) calloc(num_wheels,sizeof(struct wheel));
|
||||
|
||||
/*read original wheel positions*/
|
||||
for (i=0;i<NW;i++){
|
||||
fscanf(stream,"%lf %lf %lf", temp, temp+1, temp+2);
|
||||
if (one_radius)
|
||||
x[i].w.rad = radius;
|
||||
else
|
||||
fscanf(stream,"%lf",& x[i].w.rad);
|
||||
MAT4X3PNT(x[i].w.pos,m_rev_axes,temp);
|
||||
if (i==0)
|
||||
track_y = x[0].w.pos[1];
|
||||
else
|
||||
x[i].w.pos[1] = track_y;
|
||||
|
||||
|
||||
wh[i].pos[0] = x[i].w.pos[0];
|
||||
wh[i].pos[1] = x[i].w.pos[1];
|
||||
wh[i].pos[2] = x[i].w.pos[2];
|
||||
wh[i].rad = x[i].w.rad;
|
||||
}
|
||||
(void) fclose(stream);
|
||||
|
||||
/* initialize to_track */
|
||||
VSET(to_track, 0.0, track_y, 0.0);
|
||||
VSET(to_front,1.0,0.0,0.0);
|
||||
|
||||
if (get_circumf&& (!read_wheels)) {
|
||||
track_prep();
|
||||
printf("%.10g\n",tracklen);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
if (dist_mode==STEERED) {
|
||||
/* prime the pumps */
|
||||
scanf("%*f");/*time*/
|
||||
val = scanf("%lf %lf %lf", cent_pos, cent_pos+1, cent_pos + 2);
|
||||
if (val < 3)
|
||||
return(0);
|
||||
go = anim_steer_mat(mat_x, cent_pos, 0);
|
||||
last_steer = 0;
|
||||
} else {
|
||||
go = 1;
|
||||
}
|
||||
|
||||
if (anti_strobe) {
|
||||
BN_RANDSEED(rndtabi, 0);
|
||||
}
|
||||
|
||||
/* main loop */
|
||||
prev_dist = distance = 0.0;
|
||||
frame = first_frame;
|
||||
for ( ; ; frame++) {
|
||||
if (dist_mode==GIVEN){
|
||||
scanf("%*f");/*time*/
|
||||
val = scanf("%lf",&distance);
|
||||
if (val < 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (dist_mode==CALCULATED){
|
||||
scanf("%*f");/*time*/
|
||||
scanf("%lf %lf %lf", cent_pos, cent_pos+1, cent_pos+2);
|
||||
val = scanf("%lf %lf %lf",&yaw,&pch,&roll);
|
||||
if (val < 3)
|
||||
break;
|
||||
anim_dy_p_r2mat(mat_x,yaw,pch,roll);
|
||||
anim_dy_p_r2mat(mat_x,yaw,pch,roll);
|
||||
anim_add_trans(mat_x,cent_pos,rcentroid);
|
||||
}
|
||||
|
||||
if (read_wheels) {
|
||||
/* read in all wheel positions */
|
||||
for(i=0;i<NW;i++){
|
||||
val=scanf("%lf %lf",x[i].w.pos, x[i].w.pos + 2);
|
||||
if (val < 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dist_mode==STEERED) {
|
||||
scanf("%*f");/*time*/
|
||||
val = scanf("%lf %lf %lf", cent_pos, cent_pos+1, cent_pos + 2);
|
||||
if (val < 3){
|
||||
if (last_steer)
|
||||
break;
|
||||
else
|
||||
last_steer = 1;
|
||||
}
|
||||
go = anim_steer_mat(mat_x, cent_pos, last_steer);
|
||||
anim_add_trans(mat_x,cent_pos,rcentroid);
|
||||
}
|
||||
|
||||
/* call track_prep to calculate geometry of track */
|
||||
if ((frame==first_frame)||read_wheels) {
|
||||
if ((track_prep())==-1){
|
||||
fprintf(stderr,"Track: error in frame %d: track too short.\n",frame);
|
||||
break;
|
||||
}
|
||||
if (get_circumf) {
|
||||
printf("%d\t%.10g\n",frame,tracklen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((dist_mode==CALCULATED)||(dist_mode==STEERED)){
|
||||
/*determine distance traveled*/
|
||||
VMOVE(wheel_prev,wheel_now);
|
||||
MAT4X3PNT(wheel_now,mat_x,to_track);
|
||||
if (frame > first_frame){ /* increment distance by distance moved*/
|
||||
VSUB2(vdelta,wheel_now,wheel_prev);
|
||||
MAT3X3VEC(temp,mat_x,to_front);/*new front of vehicle*/
|
||||
distance += VDOT(temp,vdelta);/*portion of vdelta in line with track*/
|
||||
}
|
||||
}
|
||||
|
||||
if (anti_strobe) {
|
||||
halfpadlen = 0.5 * tracklen/(fastf_t) num_links;
|
||||
delta = distance - prev_dist;
|
||||
prev_dist = distance;
|
||||
if ((delta >= halfpadlen)||(delta <= -halfpadlen)) {
|
||||
distance += BN_RANDOM(rndtabi) * 2.0* halfpadlen;
|
||||
}
|
||||
}
|
||||
|
||||
if (go && (!get_circumf)) {
|
||||
if (print_mode==PRINT_ANIM) {
|
||||
printf("start %d;\nclean;\n", frame);
|
||||
} else if (print_mode==PRINT_ARCED) {
|
||||
if (frame != arced_frame) continue;
|
||||
last_frame = 1;
|
||||
}
|
||||
if (print_link) {
|
||||
for (count=0;count<num_links;count++){
|
||||
(void) get_link(position,&y_rot,distance+tracklen*count/num_links+init_dist);
|
||||
anim_y_p_r2mat(wmat,0.0,y_rot,0.0);
|
||||
anim_add_trans(wmat,position,zero);
|
||||
if (axes || cent){ /* link moved to vehicle coords */
|
||||
MAT_MOVE(mat_x,wmat);
|
||||
bn_mat_mul(wmat,m_axes,mat_x);
|
||||
}
|
||||
if (print_mode==PRINT_ANIM) {
|
||||
printf("anim %s%d matrix %s\n", *(argv+link_nindex),count,link_cmd);
|
||||
anim_mat_printf(stdout,wmat,"%.10g ","\n",";\n");
|
||||
} else if (print_mode==PRINT_ARCED) {
|
||||
printf("arced %s%d matrix %s ", *(argv+link_nindex),count,link_cmd);
|
||||
anim_mat_printf(stdout,wmat,"%.10g ","","\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (print_wheel){
|
||||
for (count = 0;count<num_wheels;count++){
|
||||
anim_y_p_r2mat(wmat,0.0,-distance/wh[count].rad,0.0);
|
||||
VREVERSE(temp,wh[count].pos);
|
||||
anim_add_trans(wmat,x[count].w.pos,temp);
|
||||
if (axes || cent){
|
||||
bn_mat_mul(mat_x,wmat,m_rev_axes);
|
||||
bn_mat_mul(wmat,m_axes,mat_x);
|
||||
}
|
||||
if (print_mode==PRINT_ANIM) {
|
||||
printf("anim %s%d matrix %s\n",*(argv+wheel_nindex),count,wheel_cmd);
|
||||
anim_mat_printf(stdout,wmat,"%.10g ","\n",";\n");
|
||||
} else if (print_mode==PRINT_ARCED) {
|
||||
printf("arced %s%d matrix %s ",*(argv+wheel_nindex),count,wheel_cmd);
|
||||
anim_mat_printf(stdout,wmat,"%.10g ","","\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (print_mode==PRINT_ANIM)
|
||||
printf("end;\n");
|
||||
}
|
||||
if (last_frame) break;
|
||||
}
|
||||
free(x);
|
||||
free(wh);
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#define OPT_STR "sycuvb:d:f:i:r:p:w:g:m:l:a"
|
||||
|
||||
int get_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c, i;
|
||||
fastf_t yaw, pch, rll;
|
||||
void anim_dx_y_z2mat(), anim_dz_y_x2mat();
|
||||
/* defaults*/
|
||||
wheel_nindex = link_nindex = 0;
|
||||
axes = cent = print_wheel = print_link = 0;
|
||||
arced_frame = first_frame = 0;
|
||||
init_dist = radius = 0.0;
|
||||
one_radius = get_circumf = read_wheels = 0;
|
||||
strcpy(link_cmd, "rarc");
|
||||
strcpy(wheel_cmd, "lmul");
|
||||
print_mode = PRINT_ANIM;
|
||||
dist_mode = GIVEN;
|
||||
len_mode = TRACK_MIN;
|
||||
anti_strobe = 0;
|
||||
|
||||
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
|
||||
i=0;
|
||||
switch(c){
|
||||
case 's':
|
||||
dist_mode = STEERED;
|
||||
break;
|
||||
case 'y':
|
||||
dist_mode = CALCULATED;
|
||||
break;
|
||||
case 'c':
|
||||
get_circumf = 1;
|
||||
break;
|
||||
case 'u':
|
||||
dist_mode = GIVEN;
|
||||
break;
|
||||
case 'v':
|
||||
read_wheels = 1;
|
||||
break;
|
||||
case 'b':
|
||||
bu_optind -= 1;
|
||||
sscanf(argv[bu_optind+(i++)],"%lf", &yaw );
|
||||
sscanf(argv[bu_optind+(i++)],"%lf", &pch );
|
||||
sscanf(argv[bu_optind+(i++)],"%lf", &rll );
|
||||
bu_optind += 3;
|
||||
anim_dx_y_z2mat(m_axes, rll, -pch, yaw);
|
||||
anim_dz_y_x2mat(m_rev_axes, -rll, pch, -yaw);
|
||||
axes = 1;
|
||||
break;
|
||||
case 'd':
|
||||
bu_optind -= 1;
|
||||
sscanf(argv[bu_optind+(i++)],"%lf",centroid);
|
||||
sscanf(argv[bu_optind+(i++)],"%lf",centroid+1);
|
||||
sscanf(argv[bu_optind+(i++)],"%lf",centroid+2);
|
||||
bu_optind += 3;
|
||||
VREVERSE(rcentroid,centroid);
|
||||
cent = 1;
|
||||
break;
|
||||
case 'f':
|
||||
sscanf(bu_optarg,"%d",&first_frame);
|
||||
break;
|
||||
case 'i':
|
||||
sscanf(bu_optarg,"%lf",&init_dist);
|
||||
break;
|
||||
case 'r':
|
||||
sscanf(bu_optarg,"%lf",&radius);
|
||||
one_radius = 1;
|
||||
break;
|
||||
case 'p':
|
||||
sscanf(bu_optarg,"%d", &num_links);
|
||||
link_nindex = bu_optind;
|
||||
bu_optind += 1;
|
||||
print_link = 1;
|
||||
break;
|
||||
case 'w':
|
||||
wheel_nindex = bu_optind - 1;
|
||||
/*sscanf(bu_optarg,"%s",wheel_name);*/
|
||||
print_wheel = 1;
|
||||
break;
|
||||
case 'g':
|
||||
sscanf(bu_optarg,"%d",&arced_frame);
|
||||
print_mode = PRINT_ARCED;
|
||||
break;
|
||||
case 'm':
|
||||
switch (*bu_optarg) {
|
||||
case 'p':
|
||||
strncpy(link_cmd,argv[bu_optind], 10);
|
||||
break;
|
||||
case 'w':
|
||||
strncpy(wheel_cmd,argv[bu_optind], 10);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -m%c\n",*bu_optarg);
|
||||
return(0);
|
||||
}
|
||||
bu_optind += 1;
|
||||
break;
|
||||
case 'l':
|
||||
switch (*bu_optarg) {
|
||||
case 'm':
|
||||
len_mode = TRACK_MIN;
|
||||
break;
|
||||
case 'f':
|
||||
len_mode = TRACK_FIXED;
|
||||
sscanf(argv[bu_optind],"%lf",&first_tracklen);
|
||||
tracklen = first_tracklen;
|
||||
bu_optind++;
|
||||
break;
|
||||
case 's':
|
||||
len_mode = TRACK_STRETCH;
|
||||
sscanf(argv[bu_optind],"%lf",&first_tracklen);
|
||||
tracklen = first_tracklen;
|
||||
bu_optind++;
|
||||
break;
|
||||
case 'e':
|
||||
len_mode = TRACK_ELASTIC;
|
||||
sscanf(argv[bu_optind],"%lf",&first_tracklen);
|
||||
tracklen = first_tracklen;
|
||||
bu_optind++;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -l%c\n",*bu_optarg);
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
anti_strobe = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -%c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* TRACK_PREP - Calculate the geometry of the track. Wheel positions and
|
||||
* radii should already exist in the x[i] structs. Track_prep fills in the
|
||||
* rest of the x[i] structs and also calculates values for curve_a, curve_b,
|
||||
* curve_c, and s_start, which describe the caternary segment
|
||||
* return values: 0 = GOOD
|
||||
* -1 = BAD. Track too short to fit around wheels
|
||||
*/
|
||||
int track_prep()
|
||||
{
|
||||
int i;
|
||||
fastf_t phi, costheta, arc_angle;
|
||||
fastf_t linearlen, hyperlen;
|
||||
vect_t difference;
|
||||
int getcurve();
|
||||
fastf_t hyper_get_s();
|
||||
|
||||
/* first loop - get inter axle slopes and start/end angles */
|
||||
for (i=0;i<NW;i++){
|
||||
/*calculate current slope vector*/
|
||||
VSUB2(x[i].s.dir,x[i].w.pos,x[PREV(i)].w.pos);
|
||||
x[i].s.len = MAGNITUDE(x[i].s.dir);
|
||||
/*calculate end angle of previous wheel assuming all convex*/
|
||||
phi = atan2(x[i].s.dir[2],x[i].s.dir[0]);/*absolute angle of slope*/
|
||||
costheta = (x[PREV(i)].w.rad - x[i].w.rad)/x[i].s.len;/*cosine of special angle*/
|
||||
x[PREV(i)].w.ang1 = phi + acos(costheta);
|
||||
while (x[PREV(i)].w.ang1 < 0.0)
|
||||
x[PREV(i)].w.ang1 += 2.0*M_PI;
|
||||
x[i].w.ang0 = x[PREV(i)].w.ang1;
|
||||
}
|
||||
/* second loop - handle concavities */
|
||||
for (i=0;i<NW;i++){
|
||||
arc_angle = x[i].w.ang0 - x[i].w.ang1;
|
||||
while (arc_angle < 0.0)
|
||||
arc_angle += 2.0*M_PI;
|
||||
if (arc_angle > M_PI) { /* concave */
|
||||
x[i].w.ang0 = 0.5*(x[i].w.ang0 + x[i].w.ang1);
|
||||
x[i].w.ang1 = x[i].w.ang0;
|
||||
x[i].w.arc = 0.0;
|
||||
}
|
||||
else { /* convex - angles are already correct */
|
||||
x[i].w.arc = arc_angle;
|
||||
}
|
||||
}
|
||||
|
||||
/* third loop - calculate geometry of straight track segments */
|
||||
for (i=0;i<NW;i++){
|
||||
/*calculate endpoints of track segment*/
|
||||
x[i].t.pos1[0] = x[i].w.pos[0] + x[i].w.rad*cos(x[i].w.ang0);
|
||||
x[i].t.pos1[1] = x[i].w.pos[1];
|
||||
x[i].t.pos1[2] = x[i].w.pos[2] + x[i].w.rad*sin(x[i].w.ang0);
|
||||
x[i].t.pos0[0] = x[PREV(i)].w.pos[0] + x[PREV(i)].w.rad*cos(x[PREV(i)].w.ang1);
|
||||
x[i].t.pos0[1] = x[PREV(i)].w.pos[1];
|
||||
x[i].t.pos0[2] = x[PREV(i)].w.pos[2] + x[PREV(i)].w.rad*sin(x[PREV(i)].w.ang1);
|
||||
/*calculate length and direction of track segment*/
|
||||
VSUB2(difference,x[i].t.pos1,x[i].t.pos0);
|
||||
x[i].t.len = MAGNITUDE(difference);
|
||||
VSCALE((x[i].t.dir),difference,(1.0/x[i].t.len));
|
||||
}
|
||||
|
||||
/* calculate total track length used so far*/
|
||||
linearlen = x[0].w.arc*x[0].w.rad;
|
||||
for (i=1;i<NW;i++){
|
||||
linearlen += x[i].t.len;
|
||||
linearlen += x[i].w.arc*x[i].w.rad;
|
||||
}
|
||||
|
||||
if (len_mode==TRACK_MIN) {
|
||||
tracklen = linearlen + x[0].t.len;
|
||||
curve_a = 0.0;
|
||||
return(0); /* early return */
|
||||
}
|
||||
|
||||
if (len_mode==TRACK_ELASTIC) {
|
||||
tracklen = first_tracklen;
|
||||
}
|
||||
|
||||
/* calculate geometry of hyperbolic segment */
|
||||
hyperlen = tracklen - linearlen;
|
||||
if(hyperlen < x[0].t.len){ /* desired length of hyperbola less than straight line*/
|
||||
if((len_mode==TRACK_ELASTIC)||(len_mode==TRACK_STRETCH)){
|
||||
tracklen += (x[0].t.len-hyperlen);
|
||||
hyperlen = tracklen - linearlen;
|
||||
}
|
||||
else{
|
||||
return(-1);/*bad, track is too short*/
|
||||
}
|
||||
}
|
||||
|
||||
getcurve(&curve_a,&curve_b,&curve_c,&(x[NW-1].w.ang1),&(x[0].w.ang0),hyperlen,x[NW-1].w.pos,x[0].w.pos,x[NW-1].w.rad,x[0].w.rad);
|
||||
|
||||
/* re-evaluate zeroth track section in light of curve information */
|
||||
x[0].t.pos0[X] = x[NW-1].w.pos[X] + x[NW-1].w.rad * cos(x[NW-1].w.ang1);
|
||||
x[0].t.pos0[Z] = x[NW-1].w.pos[Z] + x[NW-1].w.rad * sin(x[NW-1].w.ang1);
|
||||
x[0].t.pos1[X] = x[0].w.pos[X] + x[0].w.rad * cos(x[0].w.ang0);
|
||||
x[0].t.pos1[Z] = x[0].w.pos[Z] + x[0].w.rad * sin(x[0].w.ang0);
|
||||
VSUB2(difference,x[0].t.pos1,x[0].t.pos0);
|
||||
x[0].t.len = MAGNITUDE(difference);
|
||||
VSCALE(x[0].t.dir,difference,(1.0/x[0].t.len));
|
||||
|
||||
if (curve_a > VDIVIDE_TOL)
|
||||
s_start = hyper_get_s(curve_a, 0.0, x[0].t.pos0[X] - curve_c);
|
||||
|
||||
x[0].w.arc = x[0].w.ang0 - x[0].w.ang1;
|
||||
if (x[0].w.arc<0.0)
|
||||
x[0].w.arc += 2.0*M_PI;
|
||||
x[NW-1].w.arc = x[NW-1].w.ang0 - x[NW-1].w.ang1;
|
||||
if (x[NW-1].w.arc<0.0)
|
||||
x[NW-1].w.arc += 2.0*M_PI;
|
||||
|
||||
return(0); /*good*/
|
||||
}
|
||||
|
||||
/* GET_LINK - Find the position and angle of a link which is a given
|
||||
* distance around the track, measured from the point where the caternary
|
||||
* section meets wheel.0.
|
||||
*/
|
||||
int get_link(pos,angle_p,dist)
|
||||
fastf_t *angle_p, dist;
|
||||
vect_t pos;
|
||||
{
|
||||
int i;
|
||||
vect_t temp;
|
||||
fastf_t hyper_get_x(), hyper_get_z(), hyper_get_ang();
|
||||
|
||||
while (dist >= tracklen) /*periodicize*/
|
||||
dist -= tracklen;
|
||||
while (dist < 0.0)
|
||||
dist += tracklen;
|
||||
|
||||
/* we want it to ignore the distance between wheel(n-1) and wheel(0)*/
|
||||
dist += x[0].t.len;
|
||||
for (i=0;i<NW;i++){
|
||||
if ( (dist -= x[i].t.len) < 0 ){
|
||||
VSCALE(temp,(x[i].t.dir),dist);
|
||||
VADD2(pos,x[i].t.pos1,temp);
|
||||
*angle_p = atan2(x[i].t.dir[2],x[i].t.dir[0]);
|
||||
return(2*i);
|
||||
}
|
||||
if ((dist -= x[i].w.rad*x[i].w.arc) < 0){
|
||||
*angle_p = dist/x[i].w.rad;
|
||||
*angle_p = x[i].w.ang1 - *angle_p;/*from x-axis to link*/
|
||||
pos[X] = x[i].w.pos[X] + x[i].w.rad*cos(*angle_p);
|
||||
pos[Y] = x[i].w.pos[Y];
|
||||
pos[Z] = x[i].w.pos[Z] + x[i].w.rad*sin(*angle_p);
|
||||
*angle_p -= M_PI_2; /*angle of clockwise tangent to circle*/
|
||||
return(2*i+1);
|
||||
}
|
||||
}
|
||||
|
||||
/* caternary section */
|
||||
if ( curve_a > VDIVIDE_TOL){
|
||||
pos[X] = hyper_get_x(curve_a, 0.0, s_start+dist);
|
||||
pos[Y] = x[0].w.pos[Y];
|
||||
pos[Z] = hyper_get_z(curve_a,curve_b,0.0, pos[X]);
|
||||
pos[X] += curve_c;
|
||||
*angle_p = hyper_get_ang(curve_a,curve_c, pos[X]);
|
||||
}
|
||||
else { /* practically linear */
|
||||
VSCALE(temp,(x[0].t.dir),dist);
|
||||
VADD2(pos,x[0].t.pos0,temp);
|
||||
*angle_p = atan2(x[0].t.dir[Z],x[0].t.dir[X]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void show_info(which)/* for debugging - -1:track 0:both 1:link*/
|
||||
int which;
|
||||
{
|
||||
int i;
|
||||
if (which <=0){
|
||||
fprintf(stderr,"track length: %f\n",tracklen);
|
||||
fprintf(stderr,"link length: %f\n",tracklen/num_links);
|
||||
for (i=0;i<NW;i++){
|
||||
fprintf(stderr,"wheel %d: \n",i);
|
||||
fprintf(stderr," pos\t%f\t%f\t%f\t\n",x[i].w.pos[X],x[i].w.pos[Y],x[i].w.pos[Z]);
|
||||
fprintf(stderr," rad\t%f\tang0\t%f\tang1\t%f\tarc\t%f\n",x[i].w.rad,x[i].w.ang0,x[i].w.ang1,x[i].w.arc);
|
||||
|
||||
fprintf(stderr,"track %d: \n",i);
|
||||
fprintf(stderr," pos0\t%f\t%f\tpos1\t%f\t%f\n",x[i].t.pos0[X],x[i].t.pos0[Z],x[i].t.pos1[X],x[i].t.pos1[Z]);
|
||||
fprintf(stderr," dir\t%f\t%f\t%f\tlen\t%f\n",x[i].t.dir[X],x[i].t.dir[Y],x[i].t.dir[Z],x[i].t.len);
|
||||
fprintf(stderr,"slope %d: %f %f %f %f\n",i,x[i].s.dir[0],x[i].s.dir[1],x[i].s.dir[2],x[i].s.len);
|
||||
}
|
||||
}
|
||||
/* if (which >= 0){
|
||||
fprintf(stderr,"%d %f %f %f %f\n",count,position[0],position[1],position[2],y_rot);
|
||||
}*/
|
||||
}
|
||||
|
||||
Executable
+95
@@ -0,0 +1,95 @@
|
||||
.TH ANIM_TURN 1 BRL/CAD
|
||||
.SH NAME
|
||||
anim_turn - make animation table for vehicle with front-wheel steering.
|
||||
.SH SYNOPSIS
|
||||
.B anim_turn -l length
|
||||
.B [-a angle]
|
||||
.B [-r radius]
|
||||
.B [-f factor]
|
||||
.B [-p integer]
|
||||
.B < in.table
|
||||
.B > out.table
|
||||
.SH DESCRIPTION
|
||||
The motion of a front wheel steered vehicle is not simple - the
|
||||
instaneous velocity of the front wheels is in the direction they are
|
||||
pointed, while the instantaneous velocity of the back wheels is the
|
||||
direction the vehicle is pointed. The purpose of
|
||||
.I anim_turn
|
||||
is to
|
||||
produce a complete animation table for such a vehicle, given a table
|
||||
specifying the desired position of the front axle at each relevant
|
||||
time step. The input table should contain four columns, specifying the
|
||||
time and 3D position of the center of the front axle. Actually, the path
|
||||
is assumed to be confined to an x-y plane, but the three columns are
|
||||
included for consistency with other animation routines.
|
||||
.PP
|
||||
The output is normally a seven-column table which is a copy of
|
||||
the input table with three extra columns specifying the yaw,
|
||||
pitch, and roll of the truck at each time. The pitch and roll
|
||||
are always zero, since the motion is assumed be in an x-y plane.
|
||||
.PP
|
||||
The
|
||||
.B \-l#
|
||||
option is not optional, and is used to specify the length
|
||||
of the wheelbase (from the front axle to the rear axle).
|
||||
.PP
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-a#
|
||||
.I Track
|
||||
assumes that the truck should initially be oriented
|
||||
along the line defined by the first two positions in the input table.
|
||||
Otherwise, the desired initial yaw of the truck can be specified with the
|
||||
.B \-a#
|
||||
option.
|
||||
.TP
|
||||
.B \-r#
|
||||
Specify the radii of the front wheels. If this option is selected,
|
||||
.I track
|
||||
will create an animation script to animate the front wheels. The output
|
||||
table would contain four columns: time, swivel-angle, roll, and a zero
|
||||
channel. These represent the orientation of the front wheels, in terms
|
||||
of yaw, pitch, and roll, and the table can be piped directly to
|
||||
.IR anim_script .
|
||||
.TP
|
||||
.B \-f#
|
||||
Specify a factor to be used to animate a steering wheel. If this option
|
||||
is selected, the output table will contain four columns: time, swivel,
|
||||
and two zero columns. This table can be used directly by
|
||||
.I anim_script
|
||||
to make an animation script for a steering wheel. The argument to the
|
||||
option should be the factor by which to exagerate the swiveling of
|
||||
the wheels. For
|
||||
example, on a typical truck, you may need to turn the steering wheel 360
|
||||
degrees in order for the wheels to swivel 20 degrees. To model this
|
||||
effect, a factor of 18 would be used.
|
||||
.TP
|
||||
.B \-p#
|
||||
Specify the ratio of input rows to output rows,
|
||||
which must be an integer. The default, of course, is one. The accuracy
|
||||
of the output depends on having a large number of input lines, which is
|
||||
not usually a problem in animations, which require a large number of
|
||||
frames per second. However, if a test animation with a small number of
|
||||
frames per second is being created, the user should give an input table
|
||||
with a high number of input rows and reduce the output with the
|
||||
.B \-p#
|
||||
option. For example, if
|
||||
.B in.table
|
||||
contains 30 rows for each second of the
|
||||
animation, then the command
|
||||
.sp
|
||||
.B
|
||||
anim_turn -l 3000 -p10 < in.table > out.table
|
||||
.sp
|
||||
would produce an animation table containing 3 rows for each second of
|
||||
the animation.
|
||||
.SH BUGS
|
||||
The algorithm used only works for motion in an x-y plane.
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1993-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
Executable
+185
@@ -0,0 +1,185 @@
|
||||
/* A N I M _ T U R N . C
|
||||
*
|
||||
* Animate front-wheel steered vehicles.
|
||||
*
|
||||
* This is a filter which operates on animation tables. Given an
|
||||
* animation table for the position of the front axle, anim_turn produces
|
||||
* an animation table for position and orientation. Options provide for
|
||||
* animating the wheels and/or steering wheel.
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "machine.h"
|
||||
#include "vmath.h"
|
||||
#include "bu.h"
|
||||
#include "anim.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
int get_args();
|
||||
extern void anim_y_p_r2mat();
|
||||
extern void anim_add_trans();
|
||||
|
||||
extern int bu_optind;
|
||||
extern char *bu_optarg;
|
||||
|
||||
int print_int = 1;
|
||||
int angle_set = 0;
|
||||
int turn_wheels = 0;
|
||||
fastf_t length, angle, radius;
|
||||
fastf_t factor = 1.0;
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int count;
|
||||
fastf_t val, time, roll_ang, yaw,sign;
|
||||
vect_t v, point, front, back, zero, temp1, temp2;
|
||||
mat_t m_from_world, m_to_world;
|
||||
double bn_atan2();
|
||||
|
||||
/* initialize variables */
|
||||
VSETALL(zero, 0.0);
|
||||
VSETALL( v , 0.0 );
|
||||
VSETALL( point, 0.0 );
|
||||
VSETALL( front, 0.0 );
|
||||
VSETALL( back, 0.0 );
|
||||
VSETALL( temp1, 0.0 );
|
||||
VSETALL( temp2, 0.0 );
|
||||
for( count=0 ; count<ELEMENTS_PER_MAT ; count++ )
|
||||
m_from_world[count]=m_to_world[count]=0.0;
|
||||
length = angle = radius = roll_ang = 0.0;
|
||||
|
||||
if (!get_args(argc,argv))
|
||||
fprintf(stderr,"ascript: Get_args error");
|
||||
|
||||
if (!angle_set) { /* set angle if not yet done */
|
||||
scanf("%*f%*[^-0123456789]");
|
||||
VSCAN(temp1);
|
||||
scanf("%*f%*[^-0123456789]");
|
||||
VSCAN(temp2);
|
||||
angle = bn_atan2( (temp2[1]-temp1[1]),(temp2[0]-temp1[0]) );
|
||||
rewind(stdin);
|
||||
}
|
||||
count = 0;
|
||||
while (1) {
|
||||
/* read one line of table */
|
||||
val = scanf("%lf%*[^-0123456789]",&time); /*read time,ignore garbage*/
|
||||
val = scanf("%lf %lf %lf", point, point+1, point +2);
|
||||
if (val < 3) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*update to and from matrices */
|
||||
|
||||
if (count) { /* not first time through */
|
||||
/* calculate matrices corrsponding to last position*/
|
||||
anim_y_p_r2mat(m_to_world,angle,0.0,0.0);
|
||||
anim_add_trans(m_to_world,front,zero);
|
||||
anim_y_p_r2mat(m_from_world,-angle,0.0,0.0);
|
||||
VREVERSE(temp1,front);
|
||||
anim_add_trans(m_from_world,zero,temp1);
|
||||
|
||||
/* calculate new position for front and back axles */
|
||||
/* front goes to the point, back slides along objects*/
|
||||
/* current front to back axis */
|
||||
MAT4X3PNT(v,m_from_world,point);/* put point in vehicle coordinates*/
|
||||
if (v[1] > length) {
|
||||
fprintf(stderr,"anim_turn: Distance between positions greater than length of vehicle - ABORTING\n");
|
||||
break;
|
||||
}
|
||||
temp2[0] = v[0] - sqrt(length*length - v[1]*v[1]); /*calculate back*/
|
||||
temp2[1] = temp2[2] = 0.0;
|
||||
MAT4X3PNT(back,m_to_world,temp2);/*put "back" in world coordinates*/
|
||||
VMOVE(front,point);
|
||||
|
||||
/*calculate new angle of vehicle*/
|
||||
VSUB2(temp1,front,back);
|
||||
angle = bn_atan2(temp1[1],temp1[0]);
|
||||
}
|
||||
else { /*first time through */
|
||||
/*angle is already determined*/
|
||||
VMOVE(front, point);
|
||||
}
|
||||
|
||||
/*calculate turn angles and print table*/
|
||||
|
||||
if (turn_wheels){
|
||||
if (v[0] >= 0)
|
||||
sign = 1.0;
|
||||
else
|
||||
sign = -1.0;
|
||||
yaw = bn_atan2(sign*v[1],sign*v[0]);
|
||||
if (radius > VDIVIDE_TOL)
|
||||
roll_ang -= sign * MAGNITUDE(v) / radius;
|
||||
|
||||
if (!(count%print_int))
|
||||
printf("%.10g %.10g %.10g 0.0\n",time,factor*RTOD*yaw,RTOD*roll_ang);
|
||||
}
|
||||
else { /* print position and orientation of vehicle */
|
||||
if (!(count%print_int))
|
||||
printf("%.10g %.10g %.10g %.10g %.10g 0.0 0.0\n",time,front[0],front[1],front[2], RTOD * angle);
|
||||
}
|
||||
count++;
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
#define OPT_STR "r:l:a:f:p:"
|
||||
|
||||
int get_args(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
while ( (c=bu_getopt(argc,argv,OPT_STR)) != EOF) {
|
||||
switch(c){
|
||||
case 'l':
|
||||
sscanf(bu_optarg,"%lf",&length);
|
||||
break;
|
||||
case 'a':
|
||||
sscanf(bu_optarg,"%lf",&angle);
|
||||
angle *= DTOR; /* degrees to radians */
|
||||
angle_set = 1;
|
||||
break;
|
||||
case 'r':
|
||||
sscanf(bu_optarg,"%lf",&radius);
|
||||
turn_wheels = 1;
|
||||
break;
|
||||
case 'f':
|
||||
turn_wheels = 1;
|
||||
sscanf(bu_optarg,"%lf",&factor);
|
||||
break;
|
||||
case 'p':
|
||||
sscanf(bu_optarg,"%d",&print_int);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"Unknown option: -%c\n",c);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
+277
@@ -0,0 +1,277 @@
|
||||
/* C A T T R A C K . C
|
||||
*
|
||||
* Caternary curve routines used by anim_track.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "conf.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include "machine.h"
|
||||
#include "vmath.h"
|
||||
#include "anim.h"
|
||||
|
||||
#define MAX_REACHED 0
|
||||
#define SOLVED 1
|
||||
|
||||
/* the total maximum number of lowest level iterations possible is
|
||||
* T_MAX_ITS*MAX_OUT_ITS*2*MAX_ITS
|
||||
*/
|
||||
#define MAX_ITS 25
|
||||
#define MAX_OUT_ITS 25
|
||||
#define T_MAX_ITS 50
|
||||
|
||||
/* these tolerances are guessed at, except that it seems to be important
|
||||
* in elastic situations that T_TOL be significantly smaller than the others
|
||||
*/
|
||||
#define T_TOL 1.0e-14
|
||||
#define G_TOL 1.0e-12
|
||||
#define F_TOL 1.0e-12
|
||||
|
||||
/* HYPER_GET_X - get x value of a point which is a given distance along
|
||||
* caternary curve.
|
||||
* x(s) = arcsinh(a*s-sinh(a*c))/a + c
|
||||
* Left to calling routine to avoid dividing by zero.
|
||||
*/
|
||||
fastf_t hyper_get_x(a,c, s, d, x, cos_ang)
|
||||
fastf_t a, c; /* curve parameters */
|
||||
fastf_t s; /* arclength value */
|
||||
{
|
||||
fastf_t arg, asinh_arg;
|
||||
|
||||
arg = a*s - sinh(a*c);
|
||||
asinh_arg = log(arg + sqrt(arg*arg + 1.0));
|
||||
|
||||
return(asinh_arg/a + c);
|
||||
}
|
||||
|
||||
/* HYPER_GET_S - calculate the arclength parameter of a caternary
|
||||
* curve corresponding to the given value of x.
|
||||
* s(x) = (sinh(a(x-c))+sinh(ac))/a
|
||||
* Left to calling routime to avoid dividing by zero.
|
||||
*/
|
||||
fastf_t hyper_get_s(a, c, x)
|
||||
fastf_t a, c, x;
|
||||
{
|
||||
return((sinh(a*(x-c))+sinh(a*c))/a);
|
||||
}
|
||||
|
||||
/* HYPER_GET_Z - calculate point on the caternary curve:
|
||||
* z(x) = cosh(a*(x-c))/a + b
|
||||
* Left to calling routine to avoid dividing by zero.
|
||||
*/
|
||||
fastf_t hyper_get_z(a,b,c,x)
|
||||
fastf_t a,b,c,x;
|
||||
{
|
||||
fastf_t z;
|
||||
|
||||
if (fabs(a)>VDIVIDE_TOL){
|
||||
z = cosh(a*(x-c))/a + b;
|
||||
} else {
|
||||
z = b;
|
||||
}
|
||||
return(z);
|
||||
}
|
||||
|
||||
/* HYPER_GET_ANG - calculate angle corresponding to the slope of
|
||||
* caternary curve.
|
||||
* z'(x) = sinh(a*(x-c))
|
||||
*/
|
||||
fastf_t hyper_get_ang(a,c,x)
|
||||
fastf_t a,c,x;
|
||||
{
|
||||
fastf_t slope;
|
||||
|
||||
slope = sinh(a*(x-c));
|
||||
return( atan2(slope, 1.0));
|
||||
}
|
||||
|
||||
/* GET_CURVE - Find the constants a, b, and c such that the curve
|
||||
* z = cosh(a*(x-c))/a + b
|
||||
* is tangent to circles of radii r0 and r1 located at
|
||||
* (x0,z0) and (x1,z1) and such that the curve has
|
||||
* arclength delta_s between circles. Also find the angle where
|
||||
* the curve touches each circle. When called successively,
|
||||
* It uses the values of a,b, and c from the last call as a start.
|
||||
*/
|
||||
int getcurve(pa,pb,pc,pth0,pth1,delta_s, p_zero, p_one, r_zero, r_one)
|
||||
fastf_t *pa, *pb, *pc; /* curve parameters */
|
||||
fastf_t *pth0, *pth1; /* angle where curve contacts circle0,circle1 */
|
||||
fastf_t delta_s; /* desired arclength */
|
||||
fastf_t r_zero, r_one; /* radii of circle0 and circle1 */
|
||||
vect_t p_zero, p_one; /* center of circle0 and circle1 */
|
||||
{
|
||||
|
||||
int status, i, solved;
|
||||
int ingetcurve();
|
||||
fastf_t theta_one, theta_zero, new_theta_zero, new_theta_one;
|
||||
fastf_t avg_theta_zero, avg_theta_one, arc_dist;
|
||||
fastf_t tang_ang, costheta;
|
||||
double stmp;
|
||||
vect_t q_zero, q_one, diff;
|
||||
static fastf_t last_a, last_c, last_theta_one, last_theta_zero;
|
||||
static int called_before = 0;
|
||||
|
||||
/*first calculate angle at which tangent line would contact circles*/
|
||||
VSUB2(diff,p_one,p_zero);
|
||||
tang_ang = atan2(diff[Z],diff[X]);
|
||||
costheta = (r_zero-r_one)/MAGNITUDE(diff);
|
||||
tang_ang += acos(costheta);
|
||||
|
||||
if (!called_before){
|
||||
theta_one = tang_ang;
|
||||
theta_zero = tang_ang;
|
||||
(*pa) = 1.0;
|
||||
*pc = 0.5*(p_one[X]+p_zero[X]);
|
||||
called_before = 1;
|
||||
}
|
||||
else {
|
||||
theta_zero = last_theta_zero;
|
||||
theta_one = last_theta_one;
|
||||
*pa = last_a;
|
||||
*pc = last_c;
|
||||
}
|
||||
|
||||
status = MAX_REACHED;
|
||||
for (i=0;i<T_MAX_ITS;i++){
|
||||
q_zero[X] = p_zero[X] + r_zero * cos(theta_zero);
|
||||
q_zero[Z] = p_zero[Z] + r_zero * sin(theta_zero);
|
||||
q_one[X] = p_one[X] + r_one * cos(theta_one);
|
||||
q_one[Z] = p_one[Z] + r_one * sin(theta_one);
|
||||
|
||||
/* determine distance taken by arc*/
|
||||
arc_dist = r_zero * (tang_ang - theta_zero);
|
||||
arc_dist += r_one * (theta_one - tang_ang);
|
||||
|
||||
ingetcurve(pa,pb,pc, delta_s-arc_dist, q_zero, q_one);
|
||||
|
||||
solved = 0;
|
||||
/* refine theta_one */
|
||||
stmp = sinh( (*pa)*(q_zero[X]-(*pc)) );
|
||||
new_theta_zero = atan2(1.0,-stmp);
|
||||
avg_theta_zero = 0.5 * (theta_zero + new_theta_zero);
|
||||
if (fabs(theta_zero-avg_theta_zero)<T_TOL){
|
||||
solved++;
|
||||
}
|
||||
theta_zero = avg_theta_zero;
|
||||
|
||||
/* refine theta_two */
|
||||
stmp = sinh( (*pa)*(q_one[X]-(*pc)) );
|
||||
new_theta_one = atan2(1.0,-stmp);
|
||||
avg_theta_one = 0.5 * (theta_one + new_theta_one);
|
||||
if (fabs(theta_one-avg_theta_one)<T_TOL){
|
||||
solved++;
|
||||
}
|
||||
theta_one = avg_theta_one;
|
||||
|
||||
if (solved == 2){
|
||||
status = SOLVED;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
last_theta_zero = theta_zero;
|
||||
last_theta_one = theta_one;
|
||||
last_a = *pa;
|
||||
last_c = *pc;
|
||||
*pth0 = theta_zero;
|
||||
*pth1 = theta_one;
|
||||
return(status);
|
||||
|
||||
}
|
||||
|
||||
/* INGETCURVE - find constants a, b, and c, such that the curve
|
||||
* z = cosh(a*(x-c))/a + b
|
||||
* passes through (x0,z0) and (x1,z1) and has arclength delta_s
|
||||
* Appropriate first guesses for a,b, and c should be given.
|
||||
*/
|
||||
int ingetcurve(pa,pb,pc, delta_s, p_zero, p_one)
|
||||
fastf_t *pa, *pb, *pc;
|
||||
fastf_t delta_s;
|
||||
vect_t p_zero, p_one;
|
||||
{
|
||||
int status, i, j, k;
|
||||
fastf_t adjust;
|
||||
fastf_t eff(),gee();
|
||||
|
||||
status = MAX_REACHED;
|
||||
i=0;
|
||||
while (i++<MAX_OUT_ITS){
|
||||
for (j=0;j<MAX_ITS;j++){
|
||||
adjust = eff(*pa,*pc,p_zero[X],p_one[X],delta_s);
|
||||
if ((*pa-adjust)<=0.0){
|
||||
*pa *= 0.5;
|
||||
}
|
||||
else {
|
||||
*pa -= adjust;
|
||||
}
|
||||
if (adjust<F_TOL){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (k=0;k<MAX_ITS;k++){
|
||||
adjust = gee(*pa,*pc,p_zero[X],p_one[X],(p_one[Z]-p_zero[Z]));
|
||||
*pc -= adjust;
|
||||
if (adjust<G_TOL){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((j==0)&&(k==0)){
|
||||
status = SOLVED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*pb = p_zero[Z] - cosh( (*pa)*(p_zero[X]-(*pc)) )/(*pa);
|
||||
|
||||
return(status);
|
||||
|
||||
}
|
||||
|
||||
/* find Newtonian adjustment for 'a', assuming 'c' fixed*/
|
||||
fastf_t eff(a,c,x0,x1,delta_s)
|
||||
fastf_t a,c,x0,x1,delta_s;
|
||||
{
|
||||
double f,fprime;
|
||||
double arg0, arg1, sarg0, sarg1;
|
||||
|
||||
arg0 = a*(x0-c);
|
||||
arg1 = a*(x1-c);
|
||||
|
||||
sarg0 = sinh(arg0);
|
||||
sarg1 = sinh(arg1);
|
||||
|
||||
f = a*(sarg1-sarg0 - a*delta_s);
|
||||
fprime = sarg0 - sarg1 - arg0*cosh(arg0) + arg1*cosh(arg1);
|
||||
|
||||
if (fabs(fprime) > VDIVIDE_TOL)
|
||||
return(f/fprime);
|
||||
else if ((a*a) > VDIVIDE_TOL)
|
||||
return(f/(a*a));
|
||||
else if (fabs(a) > VDIVIDE_TOL)
|
||||
return(f/a);
|
||||
else
|
||||
return(f);
|
||||
}
|
||||
|
||||
/* find Newtonian adjustment for c, assuming 'a' fixed*/
|
||||
fastf_t gee(a,c,x0,x1,delta_z)
|
||||
fastf_t a,c,x0,x1,delta_z;
|
||||
{
|
||||
double g, gprime, arg0, arg1;
|
||||
|
||||
arg0 = a*(x0-c);
|
||||
arg1 = a*(x1-c);
|
||||
|
||||
g = cosh(arg1)-cosh(arg0) - a*delta_z;
|
||||
gprime = a*(sinh(arg0) - sinh(arg1));
|
||||
|
||||
if (fabs(gprime) > VDIVIDE_TOL)
|
||||
return(g/gprime);
|
||||
else if (fabs(a) > VDIVIDE_TOL)
|
||||
return(g/a);
|
||||
else
|
||||
return(g);
|
||||
}
|
||||
|
||||
Executable
+68
@@ -0,0 +1,68 @@
|
||||
/* C H A N _ A D D . C
|
||||
*
|
||||
* Add a given value to specified columns of data.
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
double addend, temp;
|
||||
int i,j,doit, of, count, val, *col_list;
|
||||
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr,"Usage: chan_add value num_columns column [column ...] < in.file > out.file\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
sscanf(*(argv+1),"%lf",&addend);
|
||||
sscanf(*(argv+2),"%d",&of);
|
||||
col_list = (int *) calloc(argc-2,sizeof(int));
|
||||
for (i=3;i<argc;i++){
|
||||
sscanf(*(argv+i),"%d",col_list+(i-3));
|
||||
}
|
||||
|
||||
count = 0;
|
||||
while (!feof(stdin)){
|
||||
val = scanf("%lf",&temp);
|
||||
if (val<1)
|
||||
;
|
||||
else {
|
||||
doit = 0;
|
||||
for (j=0;j<argc-3;j++){
|
||||
if (col_list[j]==count)
|
||||
doit = 1;
|
||||
}
|
||||
if (doit)
|
||||
printf("%.10g\t",temp + addend);
|
||||
else
|
||||
printf("%.10g\t",temp);
|
||||
}
|
||||
if ( count == (of-1))
|
||||
printf("\n");
|
||||
count = (count+1)%of;
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
.TH CHAN_MULT 1 BRL/CAD
|
||||
.SH NAME
|
||||
chan_mult - multiply columns of data by a given factor
|
||||
.PP
|
||||
chan_add - add a given value to columns of data
|
||||
.SH SYNOPSIS
|
||||
chan_mult factor num_columns column [column column ...] < infile > outfile
|
||||
.PP
|
||||
chan_add value num_columns column [column column ...] < infile > outfile
|
||||
.SH DESCRIPTION
|
||||
.I Mult_chan
|
||||
will multiply all numbers in the specified columns by the given
|
||||
factor. The infile is
|
||||
an ASCII file, with columns separeted by white space. The columns are
|
||||
numbered from 0 to (n-1).
|
||||
.I Add_chan
|
||||
behaves analogously, but with
|
||||
addition rather than multiplication.
|
||||
.SH EXAMPLES
|
||||
These routines are useful for converting between units in animation
|
||||
tables.
|
||||
.PP
|
||||
To multiply all but the first column of a four column file by 2.54:
|
||||
.PP
|
||||
.B
|
||||
chan_mult 2.54 4 1 2 3
|
||||
.PP
|
||||
To add ten to the first six columns of an eight-column file:
|
||||
.PP
|
||||
.B
|
||||
chan_add 10.0 8 0 1 2 3 4 5
|
||||
.PP
|
||||
To convert the second of three columns from Fahrenheit to Celcius:
|
||||
.PP
|
||||
.B
|
||||
chan_add -32 3 1
|
||||
.br
|
||||
.B
|
||||
chan_mult 0.56 3 1
|
||||
.SH BUGS
|
||||
The files must contain numbers and whitespaces only.
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1993-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
Executable
+67
@@ -0,0 +1,67 @@
|
||||
/* C H A N _ M U L T . C
|
||||
*
|
||||
* Multiply specified columns of data by a given factor.
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
double factor, temp;
|
||||
int i,j,doit, of, count, val, *col_list;
|
||||
|
||||
if (argc < 4){
|
||||
fprintf(stderr,"Usage: chan_mult factor num_columnss column [col ... ] < in.file > out.file\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
sscanf(*(argv+1),"%lf",&factor);
|
||||
sscanf(*(argv+2),"%d",&of);
|
||||
col_list = (int *) calloc(argc-2,sizeof(int));
|
||||
for (i=3;i<argc;i++){
|
||||
sscanf(*(argv+i),"%d",col_list+(i-3));
|
||||
}
|
||||
|
||||
count = 0;
|
||||
while (!feof(stdin)){
|
||||
val = scanf("%lf",&temp);
|
||||
if (val<1)
|
||||
;
|
||||
else {
|
||||
doit = 0;
|
||||
for (j=0;j<argc-3;j++){
|
||||
if (col_list[j]==count)
|
||||
doit = 1;
|
||||
}
|
||||
if (doit)
|
||||
printf("%.10g\t",temp*factor);
|
||||
else
|
||||
printf("%.10g\t",temp);
|
||||
}
|
||||
if ( count == (of-1))
|
||||
printf("\n");
|
||||
count = (count+1)%of;
|
||||
}
|
||||
return( 0 );
|
||||
}
|
||||
Executable
+70
@@ -0,0 +1,70 @@
|
||||
.TH CHAN_PERMUTE.C 1 BRL/CAD
|
||||
.SH NAME
|
||||
chan_permute - operate on columns of files.
|
||||
.SH SYNOPSIS
|
||||
.B chan_permute
|
||||
.B -i infile1 id id ...
|
||||
.B [-i infile2 id ...]
|
||||
.B -o outfile1 id id ...
|
||||
.B [-o outfile2 id ...]
|
||||
.SH DESCRIPTION
|
||||
This program mixes, matches, and merges ASCII files organized in
|
||||
channels or columns. Each word, separated by whitespaces, should be less
|
||||
than 40 characters long. The channels in each input file are specified
|
||||
and then mapped to the desired channels in the output file(s). These are
|
||||
the sort of things that can be done using
|
||||
.I cut
|
||||
and
|
||||
.I paste,
|
||||
but when
|
||||
working on animation tables it's often nice to be able to do it in one
|
||||
step.
|
||||
.PP
|
||||
.BR Infile s
|
||||
are files to be read from,
|
||||
.BR outfile s
|
||||
are files to be written
|
||||
to, and each
|
||||
.B id
|
||||
is a small positive integer identifying a channel. All of the
|
||||
input
|
||||
.BR id 's
|
||||
should be distinct integers, or the results are not guaranteed.
|
||||
.PP
|
||||
.I Chan_permute
|
||||
interprets
|
||||
.B -i stdin
|
||||
as standard input and
|
||||
.B -o stdout
|
||||
as
|
||||
standard output.
|
||||
.SH EXAMPLES
|
||||
The command
|
||||
.sp
|
||||
chan_permute -i foo 0 1 2 -o stdout 2 1 0
|
||||
.sp
|
||||
reverses the order of foo's three columns and sends them to standard output.
|
||||
.sp
|
||||
.sp
|
||||
The command
|
||||
.sp
|
||||
chan_permute -i file1 0 1 -i file2 2 3 -o file3 2 0 1 -o file4 3 0 1
|
||||
.sp
|
||||
creates file3 and file4, each containing one of the columns of file2
|
||||
followed by both columns of file1.
|
||||
.SH BUGS
|
||||
A given file may be referenced
|
||||
more than once for input, but may not be referenced for input and output
|
||||
together or output and output together. In the latter case, the second
|
||||
output reference overrides the other. The
|
||||
.BR id 's
|
||||
must be integers
|
||||
somewhere between 0 and the number of arguments, inclusive.
|
||||
.SH AUTHOR
|
||||
Carl J. Nuzman
|
||||
.SH COPYRIGHT
|
||||
This software is Copyright (C) 1993-2004 by the United States Army
|
||||
in all countries except the USA. All rights reserved.
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
Executable
+152
@@ -0,0 +1,152 @@
|
||||
/* C H A N _ P E R M U T E . C
|
||||
*
|
||||
* This program mixes, matches, and merges files organized in
|
||||
* channels or columns.
|
||||
* It's nothing cut and paste can't do, but sometimes it's nice to
|
||||
* be able to do it in one step, especially when working with animation
|
||||
* tables.
|
||||
*Usage: channel -i infile1 id id id ... [-i infile2 ...] -o outfile1 id id ...
|
||||
* [-o outfile2 ...]
|
||||
*where infiles are files to be read from, outfiles are files to be written
|
||||
*to, and each id is a small positive integer identifying a channel. All of the
|
||||
*input id's should be distinct integers, or the results are not guaranteed.
|
||||
*
|
||||
* Author -
|
||||
* Carl J. Nuzman
|
||||
*
|
||||
* Source -
|
||||
* The U. S. Army Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005-5068 USA
|
||||
*
|
||||
* Distribution Notice -
|
||||
* Re-distribution of this software is restricted, as described in
|
||||
* your "Statement of Terms and Conditions for the Release of
|
||||
* The BRL-CAD Pacakge" agreement.
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1993-2004 by the United States Army
|
||||
* in all countries except the USA. All rights reserved.
|
||||
*/
|
||||
#include "conf.h"
|
||||
|
||||
#ifdef USE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAXLEN 40
|
||||
|
||||
typedef char Word[MAXLEN];
|
||||
|
||||
struct unit {
|
||||
FILE *file;
|
||||
int channels;
|
||||
short *list;
|
||||
unsigned i_o; /*i=1 o=0*/
|
||||
};
|
||||
|
||||
|
||||
char ihead[] = "-i";
|
||||
char ohead[] = "-o";
|
||||
|
||||
int
|
||||
main(argc,argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int i,j, maxlength,num_done;
|
||||
int icount, ocount;
|
||||
struct unit *x, *y;
|
||||
Word *arrayd;
|
||||
|
||||
i=j=icount = ocount = maxlength = 0;
|
||||
for(i=1;i<argc;i++){
|
||||
if( !strncmp(argv[i],ihead,2) ){
|
||||
j=0;
|
||||
icount++;
|
||||
}
|
||||
else if( !strncmp(argv[i],ohead,2) ){
|
||||
j=0;
|
||||
ocount++;
|
||||
}
|
||||
else
|
||||
maxlength = (++j>maxlength) ? j : maxlength;
|
||||
}
|
||||
|
||||
y = (struct unit *) calloc(icount+ocount,sizeof(struct unit));
|
||||
x = y - 1;
|
||||
for(i=1;i<argc;i++){
|
||||
if( !strncmp(argv[i],"-",1) ){
|
||||
j=0;
|
||||
x++;
|
||||
x->list = (short *) calloc(maxlength,sizeof(short));
|
||||
if (argv[i][1] == 'i'){
|
||||
i++;
|
||||
(x)->i_o = 1;
|
||||
if ( ! strcmp(argv[i],"stdin") )
|
||||
x->file = stdin;
|
||||
else if ( !(x->file = fopen(argv[i],"r")) )
|
||||
fprintf(stderr,"Channel: can't open %s\n",argv[i]);
|
||||
}
|
||||
else if (argv[i][1] == 'o'){
|
||||
i++;
|
||||
(x)->i_o = 0;
|
||||
if ( ! strcmp(argv[i],"stdout") )
|
||||
x->file = stdout;
|
||||
else if ( !(x->file = fopen(argv[i],"w")) )
|
||||
fprintf(stderr,"Channel: can't write to %s\n",argv[i]);
|
||||
}
|
||||
else{
|
||||
fprintf(stderr,"Illegal option %c\n",argv[i][1]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
else{
|
||||
sscanf(argv[i],"%hd",x->list+(j++));
|
||||
x->channels++;
|
||||
}
|
||||
}
|
||||
arrayd = (Word *) calloc(argc,sizeof(Word));/*may use more memory than absolutely necessary*/
|
||||
num_done = 0;
|
||||
while(num_done < icount ){ /* go until all in files are done */
|
||||
num_done = 0;
|
||||
for (x=y;x<y+ocount+icount;x++){ /* do one line */
|
||||
if(num_done >= icount)
|
||||
;/*chill - all in files done */
|
||||
else if (x->i_o == 1){
|
||||
if(feof(x->file))
|
||||
num_done += 1;
|
||||
else
|
||||
for(j=0;j<x->channels;j++)
|
||||
fscanf(x->file,"%s ",arrayd[x->list[j]]);
|
||||
}
|
||||
else if (x->i_o == 0){
|
||||
for(j=0;j<x->channels;j++)
|
||||
fprintf(x->file,"%s\t",arrayd[x->list[j]]);
|
||||
fprintf(x->file,"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
free(arrayd);
|
||||
for (x=y;x<y+ocount+icount;x++){
|
||||
free(x->list);
|
||||
}
|
||||
free(y);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int max(m,n) /*return greatest of n integers, unless one is greater than n*/
|
||||
int m[],n;
|
||||
{
|
||||
int i,j;
|
||||
j = 0;
|
||||
for (i=0;i<n;i++){
|
||||
j = (m[i]>j) ? m[i] : j;
|
||||
}
|
||||
return( (j>n) ? 0 : j );
|
||||
}
|
||||
@@ -1,246 +0,0 @@
|
||||
Annotation and view-object rendering notes
|
||||
==========================================
|
||||
|
||||
Scope
|
||||
-----
|
||||
|
||||
BRL-CAD has two related, but deliberately distinct, ways to represent visual
|
||||
markup:
|
||||
|
||||
* An annotation is an ID_ANNOT database primitive. It is persistent model
|
||||
content with enough semantic and presentation information to be reproduced
|
||||
outside the application that created it.
|
||||
* A view object is application-owned scene state. It is useful for interactive
|
||||
construction and manipulation, but is intentionally not backed by a database
|
||||
object.
|
||||
|
||||
They share portions of the interactive display infrastructure, but they do not
|
||||
currently have interchangeable ownership, lifetime, or rendering semantics.
|
||||
|
||||
|
||||
Annotation capabilities
|
||||
-----------------------
|
||||
|
||||
An rt_annot_internal stores a model-space anchor, a set of 2D vertices, and
|
||||
either a model plane basis or screen-space placement. Its segment types cover
|
||||
lines, circular arcs, NURBS, Beziers, text, and filled polygons. Segment style
|
||||
records include a semantic role, line pattern and width, RGBA color, font or
|
||||
symbol, text scaling, and decorative flags.
|
||||
|
||||
The libged annotate command can create styled text, leaders, linear/angular/
|
||||
radius/diameter/ordinate dimensions, and bounding-box autodim groups. It can
|
||||
regenerate derived annotations from saved attributes and associate them with
|
||||
source model objects without making them part of those objects' CSG trees.
|
||||
|
||||
Annotations therefore have the properties needed for persistent markup:
|
||||
|
||||
* database naming, paths, transforms, and instances;
|
||||
* survival across save/reopen and transfer to another application;
|
||||
* semantic segment roles and per-segment presentation data;
|
||||
* model-space and view-dependent screen-space placement; and
|
||||
* high-level generation metadata and source-object associations.
|
||||
|
||||
An annotation is informational coverage, not a CSG solid. The raytracing
|
||||
implementation preserves that distinction. It prepares annotation coverage
|
||||
from active database paths and composites it on primary samples after ordinary
|
||||
geometry has established color and depth. Model-space annotation coverage is
|
||||
occluded by nearer solid geometry. Screen-space annotation coverage uses the
|
||||
render view and image dimensions. Annotations do not acquire artificial
|
||||
volume, alter model bounds, cast shadows, or participate in reflection and
|
||||
refraction rays.
|
||||
|
||||
Visible coverage is returned in back-to-front layers. Model-space layers are
|
||||
ordered by ray distance, followed by view-space layers ordered by projected
|
||||
anchor depth; segment draw order breaks ties within an annotation. This lets
|
||||
the image renderers apply source-over alpha consistently while retaining the
|
||||
single-frontmost-hit query for compatibility. NIRT continues to report one
|
||||
frontmost segment per model-space annotation rather than exposing these
|
||||
presentation layers as solid partitions.
|
||||
|
||||
Color follows normal database tree state. An annotation segment with an
|
||||
explicit RGBA style wins; otherwise it inherits the resolved combination-path
|
||||
color; otherwise it is white. The legacy region-ID color table is not applied
|
||||
to annotation display or coverage, since annotations are informational leaves
|
||||
rather than regions.
|
||||
|
||||
Prepared coverage uses the existing libbg RTree implementation. A 3D RTree
|
||||
culls model-space annotation instances and a 2D local RTree culls segments
|
||||
inside every annotation. Screen-space instance extents cannot be placed in a
|
||||
static world-space index because they change with the view, so those instances
|
||||
remain in a compact list while still using their local segment RTree. This
|
||||
avoids a new spatial data structure and keeps prepared scenes immutable and
|
||||
safe for concurrent sample queries.
|
||||
|
||||
The rt, ART, and ADRT/ISST integrations follow this overlay model. ERT invokes
|
||||
rt with the database, displayed database paths, and view, so database-backed
|
||||
annotations can follow that route as well. ERT does not currently serialize
|
||||
or pass application-owned view objects to its subprocess.
|
||||
|
||||
NIRT keeps annotation diagnostics opt-in. `useannot 1` enables model-space
|
||||
annotation intersections, and the `fmt a` action reports them. Default NIRT
|
||||
output is unchanged. Screen-space annotations are deliberately omitted
|
||||
because a NIRT ray does not define an image size, pixel footprint, or complete
|
||||
model-to-view mapping.
|
||||
|
||||
|
||||
View-object capabilities
|
||||
------------------------
|
||||
|
||||
The core representation is bv_scene_obj. A view set owns shared view objects,
|
||||
and a particular bview can also own local objects. Independent views force
|
||||
local ownership. bv_obj_put recycles objects when their application lifetime
|
||||
ends; the objects are not written to the .g database.
|
||||
|
||||
The `view obj` command exposes the principal markup types:
|
||||
|
||||
* Lines are model-coordinate polylines represented by vlists. Generic scene
|
||||
rendering can add arrowheads to segment ends.
|
||||
* Labels have a model anchor and optional model-space target/leader. Their text
|
||||
is projected and drawn as screen-facing HUD text. If the command omits Z,
|
||||
screen X/Y coordinates are projected onto the current view plane at creation
|
||||
time.
|
||||
* Polygons include general polygons, circles, ellipses, rectangles, and
|
||||
squares. Creation and editing operate on a saved view plane with a view-Z
|
||||
offset. Selection, movement, open/close, area, overlap, and 2D boolean
|
||||
operations are supported. A "fill" is currently a set of hatch lines, not
|
||||
an opaque surface. Polygons can be explicitly imported from or exported to
|
||||
persistent sketch primitives.
|
||||
|
||||
Scene objects also provide object color, transparency, pixel line width, dash
|
||||
style, and arrow dimensions. Not all of these properties have a uniform
|
||||
command interface for every object type.
|
||||
|
||||
There are other visual layers that should not be conflated with these objects.
|
||||
Legacy gv_tcl data/sdata arrows, axes, lines, labels, and polygons have a
|
||||
separate representation. Faceplate/HUD elements are screen UI. Database
|
||||
objects temporarily cloned for editing are also transient, but retain database
|
||||
primitive semantics and live in the database-object scene containers.
|
||||
|
||||
|
||||
Comparison
|
||||
----------
|
||||
|
||||
Both annotations and view objects eventually produce display-manager pixels,
|
||||
often through bv_scene_obj and vlists. That common final path does not make
|
||||
their source representations equivalent.
|
||||
|
||||
Annotations are the canonical choice when markup must be saved, named in a
|
||||
database, instanced, shared, raytraced from a .g file, or understood by another
|
||||
program. View objects are the right choice for application/session state that
|
||||
must be created and manipulated without changing the database.
|
||||
|
||||
Some view objects have a direct annotation analogue, but conversion is not
|
||||
lossless without type-aware logic:
|
||||
|
||||
* A view polyline maps naturally to line segments, including arrowhead style.
|
||||
* A polygon outline and its hatch lines can map to annotation coverage, but the
|
||||
existing view "fill" must not silently become an opaque filled polygon.
|
||||
* A label is hybrid. Its target and leader are model-space geometry while its
|
||||
glyphs remain screen-facing at a projected model anchor.
|
||||
* Arbitrary vlist extraction is insufficient because display-matrix commands,
|
||||
point and line sizes, child objects, glyph behavior, and semantic roles are
|
||||
otherwise lost or ambiguous.
|
||||
|
||||
View-object line width and annotation line width also need an explicit unit
|
||||
policy. View-object widths are display pixels. Screen-space annotation widths
|
||||
are view-dependent coverage widths. A model-space annotation's line_width is
|
||||
used as a scale on the automatically selected model-space stroke width. In
|
||||
other words, removing a separate raytracer "stroke-width" setting does not
|
||||
remove width control: the annotation's existing line_width/`--line-width`
|
||||
style remains the single user-facing control. The renderer interprets it in
|
||||
the appropriate coordinate system rather than exposing a second competing
|
||||
knob.
|
||||
|
||||
|
||||
Recommended transient rendering design
|
||||
--------------------------------------
|
||||
|
||||
Do not make librt or the raytracers depend on bv_scene_obj, libbv application
|
||||
containers, or libged. Do not manufacture tubes, TGCs, meshes, or geometry
|
||||
just in front of the view plane. Artificial geometry would affect bounds,
|
||||
depth, shadows, and secondary rays, and would make antialiasing and perspective
|
||||
behavior depend on a fabricated distance from the eye.
|
||||
|
||||
If transient view objects need to appear in raytraced output, use an explicit
|
||||
application-to-renderer snapshot boundary:
|
||||
|
||||
1. The GED/application layer snapshots selected live view objects when a render
|
||||
is launched. This is the only layer that owns their lifetime and semantics.
|
||||
2. A type-aware adapter in libged or libbv translates supported objects into a
|
||||
renderer-neutral overlay/coverage description. It should reuse annotation
|
||||
coverage preparation through an in-memory annotation-instance interface,
|
||||
rather than duplicate line, glyph, and arrow intersection algorithms.
|
||||
3. The snapshot travels with the exact view state: model-to-view transform,
|
||||
perspective, image width and height, and sampling convention. In-process
|
||||
renderers can receive it directly; subprocess rt/ERT needs an explicit
|
||||
serialized side channel.
|
||||
4. Raytracers composite this coverage only on primary image samples, after
|
||||
geometry color and depth are known. It remains outside CSG, model bounds,
|
||||
shadows, reflections, and refractions.
|
||||
5. Initial support should be deliberately finite: polyline strokes and
|
||||
arrowheads, label glyphs and leaders, polygon outlines, and polygon hatches.
|
||||
Faceplate elements and legacy gv_tcl overlays should be separately specified
|
||||
opt-in layers rather than being included accidentally.
|
||||
6. Snapshot records should preserve object name and type, RGBA, visibility,
|
||||
local/shared ownership, presentation units, and source identity. Unsupported
|
||||
object types should produce a deliberate diagnostic or documented omission.
|
||||
|
||||
Application-side compositing of the interactive display-manager layer over an
|
||||
ERT framebuffer is a viable smaller feature if only ERT screen captures need
|
||||
view objects. It would closely reproduce the interactive view, but it would
|
||||
not make the objects available to standalone rt, ART, or ISST output and should
|
||||
not be presented as the general renderer solution.
|
||||
|
||||
Conversion between the two systems should remain explicit. Automatically
|
||||
turning view objects into database annotations would violate their deliberately
|
||||
transient contract. A user command to promote selected view markup to a
|
||||
persistent annotation would be reasonable; polygon-to-sketch export is an
|
||||
existing precedent. Conversely, a view-object editor may be used as a front
|
||||
end for constructing an annotation, provided the persistence action is clear.
|
||||
|
||||
|
||||
Maintenance findings before implementing the adapter
|
||||
----------------------------------------------------
|
||||
|
||||
Several representation issues should be corrected before type-driven snapshot
|
||||
conversion is relied upon:
|
||||
|
||||
* Container-selection flags (BV_DB_OBJS, BV_VIEW_OBJS, BV_LOCAL_OBJS, and
|
||||
BV_CHILD_OBJS) reuse numeric bits also used for semantic s_type_flags
|
||||
(BV_DBOBJ_BASED, BV_VIEWONLY, BV_LINES, and others). bv_obj_create currently
|
||||
assigns its type argument to s_type_flags. A local view object consequently
|
||||
acquires BV_LINES incidentally, while the line command does not explicitly
|
||||
tag lines. The namespaces should be separated and every object explicitly
|
||||
typed.
|
||||
* Lines, labels, and polygons should have unambiguous type tags and per-type
|
||||
lifecycle/extraction callbacks. Snapshot conversion must inspect typed data,
|
||||
not infer semantics from a rendered vlist.
|
||||
* Label construction should initialize every bv_label field deliberately,
|
||||
including size, line_flag, anchor, arrow, and target. Current construction
|
||||
does not establish all of those values on every path.
|
||||
* The status of legacy gv_tcl overlay data should be decided explicitly:
|
||||
migrate it, support it through a separate adapter, or document its exclusion.
|
||||
* Screen-space annotation display and raytrace units need a parity test. The
|
||||
legacy display-matrix vlist path and the ray coverage path currently express
|
||||
screen offsets through different mechanisms; their apparent agreement must
|
||||
be verified rather than assumed.
|
||||
* Per-segment annotation colors exceed the legacy interactive vlist object's
|
||||
single-color model. Uniform annotate-command colors work today, but true
|
||||
multicolor interactive parity may require split scene objects or a richer
|
||||
display representation.
|
||||
|
||||
Tests for a future adapter should cover shared and local ownership, cleanup,
|
||||
label anchors and leaders, polygon holes/hatches/view-Z, perspective, pixel
|
||||
width, model-space occlusion, screen-space overlay, and serialization across
|
||||
the ERT subprocess boundary.
|
||||
|
||||
|
||||
Conclusion
|
||||
----------
|
||||
|
||||
Persistent annotations and transient view objects should continue to coexist.
|
||||
The annotation coverage scene is the correct renderer-side abstraction for
|
||||
both saved annotations and a future snapshot of transient markup. The
|
||||
application should perform the semantic conversion and transfer a view-complete
|
||||
snapshot; the renderer should treat it as primary-ray coverage, never as
|
||||
invented scene geometry.
|
||||
@@ -0,0 +1,51 @@
|
||||
This is awf, the Amazingly Workable Formatter -- a "nroff -man" or
|
||||
(subset) "nroff -ms" clone written entirely in (old) awk.
|
||||
|
||||
It is slow and has many restrictions, but does a decent job on most
|
||||
manual pages and simple -ms documents, and isn't subject to AT&T's
|
||||
brain-damaged licensing that denies many System V users any text
|
||||
formatter at all. It is also a text formatter that is simple enough
|
||||
to be tinkered with, for people who want to experiment.
|
||||
|
||||
Type "make r" to run a regression test, formatting the manual page
|
||||
(awf.1) and comparing it to a preformatted copy (awf.1.out). Type
|
||||
"make install" to install it. Pathnames may need changing.
|
||||
|
||||
I don't know whether awf will run on 16-bit machines. Data requirements
|
||||
are modest, but I fear the programs are probably big enough to run awk
|
||||
out of space.
|
||||
|
||||
I can't believe I really wrote this.
|
||||
|
||||
Henry Spencer at U of Toronto Zoology
|
||||
henry@zoo.toronto.edu utzoo!henry
|
||||
13 July 1990
|
||||
/*
|
||||
* Copyright 1990 University of Toronto. All rights reserved.
|
||||
* Written by Henry Spencer.
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or of the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. The author is not responsible for the consequences of use of this
|
||||
* software, no matter how awful, even if they arise from flaws in it.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Since few users ever read sources,
|
||||
* credits must appear in the documentation.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software. Since few users
|
||||
* ever read sources, credits must appear in the documentation.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
As required by the above notice, you are informed that this software
|
||||
has been slightly modified to become the formatter for the fallback
|
||||
manual-page reading software for the BRL-CAD Package.
|
||||
If you wish an unmodified copy of AWF, you should contact the original
|
||||
author at the address above.
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* awf/Cakefile
|
||||
*
|
||||
* The actual formatter is located in "../brlman", because it needs to
|
||||
* be installed in BINDIR.
|
||||
*
|
||||
* Note: The file "brlman/awf" needs to be modified when the definition of
|
||||
* ETCDIR is changed.
|
||||
*/
|
||||
#include "../Cakefile.defs"
|
||||
|
||||
#define PRODUCTS common dev.dumb mac.man mac.ms \
|
||||
pass1 pass2.base pass2.man pass2.ms pass3 \
|
||||
AWF_COPYRIGHT
|
||||
#define SRCDIR awf
|
||||
#undef BINDIR
|
||||
#define BINDIR ETCDIR
|
||||
#undef BINPERM
|
||||
#define BINPERM MANPERM
|
||||
#define FILES /**/
|
||||
#define SRCSUFF /**/
|
||||
#define MANSECTION 1
|
||||
|
||||
#define STATIC_PRODUCTS PRODUCTS /* Force PRODUCTS into dist */
|
||||
|
||||
/*
|
||||
* There is nothing to compile.
|
||||
* The "install-prod" rule should install PRODUCTS,
|
||||
* and "inst-dist" rule should take care of copying to distribution dir.
|
||||
* Nothing else to do.
|
||||
*/
|
||||
all&:
|
||||
@echo "SRCDIR: all done"
|
||||
|
||||
#include "../Cakefile.rules"
|
||||
@@ -0,0 +1,212 @@
|
||||
.\" Some of the stuff in this file is a bit contorted, because it's also
|
||||
.\" the regression-test input.
|
||||
.nr ES 5n
|
||||
.de ES
|
||||
.PP
|
||||
.in +\\n(ESu
|
||||
.nf
|
||||
..
|
||||
.de EE
|
||||
.in -\\n(ESu
|
||||
.fi
|
||||
.PP
|
||||
..
|
||||
.de PT
|
||||
.ie \\n(.$>1 .TP "\\$2"
|
||||
.el .TP
|
||||
.ie !'\\$1'' \\$1
|
||||
.el \(bu
|
||||
..
|
||||
.ds Nr \fInroff\fR
|
||||
.TH AWF 1 "13 July 1990"
|
||||
.BY "U of Toronto"
|
||||
.SH NAME
|
||||
awf \- amazingly workable (text) formatter
|
||||
.SH SYNOPSIS
|
||||
.B awf
|
||||
.BI \-m acros
|
||||
[ file ] ...
|
||||
.SH DESCRIPTION
|
||||
.if t .tm OOPS -- AWF THINKS IT'S TROFF!!!
|
||||
.I Awf
|
||||
formats the text from the input \fIfile\fR(s)
|
||||
(standard input if none)
|
||||
in an imitation of
|
||||
\*(Nr's style with the \fB\-man\fR or \fB\-ms\fR macro packages.
|
||||
The
|
||||
.BI \-m acro
|
||||
option is mandatory and must be `\-man' or `\-ms'.
|
||||
.PP
|
||||
.I Awf
|
||||
implements the following raw \*(Nr requests:
|
||||
.LP
|
||||
.\e" .ce .fi .in .ne .pl .sp
|
||||
.ad .de .ft .it .nf .po .ta
|
||||
.bp .ds .ie .ll .nr .ps .ti
|
||||
.br .el .if .na .ns .rs .tm
|
||||
.LP
|
||||
and the following in-text codes:
|
||||
.ES
|
||||
\e$ \e% \e* \ec \ef \en \es
|
||||
.EE
|
||||
plus the full list of \*(Nr/\c
|
||||
.I troff
|
||||
special characters in
|
||||
the original V7 \fItroff\fR manual.
|
||||
.PP
|
||||
Many restrictions are present; the behavior in general is a subset of
|
||||
\*(Nr's. Of particular note are the following:
|
||||
.IP \(bu 2
|
||||
Point sizes do not exist;
|
||||
.B .ps
|
||||
and
|
||||
.B \es
|
||||
are ignored.
|
||||
.PT
|
||||
Conditionals implement only numeric comparisons on
|
||||
.BR \en(.$ ,
|
||||
string com\%par\%isons between a macro parameter and a literal,
|
||||
and
|
||||
.B n
|
||||
(always true)
|
||||
and
|
||||
.BR t
|
||||
(always false).
|
||||
.PT
|
||||
The implementation of strings is generally primitive.
|
||||
.IP \(bu
|
||||
Expressions in (e.g.)\&
|
||||
.B .sp
|
||||
are fairly general, but the
|
||||
.BR | ,
|
||||
.BR & ,
|
||||
and
|
||||
.BR :\&
|
||||
operators do not exist, and the implementation of
|
||||
.B \ew
|
||||
requires that quote (') be used as the delimiter and
|
||||
simply counts the characters inside (so that, e.g.,
|
||||
\ew'\e(bu'
|
||||
equals 4).
|
||||
.P
|
||||
White space at the beginning of lines,
|
||||
and imbedded white space within lines, is dealt with properly.
|
||||
Sentence terminators at ends of lines are understood to imply
|
||||
extra space afterward in filled lines.
|
||||
Tabs are im\%plemented crudely and not quite correctly, although
|
||||
in most cases they work as expected.
|
||||
Hyphenation is done only at explicit hyphens, em-dashes, and \*(Nr
|
||||
discretionary hyphens.
|
||||
.SH "MAN MACROS"
|
||||
The
|
||||
.B \-man
|
||||
macro set implements the full V7 manual macros,
|
||||
plus a few semi-random oddballs.
|
||||
The full list is:
|
||||
.ES
|
||||
\&.B .DT .IP .P .RE .SM
|
||||
\&.BI .HP .IR .PD .RI .TH
|
||||
\&.BR .I .LP .PP .RS .TP
|
||||
\&.BY .IB .NB .RB .SH .UC
|
||||
.EE
|
||||
.B .BY
|
||||
and
|
||||
.B .NB
|
||||
each take a single string argument (respectively, an indi\%cation of
|
||||
authorship and a note about the status of the manual page) and arrange
|
||||
to place it in the page footer.
|
||||
.SH "MS MACROS"
|
||||
The
|
||||
.B \-ms
|
||||
macro set is a substantial subset of the V7 manuscript macros.
|
||||
The implemented macros are:
|
||||
.ES
|
||||
\&.AB .CD .ID .ND .QP .RS .UL
|
||||
\&.AE .DA .IP .NH .QS .SH .UX
|
||||
\&.AI .DE .LD .NL .R .SM
|
||||
\&.AU .DS .LG .PP .RE .TL
|
||||
\&.B .I .LP .QE .RP .TP
|
||||
.EE
|
||||
Size changes are recognized but ignored, as are
|
||||
.B .RP
|
||||
and
|
||||
.BR .ND .
|
||||
.B .UL
|
||||
just prints its argument in italics.
|
||||
.BR .DS / .DE
|
||||
does not do a keep,
|
||||
nor do any of the other macros that normally imply keeps.
|
||||
.PP
|
||||
Assignments to the header/footer string variables are recognized and
|
||||
implemented, but there is otherwise no control over header/footer
|
||||
formatting.
|
||||
The
|
||||
.B DY
|
||||
string variable is available.
|
||||
The
|
||||
.BR PD ,
|
||||
.BR PI ,
|
||||
and
|
||||
.BR LL
|
||||
number registers exist and can be changed.
|
||||
.SH OUTPUT
|
||||
The only output format supported by
|
||||
.IR awf ,
|
||||
in its distributed form,
|
||||
is that appropriate to a dumb terminal,
|
||||
using overprinting for italics (via underlining) and bold.
|
||||
The \*(Nr special characters are printed as some vague approximation
|
||||
(it's sometimes very vague) to their correct appearance.
|
||||
.PP
|
||||
.IR Awf 's
|
||||
knowledge of the output device is established by a device file,
|
||||
which is read before the user's input.
|
||||
It is sought in
|
||||
.IR awf 's
|
||||
library directory, first as
|
||||
.BI dev. term
|
||||
(where \fIterm\fR is the value of the TERM environment variable)
|
||||
and, failing that, as
|
||||
.BR dev.dumb .
|
||||
The device file
|
||||
uses special internal commands
|
||||
to set up resolution, special characters, fonts, etc.,
|
||||
and more normal \*(Nr commands to set up page length etc.
|
||||
.SH FILES
|
||||
All in \fI/usr/lib/awf\fR (this can be overridden by the AWFLIB
|
||||
environment variable):
|
||||
|
||||
.ta \w'pass2.base'u+((3n-1n)/2u)
|
||||
.nf
|
||||
common common device-independent initialization
|
||||
dev.* device-specific initialization
|
||||
mac.m* macro packages
|
||||
pass1 macro substituter
|
||||
pass2.base central formatter
|
||||
pass2.m* macro-package-specific bits of formatter
|
||||
pass3 line and page composer
|
||||
.SH SEE ALSO
|
||||
awk(1), nroff(1), man(7), ms(7)
|
||||
.SH DIAGNOSTICS
|
||||
.na
|
||||
Unlike
|
||||
.IR nroff ,
|
||||
.I awf
|
||||
complains whenever it sees unknown commands and macros.
|
||||
All diagnostics (these and some internal ones) appear on standard error
|
||||
at the end of the run.
|
||||
.ad
|
||||
.SH HISTORY
|
||||
Written at University of Toronto by Henry Spencer,
|
||||
more or less as a supplement to the C News project.
|
||||
.LP
|
||||
.ce 99
|
||||
\(rh None of the above really want to admit it. \(lh
|
||||
.ce 0
|
||||
.SH BUGS
|
||||
There are plenty, but what do you expect for a text formatter
|
||||
written entirely in (old) \fIawk\fR?
|
||||
.PP
|
||||
The
|
||||
.B \-ms
|
||||
stuff has not been checked out very thoroughly.
|
||||
@@ -0,0 +1,7 @@
|
||||
.\" Common startup code, fully device-independent.
|
||||
.\" --------------------------------
|
||||
.fi
|
||||
.ce 0
|
||||
.ta +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5
|
||||
.in 0
|
||||
.ti 0
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
.\" Device-dependent but not macro-set-dependent definitions.
|
||||
.\" --------------------------------
|
||||
.\" overall formatting initialization
|
||||
.\" 12 cpi horizontal exploits 80-column terminal well (6.5i@12 = 78)
|
||||
.^r cpi 12 6
|
||||
.\" call margin adjustment device-dependent for sake of some unusual cases
|
||||
.ad
|
||||
.\" page parameters
|
||||
.pl 11i
|
||||
.ll 6.5i
|
||||
.po 0
|
||||
.\" --------------------------------
|
||||
.\" fonts, and their hyphens, last font change doubled to set up \fP
|
||||
.^f R
|
||||
.ft R
|
||||
.^c hy 1 -
|
||||
.^f I
|
||||
.ft I
|
||||
.^c hy 1 -
|
||||
.^f B
|
||||
.ft B
|
||||
.^c hy 1 -\b-\b-
|
||||
.ft R
|
||||
.ft R
|
||||
.\" --------------------------------
|
||||
.\" definitions of nroff special characters
|
||||
.\" The character definitions here operate on the "better ugly than invisible"
|
||||
.\" principle, and try to approximate the character *somehow*. They were
|
||||
.\" tuned for a Teletype 40 line printer, but should give vaguely plausible
|
||||
.\" results on any overprinting ASCII device.
|
||||
.\"
|
||||
.\" first, things that nroff considered builtins
|
||||
.^c \ 1 \\
|
||||
.^c e 1 \\
|
||||
.^c ' 1 '
|
||||
.^c ` 1 `
|
||||
.^c - 1 -
|
||||
.\" some things seem to assume that \+ is like \-
|
||||
.^c + 1 +
|
||||
.\" we do not do backslash-space here, it can't be done with .^c, but the
|
||||
.\" other forms of space we can do
|
||||
.^c 0 1 "
|
||||
.^c | 0
|
||||
.^c ^ 0
|
||||
.^c & 0
|
||||
.\"
|
||||
.\" and more normal characters
|
||||
.\" note, the hyphenation logic knows about em
|
||||
.^c em 2 --
|
||||
.\" hy is a special case, see above
|
||||
.^c bu 1 +\bo
|
||||
.^c sq 2 []
|
||||
.^c ru 1 _
|
||||
.^c 12 3 1/2
|
||||
.^c 14 3 1/4
|
||||
.^c 34 3 3/4
|
||||
.^c de 1 '\b`
|
||||
.^c dg 1 -\b!
|
||||
.^c fm 1 '
|
||||
.^c ct 1 /\bc
|
||||
.^c rg 3 (R)
|
||||
.^c co 3 (c)
|
||||
.^c pl 1 +
|
||||
.^c mi 1 -
|
||||
.^c eq 1 =
|
||||
.^c ** 1 *
|
||||
.^c sc 1 j\bf
|
||||
.^c aa 1 '
|
||||
.^c ga 1 `
|
||||
.^c ul 1 _
|
||||
.^c sl 1 /
|
||||
.^c *a 1 <\ba
|
||||
.^c *b 1 ,\bB
|
||||
.^c *g 1 ,\by
|
||||
.^c *d 1 S\bo
|
||||
.^c *e 1 -\bc
|
||||
.^c *z 1 ,\bL
|
||||
.^c *y 1 ,\bn
|
||||
.^c *h 1 -\b0
|
||||
.^c *i 1 ,\bi
|
||||
.^c *k 1 <\bK
|
||||
.^c *l 1 \\\b>
|
||||
.^c *m 1 ,\bu
|
||||
.^c *n 1 ,\bv
|
||||
.^c *c 1 ,\b3
|
||||
.^c *o 1 o
|
||||
.^c *p 1 -\bn
|
||||
.^c *r 1 p
|
||||
.^c *s 1 -\bo
|
||||
.^c ts 1 s
|
||||
.^c *t 1 ~\bt
|
||||
.^c *u 1 u
|
||||
.^c *f 1 /\bo
|
||||
.^c *x 1 /\b\\
|
||||
.^c *q 1 |\bu
|
||||
.^c *w 1 u\bw
|
||||
.^c *G 2 ~\b|~
|
||||
.^c *D 2 _\b/_\b\\
|
||||
.^c *H 1 -\bO
|
||||
.^c *L 2 /\\
|
||||
.^c *C 1 _\b-\b~
|
||||
.^c *P 2 ~\b|~\b|
|
||||
.^c *S 1 ~\b_\b>
|
||||
.^c *U 1 Y
|
||||
.^c *F 1 |\bO
|
||||
.^c *Q 1 |\bU
|
||||
.^c *W 2 _\b(_\b)
|
||||
.^c sr 2 \\/
|
||||
.^c rn 1 ~
|
||||
.^c >= 1 _\b>
|
||||
.^c <= 1 _\b<
|
||||
.^c == 1 _\b=
|
||||
.^c ~= 1 ~\b=
|
||||
.^c ap 1 ~
|
||||
.^c != 1 /\b=
|
||||
.^c -> 2 ->
|
||||
.^c <- 2 <-
|
||||
.^c ua 1 |\b^
|
||||
.^c da 1 |\bv
|
||||
.^c mu 1 x
|
||||
.^c di 1 -\b:
|
||||
.^c +- 1 _\b+
|
||||
.^c cu 1 U
|
||||
.^c ca 3 (^)
|
||||
.^c sb 2 (_\b~
|
||||
.^c sp 2 _\b~)
|
||||
.^c ib 2 (~\b_\b=
|
||||
.^c ip 2 ~\b_\b=)
|
||||
.^c if 2 oo
|
||||
.^c pd 1 3\bo
|
||||
.^c gr 1 ~\bV
|
||||
.^c no 1 -
|
||||
.^c is 1 '\b,\bI
|
||||
.^c pt 2 oc
|
||||
.^c es 1 /\bO
|
||||
.^c mo 1 -\bC
|
||||
.^c br 1 |
|
||||
.^c dd 1 I\b|
|
||||
.^c rh 1 =\b>
|
||||
.^c lh 1 =\b<
|
||||
.^c bs 4 (:-)
|
||||
.^c or 1 |
|
||||
.^c ci 1 O
|
||||
.^c lt 1 ~\b(
|
||||
.^c lb 1 _\b(
|
||||
.^c rt 1 ~\b)
|
||||
.^c rb 1 _\b)
|
||||
.^c lk 1 -\b(
|
||||
.^c rk 1 -\b)
|
||||
.^c bv 1 |
|
||||
.^c lf 1 _\b[
|
||||
.^c rf 1 _\b]
|
||||
.^c lc 1 ~\b[
|
||||
.^c rc 1 ~\b]
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
.\"-----------------
|
||||
.de TH
|
||||
.ds LH "\\$1(\\$2)
|
||||
.ds CH "Unix Programmer's Manual
|
||||
.ds RH "\\$1(\\$2)
|
||||
.ds LF "
|
||||
.ds CF "\\$3
|
||||
.ds RF "%
|
||||
..
|
||||
.\"-----------------
|
||||
.de NB
|
||||
.ds nb "\\$1
|
||||
.lF
|
||||
..
|
||||
.\"-----------------
|
||||
.de BY
|
||||
.ds by "\\$1
|
||||
.lF
|
||||
..
|
||||
.\"-----------------
|
||||
.de UC
|
||||
.BY "\\$1BSD"
|
||||
..
|
||||
.\"-----------------
|
||||
.\" common initialization for headers and paragraphs: .In need
|
||||
.de In
|
||||
.ne \\$1
|
||||
.sp \\n(PDu
|
||||
.fi
|
||||
.in \\n(inu
|
||||
.ti 0
|
||||
.it
|
||||
.ft R
|
||||
.ns
|
||||
..
|
||||
.\"-----------------
|
||||
.de SH
|
||||
.In 6
|
||||
.in 0
|
||||
.ft B
|
||||
\&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
|
||||
.ft R
|
||||
.nr in 5n
|
||||
.in \\n(inu
|
||||
..
|
||||
.\"-----------------
|
||||
.de LP
|
||||
.In 4
|
||||
..
|
||||
.\"-----------------
|
||||
.de PP
|
||||
.LP
|
||||
..
|
||||
.\"-----------------
|
||||
.de P
|
||||
.LP
|
||||
..
|
||||
.\"-----------------
|
||||
.de HP
|
||||
.In 4
|
||||
.ti 0-\\n(tpu
|
||||
..
|
||||
.\"-----------------
|
||||
.de TP
|
||||
.In 4
|
||||
.if \\n(.$>0 .nr tp \\$1n
|
||||
.in \\n(inu+\\n(tpu
|
||||
.ti 0-\\n(tpu
|
||||
.it 1 tP
|
||||
..
|
||||
.\"-----------------
|
||||
.de IP
|
||||
.ie \\n(.$>1 .TP "\\$2"
|
||||
.el .TP
|
||||
\&\\$1
|
||||
..
|
||||
.\"-----------------
|
||||
.de I
|
||||
.ft I
|
||||
.it 1 fP
|
||||
.if \\n(.$>0 \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
|
||||
..
|
||||
.\"-----------------
|
||||
.de B
|
||||
.ft B
|
||||
.it 1 fP
|
||||
.if \\n(.$>0 \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
|
||||
..
|
||||
.\"-----------------
|
||||
.de IR
|
||||
\&\\fI\\$1\\fR\\$2\\fI\\$3\\fR\\$4\\fI\\$5\\fR\\$6\\fI\\$7\\fR\\$8\\fI\\$9\\fR
|
||||
..
|
||||
.\"-----------------
|
||||
.de RI
|
||||
\&\\$1\\fI\\$2\\fR\\$3\\fI\\$4\\fR\\$5\\fI\\$6\\fR\\$7\\fI\\$8\\fR\\$9
|
||||
..
|
||||
.\"-----------------
|
||||
.de BR
|
||||
\&\\fB\\$1\\fR\\$2\\fB\\$3\\fR\\$4\\fB\\$5\\fR\\$6\\fB\\$7\\fR\\$8\\fB\\$9\\fR
|
||||
..
|
||||
.\"-----------------
|
||||
.de RB
|
||||
\&\\$1\\fB\\$2\\fR\\$3\\fB\\$4\\fR\\$5\\fB\\$6\\fR\\$7\\fB\\$8\\fR\\$9
|
||||
..
|
||||
.\"-----------------
|
||||
.de BI
|
||||
\&\\fB\\$1\\fI\\$2\\fB\\$3\\fI\\$4\\fB\\$5\\fI\\$6\\fB\\$7\\fI\\$8\\fB\\$9\\fR
|
||||
..
|
||||
.\"-----------------
|
||||
.de IB
|
||||
\&\\fI\\$1\\fB\\$2\\fI\\$3\\fB\\$4\\fI\\$5\\fB\\$6\\fI\\$7\\fB\\$8\\fI\\$9\\fR
|
||||
..
|
||||
.\"-----------------
|
||||
.de SM
|
||||
.\" no-op
|
||||
.if \\n(.$>0 \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
|
||||
..
|
||||
.\"-----------------
|
||||
.de DT
|
||||
.ta +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5
|
||||
..
|
||||
.\"-----------------
|
||||
.de RS
|
||||
.in +5n
|
||||
..
|
||||
.\"-----------------
|
||||
.de RE
|
||||
.in -5n
|
||||
..
|
||||
.\"-----------------
|
||||
.de PD
|
||||
.ie \\n(.$=0 .nr PD 0.3v
|
||||
.el .nr PD \\$1n
|
||||
..
|
||||
.\"-----------------
|
||||
.\" misc. initialization
|
||||
.nr tp 5n
|
||||
.PD
|
||||
.ds R \(rg
|
||||
.ds S "
|
||||
.ds Tm (TM)
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
.\"-----------------
|
||||
.de R
|
||||
.ie \\n(.$=0 .ft R
|
||||
.el \\fR\\$1\\fP\\$2
|
||||
..
|
||||
.\"-----------------
|
||||
.de I
|
||||
.ie \\n(.$=0 .ft I
|
||||
.el \\fI\\$1\\fP\\$2
|
||||
..
|
||||
.\"-----------------
|
||||
.de B
|
||||
.ie \\n(.$=0 .ft B
|
||||
.el \\fB\\$1\\fP\\$2
|
||||
..
|
||||
.\"-----------------
|
||||
.de UX
|
||||
.\" old-fashioned capitalization -- I've never gotten used to the new one
|
||||
\\$2Unix\\$1
|
||||
..
|
||||
.\"-----------------
|
||||
.de DA
|
||||
.ds DY "\\$1 \\$2 \\$3
|
||||
.\" keep trailing spaces out of CF
|
||||
.if \\n(.$=1 .ds CF "\\$1
|
||||
.if \\n(.$=2 .ds CF "\\$1 \\$2
|
||||
.if \\n(.$>2 .ds CF "\\$1 \\$2 \\$3
|
||||
..
|
||||
.\"-----------------
|
||||
.de ND
|
||||
.\" it's our default, ignore it
|
||||
..
|
||||
.\"-----------------
|
||||
.de TL
|
||||
.rs
|
||||
.sp 5
|
||||
.ft B
|
||||
.ce 9999
|
||||
..
|
||||
.\"-----------------
|
||||
.de AU
|
||||
.sp 2
|
||||
.ft R
|
||||
..
|
||||
.\"-----------------
|
||||
.de AI
|
||||
.sp
|
||||
.ft R
|
||||
..
|
||||
.\"-----------------
|
||||
.de AB
|
||||
.sp 2
|
||||
.ce 0
|
||||
.ll -7n
|
||||
.in +7n
|
||||
..
|
||||
.\"-----------------
|
||||
.de AE
|
||||
.sp
|
||||
.ll
|
||||
.in
|
||||
..
|
||||
.\"-----------------
|
||||
.\" common initialization for headers and paragraphs: .In need extraspace
|
||||
.de In
|
||||
.ne \\$1
|
||||
.sp \\n(Tsu
|
||||
.nr Ts 0
|
||||
.ie \\n(.$>1 .nr iN \\$2v
|
||||
.el .nr iN 0
|
||||
.sp \\n(PDu+\\n(iNu
|
||||
.ce 0
|
||||
.ft R
|
||||
.in \\n(inu
|
||||
.ll \\n(LLu
|
||||
.ns
|
||||
.fi
|
||||
.ti 0
|
||||
..
|
||||
.\"-----------------
|
||||
.de SH
|
||||
.nr in 0
|
||||
.In 6 1
|
||||
.ft B
|
||||
..
|
||||
.\"-----------------
|
||||
.de NH
|
||||
.nr in 0
|
||||
.In 6 1
|
||||
.ft B
|
||||
.\" punt to awk code to get the header numbering right
|
||||
.nH \\$1
|
||||
.\" and pick up the result
|
||||
\&\\*(Nh
|
||||
..
|
||||
.\"-----------------
|
||||
.de LP
|
||||
.In 4
|
||||
..
|
||||
.\"-----------------
|
||||
.de PP
|
||||
.In 4
|
||||
.ti \\n(PIu
|
||||
..
|
||||
.\"-----------------
|
||||
.de TP
|
||||
.In 4
|
||||
.if \\n(.$>0 .nr tp \\$1n
|
||||
.in \\n(inu+\\n(tpu
|
||||
.ti 0-\\n(tpu
|
||||
.it 1 tP
|
||||
..
|
||||
.\"-----------------
|
||||
.de IP
|
||||
.ie \\n(.$>1 .TP "\\$2"
|
||||
.el .TP
|
||||
\&\\$1
|
||||
..
|
||||
.\"-----------------
|
||||
.de QP
|
||||
.In 4
|
||||
.in +5n
|
||||
.ll -5n
|
||||
..
|
||||
.\"-----------------
|
||||
.de QS
|
||||
.nr in +5n
|
||||
.nr LL -5n
|
||||
.In 4
|
||||
..
|
||||
.\"-----------------
|
||||
.de QE
|
||||
.nr in -5n
|
||||
.nr LL +5n
|
||||
.In 4
|
||||
..
|
||||
.\"-----------------
|
||||
.de DS
|
||||
.In 5
|
||||
.if '\\$1'C' .ce 9999
|
||||
.if '\\$1'' .in +5n
|
||||
.nf
|
||||
..
|
||||
.\"-----------------
|
||||
.de CD
|
||||
.In 5
|
||||
.ce 9999
|
||||
.nf
|
||||
..
|
||||
.\"-----------------
|
||||
.de LD
|
||||
.In 5
|
||||
.nf
|
||||
..
|
||||
.\"-----------------
|
||||
.de ID
|
||||
.In 5
|
||||
.in +5n
|
||||
.nf
|
||||
..
|
||||
.\"-----------------
|
||||
.de DE
|
||||
.In 3
|
||||
..
|
||||
.\"-----------------
|
||||
.de RS
|
||||
.nr in +5n
|
||||
.in \\n(inu
|
||||
..
|
||||
.\"-----------------
|
||||
.de RE
|
||||
.nr in -5n
|
||||
.in \\n(inu
|
||||
..
|
||||
.\"-----------------
|
||||
.de UL
|
||||
\&\\fI$1\\fP
|
||||
..
|
||||
.\"-----------------
|
||||
.de RP
|
||||
..
|
||||
.\"-----------------
|
||||
.de LG
|
||||
..
|
||||
.\"-----------------
|
||||
.de SM
|
||||
..
|
||||
.\"-----------------
|
||||
.de NL
|
||||
..
|
||||
.\"-----------------
|
||||
.\" the -ms accent strings
|
||||
.ds ' "'\b
|
||||
.ds ` "`\b
|
||||
.ds : ":\b
|
||||
.ds ^ "^\b
|
||||
.ds ~ "~\b
|
||||
.ds C "v\b
|
||||
.ds , ",\b
|
||||
.\" post-title spacing
|
||||
.nr Ts 4v
|
||||
.\" and parameter setup
|
||||
.nr LL 6i
|
||||
.ll \n(LLu
|
||||
.nr PD 0.3v
|
||||
.nr PI 5n
|
||||
@@ -0,0 +1,212 @@
|
||||
# first pass: macro expansion and .if
|
||||
# We support macros, conditionals (of three quite limited forms), and macro
|
||||
# argument substitution.
|
||||
BEGIN {
|
||||
curmacro = ""
|
||||
macros[""] = 0 # just to make it an array
|
||||
macrolen[""] = 0 # just to make it an array
|
||||
macrotext[0] = "" # just to make it an array
|
||||
args[""] = "" # just to make it an array
|
||||
ntext = 1 # first slot in macrotext; cannot be 0
|
||||
nroffset = 0 # offset between NR and "real" line numbers
|
||||
inname = "?" # input filename
|
||||
sp = 0 # stack "pointer" (number of stacked macros)
|
||||
maxsp = 25 # limit on nesting depth
|
||||
macrostack[sp] = "" # to make it an array
|
||||
nleftstack[sp] = "" # to make it an array
|
||||
ptrstack[sp] = "" # to make it an array
|
||||
nargstack[sp] = "" # to make it an array
|
||||
argstack[sp] = "" # to make it an array
|
||||
condstack[sp] = "" # to make it an array
|
||||
}
|
||||
/^\.\^#/ { # filename and line no of next line: .^# no fn
|
||||
nroffset = (NR+1) - $2
|
||||
inname = $3
|
||||
print
|
||||
next
|
||||
}
|
||||
/^\.de/ { # macro start
|
||||
curmacro = "." $2
|
||||
macros[curmacro] = ntext
|
||||
macrostart = ntext
|
||||
next
|
||||
}
|
||||
curmacro != "" && $0 !~ /^\.\.$/ { # macro text - \\ becomes \
|
||||
if ($0 !~ /\\/) # quick case, no backslashes
|
||||
line = $0
|
||||
else {
|
||||
line = ""
|
||||
for (n = 1; n <= length; n++) {
|
||||
if (substr($0, n, 2) == "\\\\")
|
||||
n++
|
||||
line = line substr($0, n, 1)
|
||||
}
|
||||
}
|
||||
macrotext[ntext++] = line
|
||||
next
|
||||
}
|
||||
curmacro != "" && $0 ~ /^\.\.$/ { # macro end
|
||||
macrolen[curmacro] = ntext - macrostart
|
||||
curmacro = ""
|
||||
print ".^#", NR - nroffset + 1, inname
|
||||
next
|
||||
}
|
||||
$0 ~ /^\./ && ( macros[$1] != 0 || $0 ~ /^\.(i[ef]|el)/ ) {
|
||||
# something that needs attention
|
||||
print ".^=", NR - nroffset, inname
|
||||
line = $0
|
||||
nleft = 0
|
||||
macro = "<none>"
|
||||
nargs = 0
|
||||
|
||||
while (line != "") {
|
||||
# conditionals; note that 1-n is !n (awk doesn't have !)
|
||||
invert = 0
|
||||
if (line ~ /^\.i[ef] !/)
|
||||
invert = 1
|
||||
prevcond = cond
|
||||
cond = 0
|
||||
if (line !~ /^\.(i[ef]|el)/) { # not conditional
|
||||
cond = 1
|
||||
iflen = 0
|
||||
} else if (line ~ /^\.i[ef] !?\\n\(\.\$[<=>][0-9] /) {
|
||||
# arithmetic comparison on arg count
|
||||
iflen = length(".if .n(.$=x ") + invert
|
||||
n = substr(line, iflen-1, 1) + 0
|
||||
op = substr(line, iflen-2, 1)
|
||||
if (op == "=" && nargs == n)
|
||||
cond = 1
|
||||
else if (op == "<" && nargs < n)
|
||||
cond = 1
|
||||
else if (op == ">" && nargs > n)
|
||||
cond = 1
|
||||
} else if (line ~ /^\.i[ef] !?'\\\$[0-9]'[^']*' /) {
|
||||
# string equality on argument
|
||||
iflen = length(".if '.$n'") + invert
|
||||
n = substr(line, iflen-1, 1)+0
|
||||
if (n <= nargs)
|
||||
s1 = args[n]
|
||||
else
|
||||
s1 = ""
|
||||
i = index(substr(line, iflen+1), "'")
|
||||
s2 = substr(line, iflen+1, i-1)
|
||||
iflen += i+1
|
||||
if (s1 == s2)
|
||||
cond = 1
|
||||
} else if (line ~ /^\.i[ef] !?[nt] /) {
|
||||
# nroff vs troff
|
||||
iflen = length(".if n ") + invert
|
||||
if (substr(line, iflen-1, 1) == "n")
|
||||
cond = 1
|
||||
} else if (line ~ /^\.el /) {
|
||||
cond = 1 - prevcond
|
||||
iflen = length(".el ")
|
||||
} else {
|
||||
line = ".tm unknown .if/.ie form: " line
|
||||
cond = 1
|
||||
iflen = 0
|
||||
}
|
||||
if (invert)
|
||||
cond = 1 - cond
|
||||
if (cond && iflen > 0) # trim true conditional off
|
||||
line = substr(line, iflen+1)
|
||||
|
||||
# do argument substitution, if necessary
|
||||
if (cond && line ~ /\\\$/) {
|
||||
orig = line
|
||||
line = ""
|
||||
for (pos = index(orig, "\\$"); pos > 0; \
|
||||
pos = index(orig, "\\$")) {
|
||||
if (pos > 1)
|
||||
line = line substr(orig, 1, pos-1)
|
||||
c = substr(orig, pos+2, 1)
|
||||
if (c ~ /[0-9]/ && c+0 <= nargs)
|
||||
line = line args[c+0]
|
||||
orig = substr(orig, pos+3)
|
||||
}
|
||||
line = line orig # the remnant
|
||||
}
|
||||
|
||||
# is it an nroff command?
|
||||
if (cond && line ~ /^\./) {
|
||||
cmd = substr(line, 1, 3)
|
||||
while (cmd ~ / $/)
|
||||
cmd = substr(cmd, 1, length(cmd)-1)
|
||||
} else
|
||||
cmd = ""
|
||||
|
||||
# deal with it
|
||||
if (!cond)
|
||||
nop = 0 # nothing
|
||||
else if (cmd == "" || macros[cmd] == 0)
|
||||
print line # not a nested macro
|
||||
else if (sp >= maxsp)
|
||||
print ".tm macros nested too deeply (" sp " levels)"
|
||||
else { # nesting
|
||||
# stack old one
|
||||
sp++
|
||||
nleftstack[sp] = nleft
|
||||
ptrstack[sp] = ptr
|
||||
macrostack[sp] = macro
|
||||
nargstack[sp] = nargs
|
||||
condstack[sp] = cond
|
||||
for (i = 1; i <= nargs; i++)
|
||||
argstack[sp ":" i] = args[i]
|
||||
|
||||
# start new one, mostly pulling arguments apart
|
||||
macro = cmd
|
||||
nleft = macrolen[macro]
|
||||
ptr = macros[macro]
|
||||
cond = 0
|
||||
argno = 1
|
||||
pos = length(macro) + 1
|
||||
for (;;) {
|
||||
while (substr(line, pos, 1) ~ /[ \t]/)
|
||||
pos++
|
||||
if (pos > length(line))
|
||||
break # NOTE BREAK OUT
|
||||
arg = ""
|
||||
if (substr(line, pos, 1) == "\"") {
|
||||
pos++
|
||||
while (substr(line, pos, 1) ~ /[^"]/) {
|
||||
arg = arg substr(line, pos, 1)
|
||||
pos++
|
||||
}
|
||||
pos++
|
||||
} else
|
||||
while (substr(line, pos, 1) ~ /[^ \t]/) {
|
||||
arg = arg substr(line, pos, 1)
|
||||
pos++
|
||||
}
|
||||
args[argno++] = arg
|
||||
}
|
||||
nargs = argno - 1
|
||||
}
|
||||
|
||||
# clean up any completed macros
|
||||
while (nleft <= 0 && sp > 0) {
|
||||
nleft = nleftstack[sp]
|
||||
ptr = ptrstack[sp]
|
||||
macro = macrostack[sp]
|
||||
nargs = nargstack[sp]
|
||||
cond = condstack[sp]
|
||||
for (i = 1; i <= nargs; i++)
|
||||
args[i] = argstack[sp ":" i]
|
||||
sp--
|
||||
}
|
||||
|
||||
# finally, get next line
|
||||
if (nleft > 0) {
|
||||
line = macrotext[ptr++]
|
||||
nleft--
|
||||
} else
|
||||
line = "" # signal loop to terminate
|
||||
}
|
||||
|
||||
print ".^#", NR - nroffset + 1, inname
|
||||
next
|
||||
}
|
||||
{
|
||||
# it's ordinary
|
||||
print
|
||||
}
|
||||
+587
@@ -0,0 +1,587 @@
|
||||
# second pass: interpretation of directives
|
||||
# A macro-set-specific portion gets interpolated into this at the "#include"
|
||||
# line. As a minimum, it must deal with .^b and .^e and with any input traps.
|
||||
BEGIN {
|
||||
# stuff for output to third pass
|
||||
nobreak = -1
|
||||
dobreak = -2
|
||||
message = -3
|
||||
OFS = "\t"
|
||||
|
||||
# special-character table; this one character needs to be hardcoded
|
||||
chars[" "] = " " ; charwidths[" "] = 1
|
||||
|
||||
debug["e"] = 0 # just to make it an array
|
||||
strings["a"] = "" # just to make it an array
|
||||
numbers["a"] = 0 # just to make it an array
|
||||
hyphens["a"] = "" # just to make it an array
|
||||
hyphenwidths["a"] = "" # just to make it an array
|
||||
|
||||
# stuff for expression decoding
|
||||
signfactor["+"] = 1
|
||||
signfactor["-"] = -1
|
||||
scale["i"] = 240
|
||||
scale["c"] = 240*50/127
|
||||
scale["P"] = 240/6
|
||||
# we get m, n, and v when we see .^r
|
||||
scale["p"] = 240/72
|
||||
scale["u"] = 1
|
||||
|
||||
# stuff for basic parameters that just get passed to third pass
|
||||
parms["in"] = 0 # just to make it an array
|
||||
prevparms["in"] = 0 # just to make it an array
|
||||
setcmd["ll"] = "linelen"
|
||||
setcmd["in"] = "indent"
|
||||
setcmd["ti"] = "tempindent"
|
||||
setcmd["po"] = "pageoffset"
|
||||
setcmd["pl"] = "pagelen"
|
||||
|
||||
# did last word end with \c ? (in which case, it's still in "word")
|
||||
backc = 0
|
||||
|
||||
# stuff for error reporting
|
||||
il = 0 # input line number
|
||||
lockil = 0 # il is locked, we're inside a macro
|
||||
inname = "?" # input filename
|
||||
msg = message "\t" # later picks up filename etc.
|
||||
|
||||
# current input trap
|
||||
afternext = ""
|
||||
}
|
||||
{
|
||||
if (!lockil)
|
||||
il++
|
||||
msg = message "\t" inname "," il ": "
|
||||
# fallthrough
|
||||
}
|
||||
/^[ \t]*$/ { # empty line
|
||||
print dobreak, "space"
|
||||
next
|
||||
}
|
||||
/^[ \t]/ { # line starting with white space
|
||||
print dobreak, "flush"
|
||||
print 0, "" # empty word
|
||||
# fallthrough
|
||||
}
|
||||
/^[^.]/ { # text
|
||||
# dispose of the easy case
|
||||
if (font == "R" && $0 !~ /\\|\t|-| / && !backc && afternext == "") {
|
||||
for (i = 1; i <= NF; i++)
|
||||
print length($i), $i
|
||||
if ($0 ~ /[.!?:]([)'"*]|])*$/)
|
||||
print nobreak, "gap", 2
|
||||
if (centering > 0) {
|
||||
print dobreak, "center"
|
||||
centering--
|
||||
} else if (!fill)
|
||||
print dobreak, "flush"
|
||||
next
|
||||
}
|
||||
|
||||
# the hard case, needs a character-by-character scan
|
||||
s = $0 " " # the space flushes the last word
|
||||
n = 1 # current position in s
|
||||
inword = 0 # have we been processing a word?
|
||||
period = "" # "." if this word ended a sentence
|
||||
nsp = 0 # count of spaces seen so far
|
||||
tabpos = 0 # which tab position was used last
|
||||
while (n <= length(s)) {
|
||||
c = substr(s, n, 1)
|
||||
|
||||
# handle state transitions
|
||||
if (c == " " || c == "\t") {
|
||||
if (inword) { # ends word
|
||||
if (!backc) {
|
||||
print wordlen, word
|
||||
if (usedhyphen)
|
||||
print nobreak, "nohyphen"
|
||||
}
|
||||
inword = 0
|
||||
nsp = 0
|
||||
}
|
||||
} else {
|
||||
if (!inword) { # begins word
|
||||
if (!backc) {
|
||||
word = ""
|
||||
wordlen = 0
|
||||
usedhyphen = 0
|
||||
}
|
||||
backc = 0
|
||||
inword = 1
|
||||
if (nsp > 1)
|
||||
print nobreak, "gap", nsp
|
||||
}
|
||||
}
|
||||
|
||||
# deal with the character
|
||||
if (c == " ") {
|
||||
nsp++
|
||||
if (n != length(s)) # not the trailing flusher
|
||||
period = ""
|
||||
} else if (c == "\t") {
|
||||
# not really right, should be based on input position
|
||||
# also, one space following tab gets ignored
|
||||
tabpos++
|
||||
if (tabpos <= ntabs)
|
||||
print nobreak, "tabto", tabs[tabpos]
|
||||
nsp = 0
|
||||
period = ""
|
||||
} else if (c == "-" && wordlen > 0) {
|
||||
# hyphen within word
|
||||
print wordlen, word, hyphenwidths[font]
|
||||
print nobreak, "userhyphen", hyphens[font], hyphenwidths[font]
|
||||
word = ""
|
||||
wordlen = 0
|
||||
period = ""
|
||||
usedhyphen = 1
|
||||
} else if (c != "\\") {
|
||||
# ordinary character
|
||||
if (font == "B")
|
||||
word = word c "\b" c "\b" c
|
||||
else if (font == "I" && c ~ /[a-zA-Z0-9]/)
|
||||
word = word "_\b" c
|
||||
else
|
||||
word = word c
|
||||
wordlen++
|
||||
if (c ~ /[.!?:]/)
|
||||
period = "."
|
||||
else if (c !~ /([)'"*]|])/)
|
||||
period = ""
|
||||
} else { # backslash
|
||||
n++
|
||||
c = substr(s, n, 1)
|
||||
if (c == "f") {
|
||||
# font change
|
||||
n++
|
||||
code = substr(s, n, 1)
|
||||
if (code == "(") {
|
||||
n++
|
||||
code = substr(s, n, 2)
|
||||
n++
|
||||
}
|
||||
if (code == "P")
|
||||
font = prevfont
|
||||
else if (fontok[code] == "")
|
||||
print msg "unknown font `" code "'"
|
||||
else {
|
||||
prevfont = font
|
||||
font = code
|
||||
}
|
||||
} else if (c == "n") {
|
||||
# number-register value
|
||||
n++
|
||||
code = substr(s, n, 1)
|
||||
if (code == "(") {
|
||||
n++
|
||||
code = substr(s, n, 2)
|
||||
n++
|
||||
}
|
||||
s = substr(s, 1, n) numbers[code] substr(s, n+1)
|
||||
} else if (c == "s") {
|
||||
# size change
|
||||
n++
|
||||
if (substr(s, n, 1) ~ /[0-9]/)
|
||||
n++
|
||||
# just ignore it
|
||||
} else if (c == "c")
|
||||
# word continuation
|
||||
backc = 1
|
||||
else if (c == "*") {
|
||||
# string-variable value
|
||||
n++
|
||||
code = substr(s, n, 1)
|
||||
if (code == "(") {
|
||||
n++
|
||||
code = substr(s, n, 2)
|
||||
n++
|
||||
}
|
||||
s = substr(s, 1, n) strings[code] substr(s, n+1)
|
||||
} else if (c == "%") {
|
||||
# discretionary hyphen
|
||||
if (wordlen > 0) {
|
||||
print wordlen, word, hyphenwidths[font]
|
||||
print nobreak, "hyphen", hyphens[font], hyphenwidths[font]
|
||||
word = ""
|
||||
wordlen = 0
|
||||
usedhyphen = 1
|
||||
}
|
||||
} else if (c == "(" && substr(s, n+1, 2) == "em" && \
|
||||
chars["em"] != "") {
|
||||
# em-dash, special case due to hyphenation
|
||||
n += 2
|
||||
emw = charwidths["em"]
|
||||
print wordlen, word, emw
|
||||
print nobreak, "userhyphen", chars["em"], emw
|
||||
word = ""
|
||||
wordlen = 0
|
||||
period = ""
|
||||
usedhyphen = 1
|
||||
} else {
|
||||
# special-character name
|
||||
code = c
|
||||
if (code == "(") {
|
||||
n++
|
||||
code = substr(s, n, 2)
|
||||
n++
|
||||
}
|
||||
word = word chars[code]
|
||||
wordlen += charwidths[code]
|
||||
period = ""
|
||||
}
|
||||
}
|
||||
|
||||
# on to the next character, at last
|
||||
n++
|
||||
}
|
||||
|
||||
# end-of-line processing
|
||||
if (!backc) {
|
||||
if (period == ".")
|
||||
print nobreak, "gap", 2
|
||||
if (centering > 0) {
|
||||
print dobreak, "center"
|
||||
centering--
|
||||
} else if (!fill)
|
||||
print dobreak, "flush"
|
||||
}
|
||||
|
||||
# if no input trap, we're done
|
||||
if (afternext == "")
|
||||
next
|
||||
|
||||
# if there is an input trap, fall into the macro-dependent section
|
||||
}
|
||||
#
|
||||
#
|
||||
#
|
||||
# at this point we plug in the macro-specific stuff, keyed on the next line
|
||||
#include note that this is an awk comment
|
||||
#
|
||||
#
|
||||
#
|
||||
/^\.it/ { # plant an input trap, sort of
|
||||
if (NF > 1 && $2 != 1)
|
||||
print msg ".it first argument must be 1"
|
||||
if (NF > 2)
|
||||
afternext = afternext "," $3
|
||||
else
|
||||
afternext = ""
|
||||
next
|
||||
}
|
||||
/^\.\^r cpi / { # set resolutions, in cpi: .^r cpi hor vert
|
||||
scale["m"] = 240/$3
|
||||
scale["n"] = 240/$3
|
||||
scale["v"] = 240/$4
|
||||
next
|
||||
}
|
||||
/^\.(ta|ll|in|ti|po|ne|sp|pl|nr)/ { # expression processing
|
||||
# sort out default scale factor
|
||||
if ($1 ~ /^\.(ne|sp|pl)/)
|
||||
exprscale = "v"
|
||||
else if ($1 ~ /^\.(nr)/)
|
||||
exprscale = "u"
|
||||
else
|
||||
exprscale = "n"
|
||||
|
||||
# which argument should we start with?
|
||||
offset = length($1) + 1
|
||||
if ($1 == ".nr")
|
||||
offset += length($2) + 1
|
||||
|
||||
# beginning of debugging message
|
||||
if (debug["e"])
|
||||
printf "%s ", msg substr($0, 1, offset)
|
||||
|
||||
# do the expressions
|
||||
s = substr($0, offset+1)
|
||||
n = 1
|
||||
while (s != "") {
|
||||
while (s ~ /^[ \t]/)
|
||||
s = substr(s, 2)
|
||||
|
||||
# an initial sign is magic
|
||||
ssign = ""
|
||||
if (s ~ /^[+-]/) {
|
||||
ssign = substr(s, 1, 1)
|
||||
s = substr(s, 2)
|
||||
}
|
||||
s = "+" s # this is an un-magic addition operator
|
||||
|
||||
# process terms
|
||||
sval = 0
|
||||
while (s ~ /^([+*%)-]|\/)/) {
|
||||
# figure out what it is and what it contributes
|
||||
if (debug["e"] > 1)
|
||||
print "s=`" s "'"
|
||||
termop = substr(s, 1, 1)
|
||||
s = substr(s, 2)
|
||||
termscale = exprscale
|
||||
if (termop == ")") {
|
||||
if (debug["e"] > 1)
|
||||
print "pop " valstack[vsp] " " opstack[vsp] " with " sval
|
||||
termval = sval
|
||||
sval = valstack[vsp]
|
||||
termop = opstack[vsp]
|
||||
vsp--
|
||||
termscale = "u"
|
||||
} else if (s ~ /^\(/) {
|
||||
if (debug["e"] > 1)
|
||||
print "push " sval " " termop
|
||||
vsp++
|
||||
valstack[vsp] = sval
|
||||
opstack[vsp] = termop
|
||||
sval = 0
|
||||
termop = "+" # dummy op and value
|
||||
termval = 0
|
||||
s = "+" substr(s, 2)
|
||||
} else if (s ~ /^\\w/) {
|
||||
delim = substr(s, 3, 1)
|
||||
s = substr(s, 4)
|
||||
endp = index(s, delim)
|
||||
if (endp == 0)
|
||||
endp = length(s) + 1
|
||||
termval = (endp - 1) * scale["n"] # crude
|
||||
s = substr(s, endp+1)
|
||||
} else if (s ~ /^\\n/) {
|
||||
if (s ~ /^\\n\(/) {
|
||||
code = substr(s, 4, 2)
|
||||
s = substr(s, 6)
|
||||
} else {
|
||||
code = substr(s, 3, 1)
|
||||
s = substr(s, 4)
|
||||
}
|
||||
termval = numbers[code]
|
||||
} else if (s ~ /^[0-9.]/) {
|
||||
for (endp = 1; endp <= length(s); endp++)
|
||||
if (substr(s, endp, 1) !~ /[0-9.]/)
|
||||
break
|
||||
termval = substr(s, 1, endp-1) + 0
|
||||
s = substr(s, endp)
|
||||
}
|
||||
|
||||
# add it in, with scaling factor
|
||||
c = substr(s, 1, 1)
|
||||
if (scale[c] != "") {
|
||||
termval *= scale[c]
|
||||
s = substr(s, 2)
|
||||
} else
|
||||
termval *= scale[termscale]
|
||||
if (termop == "+")
|
||||
sval += termval
|
||||
else if (termop == "-")
|
||||
sval -= termval
|
||||
else if (termop == "*")
|
||||
sval *= termval
|
||||
else if (termop == "/")
|
||||
sval = int(sval) / int(termval)
|
||||
else if (termop == "%")
|
||||
sval = int(sval) % int(termval)
|
||||
}
|
||||
|
||||
# remember the value, print if debugging
|
||||
expr[n] = sval
|
||||
exprsign[n] = ssign
|
||||
iexpr[n] = signfactor[ssign] * sval # convenience
|
||||
if (debug["e"])
|
||||
printf "%s ", ssign "(" sval ")"
|
||||
|
||||
# proceed to next, skipping trash if necessary
|
||||
while (s ~ /^[^ \t]/)
|
||||
s = substr(s, 2)
|
||||
n++
|
||||
}
|
||||
|
||||
# final cleanup
|
||||
nexprs = n - 1
|
||||
if (debug["e"])
|
||||
printf "\n"
|
||||
|
||||
# fallthrough
|
||||
}
|
||||
/^\.(ll|in|ti|po|pl)/ { # common code for set-parameter requests
|
||||
# relies on expression processing, including setting of exprscale
|
||||
name = substr($1, 2, 2)
|
||||
n = parms[name]
|
||||
if (nexprs == 0)
|
||||
n = prevparms[name]
|
||||
else if (exprsign[1] == "" || name == "ti")
|
||||
n = expr[1] / scale[exprscale]
|
||||
else
|
||||
n += iexpr[1] / scale[exprscale]
|
||||
prevparms[name] = parms[name]
|
||||
parms[name] = int(n)
|
||||
print dobreak, setcmd[name], parms[name]
|
||||
next
|
||||
}
|
||||
/^\.nr/ {
|
||||
# relies on expression processing
|
||||
n = numbers[$2]
|
||||
if (exprsign[1] == "")
|
||||
n = expr[1]
|
||||
else
|
||||
n += iexpr[1]
|
||||
numbers[$2] = int(n)
|
||||
next
|
||||
}
|
||||
/^\.ne/ {
|
||||
# relies on expression processing
|
||||
print dobreak, "need", int(expr[1]/scale["v"] + 0.99)
|
||||
next
|
||||
}
|
||||
/^\.sp/ {
|
||||
# relies on expression processing
|
||||
if (nexprs == 0)
|
||||
i = 1
|
||||
else
|
||||
i = int(expr[1]/scale["v"] + 0.99)
|
||||
for (; i > 0; i--)
|
||||
print dobreak, "space"
|
||||
next
|
||||
}
|
||||
/^\.ta/ {
|
||||
# relies on expression processing
|
||||
tabstop = 0
|
||||
for (n = 1; n <= nexprs; n++) {
|
||||
if (exprsign[n] == "")
|
||||
tabstop = expr[n]
|
||||
else
|
||||
tabstop += iexpr[n]
|
||||
tabs[n] = int(tabstop/scale["n"])
|
||||
}
|
||||
ntabs = nexprs
|
||||
next
|
||||
}
|
||||
/^\.ft/ {
|
||||
if (NF > 1)
|
||||
code = $2
|
||||
else
|
||||
code = "P"
|
||||
|
||||
if (code == "P")
|
||||
font = prevfont
|
||||
else if (fontok[code] == "")
|
||||
print msg "unknown font `" code "'"
|
||||
else {
|
||||
prevfont = font
|
||||
font = code
|
||||
}
|
||||
next
|
||||
}
|
||||
/^\.br/ {
|
||||
print dobreak, "flush"
|
||||
next
|
||||
}
|
||||
/^\.ds/ {
|
||||
# note, macro-set-specific code often looks at .ds as well
|
||||
if ($3 !~ /^"/)
|
||||
strings[$2] = $3
|
||||
else
|
||||
strings[$2] = substr($0, index($0, "\"")+1)
|
||||
next
|
||||
}
|
||||
/^\.ns/ {
|
||||
print nobreak, "nospace"
|
||||
next
|
||||
}
|
||||
/^\.rs/ {
|
||||
print nobreak, "yesspace"
|
||||
next
|
||||
}
|
||||
/^\.ad/ {
|
||||
print nobreak, "both"
|
||||
next
|
||||
}
|
||||
/^\.na/ {
|
||||
print nobreak, "left"
|
||||
next
|
||||
}
|
||||
/^\.nf/ {
|
||||
fill = 0
|
||||
print dobreak, "flush"
|
||||
next
|
||||
}
|
||||
/^\.fi/ {
|
||||
fill = 1
|
||||
print dobreak, "flush"
|
||||
next
|
||||
}
|
||||
/^\.\^x/ { # direct errors to this file: .^x filename
|
||||
print nobreak, "errsto", $2
|
||||
next
|
||||
}
|
||||
/^\.\^c/ { # define character: .^c name width text
|
||||
if ($4 ~ /^"/)
|
||||
s = substr($0, index($0, "\"")+1)
|
||||
else
|
||||
s = $4
|
||||
ns = ""
|
||||
while ((n = index(s, "\\")) > 0) {
|
||||
if (n > 1)
|
||||
ns = ns substr(s, 1, n-1)
|
||||
n++
|
||||
c = substr(s, n, 1)
|
||||
if (c == "\\")
|
||||
ns = ns "\\"
|
||||
else if (c == "b")
|
||||
ns = ns "\b"
|
||||
s = substr(s, n+1)
|
||||
}
|
||||
ns = ns s
|
||||
if ($2 == "hy") {
|
||||
hyphens[font] = ns
|
||||
hyphenwidths[font] = $3
|
||||
} else {
|
||||
chars[$2] = ns
|
||||
charwidths[$2] = $3
|
||||
}
|
||||
next
|
||||
}
|
||||
/^\.\^f/ { # this font is okay: .^f fontname
|
||||
# someday, this might take font-change codes as further arguments
|
||||
fontok[$2] = "yes"
|
||||
next
|
||||
}
|
||||
/^\.tm/ {
|
||||
print msg $0
|
||||
next
|
||||
}
|
||||
/^\.ps/ {
|
||||
# ignore
|
||||
next
|
||||
}
|
||||
/^\.ce/ {
|
||||
if (NF > 1)
|
||||
centering = $2
|
||||
else
|
||||
centering = 1
|
||||
next
|
||||
}
|
||||
/^\.bp/ {
|
||||
print dobreak, "need", 999
|
||||
next
|
||||
}
|
||||
/^\.\^d/ { # debug control: .^d debugvar value
|
||||
debug[$2] = $3
|
||||
next
|
||||
}
|
||||
/^\.\^#/ { # set line number of next line: .^# no file
|
||||
il = $2 - 1
|
||||
lockil = 0
|
||||
inname = $3
|
||||
next
|
||||
}
|
||||
/^\.\^=/ { # lock line number to value: .^= no file
|
||||
il = $2
|
||||
lockil = 1
|
||||
inname = $3
|
||||
next
|
||||
}
|
||||
/^\.\\"/ { # comment
|
||||
next
|
||||
}
|
||||
/^\./ {
|
||||
print msg "command `" $1 "' unsupported or unknown"
|
||||
}
|
||||
END {
|
||||
print dobreak, "need", 999 # flush page
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/^\.\^b/ { # initialization
|
||||
print nobreak, "fph", 1
|
||||
next
|
||||
}
|
||||
/^[^.]/ { # text line -- reached only for input traps
|
||||
if (afternext ~ /,fP/)
|
||||
font = prevfont
|
||||
if (afternext ~ /,tP/)
|
||||
print dobreak, "toindent"
|
||||
afternext = ""
|
||||
next
|
||||
}
|
||||
/^\.ds/ { # to catch special strings
|
||||
if ($3 !~ /^"/)
|
||||
v = $3
|
||||
else
|
||||
v = substr($0, index($0, "\"")+1)
|
||||
if ($2 ~ /^[LCR][HF]$/)
|
||||
print nobreak, $2, v
|
||||
# fallthrough to normal .ds processing in macro-independent stuff
|
||||
}
|
||||
/^\.lF/ {
|
||||
# special footer fiddling
|
||||
if (strings["by"] != "" && strings["nb"] != "")
|
||||
lf = strings["by"] "; " strings["nb"]
|
||||
else
|
||||
lf = strings["by"] strings["nb"]
|
||||
print nobreak, "LF", lf
|
||||
next
|
||||
}
|
||||
/^\.\^e/ { # finalization
|
||||
next
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/^\.\^b/ { # initialization
|
||||
nhnos[1] = 0
|
||||
next
|
||||
}
|
||||
/^[^.]/ { # text line -- reached only for input traps
|
||||
if (afternext == ",tP")
|
||||
print dobreak, "toindent"
|
||||
afternext = ""
|
||||
next
|
||||
}
|
||||
/^\.nH/ { # fooling around for numbered headings
|
||||
no = 1
|
||||
if (NF > 1)
|
||||
no = $2
|
||||
if (no == 0) {
|
||||
nhnos[1] = 0
|
||||
no = 1
|
||||
}
|
||||
nhnos[no]++
|
||||
for (n in nhnos)
|
||||
if (n > no)
|
||||
nhnos[n] = 0
|
||||
s = ""
|
||||
for (n = 1; n <= no; n++)
|
||||
s = s nhnos[n] "."
|
||||
strings["Nh"] = s # result in string for macro to grab
|
||||
next
|
||||
}
|
||||
/^\.ds/ { # to catch special strings
|
||||
if ($3 !~ /^"/)
|
||||
v = $3
|
||||
else
|
||||
v = substr($0, index($0, "\"")+1)
|
||||
if ($2 ~ /^[LCR][HF]$/)
|
||||
print nobreak, $2, v
|
||||
# fallthrough to normal .ds processing in macro-independent stuff
|
||||
}
|
||||
/^\.\^e/ { # finalization
|
||||
next
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
# third pass: setting lines and pages
|
||||
# The input language of this pass is basically <width, word> pairs, where
|
||||
# "word" may have imbedded strangeness (backspaces, etc.) for font changes
|
||||
# and special characters. Zero width is not special. A third field may
|
||||
# appear to indicate that this is a fragment of a word that can be
|
||||
# hyphenated; the third field is the width of the hyphen that would have
|
||||
# to be added if the line broke after this fragment.
|
||||
# Negative widths denote special operations. -3 is an error message, the
|
||||
# second field being the message. -1 and -2 are control messages to this
|
||||
# pass, the difference being whether a break is implied or not. The second
|
||||
# field is a message type string; more fields may appear as arguments. The
|
||||
# semantics of control messages are often -- but not always! -- similar to
|
||||
# those of troff commands. For example, "linelen" is .ll, but "center" is
|
||||
# not semantically equivalent to .ce -- it is related but more primitive.
|
||||
BEGIN {
|
||||
# input and output details
|
||||
FS = "\t"
|
||||
nobreak = -1
|
||||
dobreak = -2
|
||||
message = -3
|
||||
errs = "awf.errs" # default only, normally changed by "errsto"
|
||||
|
||||
# page setup -- some are defaults only, normally altered by pass 2
|
||||
nextlineno = 1
|
||||
thispageno = 1
|
||||
topmargin = 5
|
||||
botmargin = 5
|
||||
ind = 0 # current indent
|
||||
tmpind = 0
|
||||
pageoffset = "" # string to emit at start of each line
|
||||
nospacemode = 1
|
||||
hdrs["CH"] = "- % -"
|
||||
nop = split("LH,CH,RH,LF,CF,RF", hdrnames, ",")
|
||||
fph = 0 # print header on first page?
|
||||
fill = 1
|
||||
adj = "both"
|
||||
pagelen = 66
|
||||
linelen = 78
|
||||
|
||||
# line-builder setup
|
||||
line = "" # line so far, without padding
|
||||
paddable = "" # x means corresp. char in "line" is paddable
|
||||
thislinelen = -1 # -1 means nothing there
|
||||
cont = " " # thing to append to continue line
|
||||
contlen = 1
|
||||
eol = "" # thing to append to break line
|
||||
eollen = 0
|
||||
padfrom = "R" # "L" or "R", alternating for river avoidance
|
||||
|
||||
# many spaces, so we can use substr to get any number we need
|
||||
sps = " "
|
||||
sps = sps sps sps sps sps sps sps sps sps sps
|
||||
}
|
||||
{
|
||||
# process word, if any, causing a break if appropriate
|
||||
if ($1 >= 0 && thislinelen < 0) { # word, and first on line
|
||||
line = $2
|
||||
paddable = substr(sps, 1, length($2))
|
||||
thislinelen = $1
|
||||
} else if ($1 >= 0 && thislinelen+contlen+$1+$3 <= linelen-ind-tmpind) {
|
||||
# word, and it fits on line
|
||||
line = line cont $2
|
||||
if (cont == " ")
|
||||
paddable = paddable "x"
|
||||
else
|
||||
paddable = paddable substr(sps, 1, length(cont))
|
||||
paddable = paddable substr(sps, 1, length($2))
|
||||
thislinelen += contlen + $1
|
||||
} else if ($1 == nobreak || $1 == message)
|
||||
nop = 0 # no attention (i.e. break) needed here
|
||||
else if ($1 == dobreak && $2 == "need" && \
|
||||
nextlineno + $3 < pagelen + 1 - botmargin)
|
||||
nop = 0 # enough space is available, no action needed
|
||||
else if ($1 == dobreak && $2 == "toindent" && \
|
||||
ind + tmpind + thislinelen < ind) {
|
||||
# move to indent position within line; there is room
|
||||
n = ind - (ind + tmpind + thislinelen)
|
||||
line = line substr(sps, 1, n)
|
||||
# nothing before this is paddable
|
||||
paddable = substr(sps, 1, length(line))
|
||||
thislinelen += n
|
||||
# prevent padding immediately after this point
|
||||
cont = ""
|
||||
contlen = 0
|
||||
} else if (thislinelen >= 0 || ($1 == dobreak && $2 == "need")) {
|
||||
# must emit output, either due to break or "need"
|
||||
|
||||
# if at top of page, header
|
||||
if (nextlineno == 1) {
|
||||
for (i = int((topmargin-1)/2); i > 0; i--) {
|
||||
print ""
|
||||
nextlineno++
|
||||
}
|
||||
for (hno in hdrnames) {
|
||||
h = hdrnames[hno]
|
||||
if (hdrs[h] ~ /%/) {
|
||||
n = split(hdrs[h], t, "%")
|
||||
thispagehdrs[h] = t[1] thispageno t[2]
|
||||
} else
|
||||
thispagehdrs[h] = hdrs[h]
|
||||
}
|
||||
if (fph || thispageno > 1) {
|
||||
lh = thispagehdrs["LH"]
|
||||
ch = thispagehdrs["CH"]
|
||||
rh = thispagehdrs["RH"]
|
||||
lsp = int((linelen - length(lh ch rh)) / 2)
|
||||
rsp = linelen - length(lh ch rh) - lsp
|
||||
print pageoffset lh substr(sps, 1, lsp) ch substr(sps, 1, rsp) rh
|
||||
} else
|
||||
print ""
|
||||
nextlineno++
|
||||
while (nextlineno <= topmargin) {
|
||||
print ""
|
||||
nextlineno++
|
||||
}
|
||||
}
|
||||
|
||||
# the current line
|
||||
# first, add a trailing hyphen if any
|
||||
line = line eol
|
||||
paddable = paddable substr(sps, 1, length(eol))
|
||||
thislinelen += eollen
|
||||
|
||||
# trim trailing spaces if any
|
||||
while (line ~ / $/) {
|
||||
line = substr(line, 1, length(line)-1)
|
||||
paddable = substr(paddable, 1, length(line))
|
||||
thislinelen--
|
||||
}
|
||||
|
||||
# print it in a suitable way
|
||||
if (line == "") # empty always prints as nothing
|
||||
print ""
|
||||
else if ($1 < 0 && $2 == "center") {
|
||||
# center it
|
||||
hsp = int((linelen - thislinelen) / 2)
|
||||
if (hsp < 0)
|
||||
hsp = 0
|
||||
print pageoffset substr(sps, 1, ind+tmpind+hsp) line
|
||||
} else if (adj == "left" || (adj == "both" && \
|
||||
($1 < 0 || index(paddable, "x") == 0)))
|
||||
# no right-margin adjustment (disabled, inappropriate
|
||||
# (line ended by break), or impossible)
|
||||
print pageoffset substr(sps, 1, ind+tmpind) line
|
||||
else if (adj == "both") {
|
||||
# hard case -- adjust right margin
|
||||
# sanity check
|
||||
if (length(paddable) != length(line)) # aieeeee
|
||||
printf "awf: %f != %f!\n", length(paddable), \
|
||||
length(line) >errs
|
||||
|
||||
# compute parameters
|
||||
textlen = linelen - (ind+tmpind)
|
||||
mustadd = textlen - thislinelen
|
||||
npad = 0 # number of paddable spaces
|
||||
for (tmp = paddable; (i = index(tmp, "x")) > 0; \
|
||||
tmp = substr(tmp, i+1))
|
||||
npad++
|
||||
addatall = int(mustadd/npad) # all grow this much
|
||||
spall = substr(sps, 1, addatall)
|
||||
nmore = mustadd - addatall*npad # this many grow more
|
||||
|
||||
# build padded output text
|
||||
out = substr(sps, 1, ind+tmpind)
|
||||
padno = 0
|
||||
while ((i = index(paddable, "x")) > 0) {
|
||||
out = out substr(line, 1, i)
|
||||
padno++
|
||||
out = out spall
|
||||
if (padfrom == "L") {
|
||||
if (padno <= nmore)
|
||||
out = out " "
|
||||
} else {
|
||||
if (padno > npad-nmore)
|
||||
out = out " "
|
||||
}
|
||||
line = substr(line, i+1)
|
||||
paddable = substr(paddable, i+1)
|
||||
}
|
||||
|
||||
# print it, plus remnant not processed by loop
|
||||
print pageoffset out line
|
||||
|
||||
# tidy up
|
||||
if (padfrom == "L")
|
||||
padfrom = "R"
|
||||
else
|
||||
padfrom = "L"
|
||||
}
|
||||
|
||||
# tidy up after output line
|
||||
nextlineno++
|
||||
line = ""
|
||||
paddable = ""
|
||||
thislinelen = -1
|
||||
tmpind = 0
|
||||
nospacemode = 0
|
||||
|
||||
# if we broke from a "need", go to bottom of page
|
||||
if ($1 == dobreak && $2 == "need")
|
||||
while (nextlineno < pagelen + 1 - botmargin) {
|
||||
print ""
|
||||
nextlineno++
|
||||
}
|
||||
|
||||
# footer, if at bottom of page
|
||||
if (nextlineno >= pagelen + 1 - botmargin) {
|
||||
for (i = int((botmargin-1)/2); i > 0; i--) {
|
||||
print ""
|
||||
nextlineno++
|
||||
}
|
||||
# header code prepared thispagehdrs
|
||||
lf = thispagehdrs["LF"]
|
||||
cf = thispagehdrs["CF"]
|
||||
rf = thispagehdrs["RF"]
|
||||
lsp = int((linelen - length(lf cf rf)) / 2)
|
||||
rsp = linelen - length(lf cf rf) - lsp
|
||||
print pageoffset lf substr(sps, 1, lsp) cf substr(sps, 1, rsp) rf
|
||||
nextlineno++
|
||||
while (nextlineno <= pagelen) {
|
||||
print ""
|
||||
nextlineno++
|
||||
}
|
||||
nextlineno = 1
|
||||
thispageno++
|
||||
|
||||
# after page break, should not space unnecessarily,
|
||||
# and should pad first line from right
|
||||
nospacemode = 1
|
||||
padfrom = "R"
|
||||
}
|
||||
|
||||
# we are finally done with emitting output
|
||||
# pick up input word, if any
|
||||
if ($1 >= 0) {
|
||||
line = $2
|
||||
paddable = substr(sps, 1, length($2))
|
||||
thislinelen = $1
|
||||
}
|
||||
}
|
||||
|
||||
# if we broke, next line should pad from right
|
||||
if ($1 == dobreak)
|
||||
padfrom = "R"
|
||||
|
||||
# cleanup and post-break command processing
|
||||
if ($1 >= 0 || $2 == "nohyphen") {
|
||||
# reset hyphenation trickery after each word (fragment)
|
||||
cont = " "
|
||||
contlen = 1
|
||||
eol = ""
|
||||
eollen = 0
|
||||
} else if ($2 == "need" || $2 == "toindent")
|
||||
nop = 0 # dealt with above
|
||||
else if ($2 == "flush" || $2 == "center")
|
||||
nop = 0 # exist only to cause break
|
||||
else if ($1 == message)
|
||||
print "awf: " $2 >errs
|
||||
else if ($2 == "gap") {
|
||||
# gap between last word and next one should be >= $3
|
||||
if (thislinelen >= 0) {
|
||||
line = line substr(sps, 1, $3-1)
|
||||
paddable = paddable substr(sps, 1, $3-1)
|
||||
thislinelen += $3-1
|
||||
}
|
||||
} else if ($2 == "tabto") {
|
||||
# move to tab stop at $3
|
||||
if (thislinelen < 0)
|
||||
thislinelen = 0 # make line exist
|
||||
n = $3 - thislinelen
|
||||
if (n > 0) { # must emit some space
|
||||
line = line substr(sps, 1, n)
|
||||
# nothing before a tab is paddable
|
||||
paddable = substr(sps, 1, length(line))
|
||||
thislinelen += n
|
||||
# suppress space following
|
||||
cont = ""
|
||||
contlen = 0
|
||||
}
|
||||
} else if ($2 == "errsto")
|
||||
errs = $3
|
||||
else if ($2 ~ /^[LCR][HF]$/)
|
||||
hdrs[$2] = $3
|
||||
else if ($2 == "fph")
|
||||
fph = $3
|
||||
else if ($2 == "space") {
|
||||
if (!nospacemode) {
|
||||
# generate an empty line, which will be flushed by
|
||||
# the next word; NB we know "space" caused a flush
|
||||
line = ""
|
||||
paddable = ""
|
||||
thislinelen = linelen + 1
|
||||
nospacemode = 0
|
||||
}
|
||||
} else if ($2 == "left")
|
||||
adj = "left"
|
||||
else if ($2 == "both")
|
||||
adj = "both"
|
||||
else if ($2 == "indent")
|
||||
ind = $3
|
||||
else if ($2 == "tempindent")
|
||||
tmpind = $3
|
||||
else if ($2 == "linelen")
|
||||
linelen = $3
|
||||
else if ($2 == "pagelen")
|
||||
pagelen = $3
|
||||
else if ($2 == "nospace")
|
||||
nospacemode = 1
|
||||
else if ($2 == "yesspace")
|
||||
nospacemode = 0
|
||||
else if ($2 == "hyphen") {
|
||||
# discretionary hyphen at this point
|
||||
cont = ""
|
||||
contlen = 0
|
||||
eol = $3
|
||||
eollen = $4
|
||||
} else if ($2 == "userhyphen") {
|
||||
# user-supplied hyphen at this point
|
||||
cont = $3
|
||||
contlen = $4
|
||||
eol = $3
|
||||
eollen = $4
|
||||
} else if ($2 == "pageoffset")
|
||||
pageoffset = substr(sps, 1, $3)
|
||||
else
|
||||
print "awf: URK -- INTERNAL OPCODE `" $2 "' UNKNOWN" >errs
|
||||
}
|
||||
END {
|
||||
# second pass is supposed to fake a .ne to flush the last page
|
||||
if (nextlineno != 1)
|
||||
print "awf: last page not flushed!" >errs
|
||||
}
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
echo ---------- %1 ----------
|
||||
cd %1
|
||||
nmake /f makefile.vc /nologo %2
|
||||
@@ -0,0 +1,5 @@
|
||||
*.log
|
||||
*.log.*
|
||||
*.pix
|
||||
*.pix.*
|
||||
.cvsignore
|
||||
@@ -1,106 +0,0 @@
|
||||
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)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
configure_file(run.sh "${CMAKE_CURRENT_BINARY_DIR}/benchmark" COPYONLY)
|
||||
install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/benchmark" DESTINATION ${BIN_DIR})
|
||||
endif(BUILD_TESTING)
|
||||
distclean("${CMAKE_CURRENT_BINARY_DIR}/benchmark")
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/benchmark-done
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/run.sh $<TARGET_FILE_DIR:bark>/benchmark
|
||||
COMMAND "${CMAKE_COMMAND}" -E touch ${CMAKE_CURRENT_BINARY_DIR}/benchmark-done
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/run.sh
|
||||
)
|
||||
add_custom_target(benchmark_cp ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/benchmark-done)
|
||||
set_target_properties(benchmark_cp PROPERTIES FOLDER "Benchmark")
|
||||
endif(BUILD_TESTING)
|
||||
distclean(${CMAKE_BINARY_DIR}/${BIN_DIR}/benchmark)
|
||||
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/CMakeTmp/benchmsg.cmake" "message(\"---\")\n")
|
||||
file(
|
||||
APPEND
|
||||
"${CMAKE_BINARY_DIR}/CMakeTmp/benchmsg.cmake"
|
||||
"message(\"Run 'make benchmark-clean' in the bench directory to delete the logic\")\n"
|
||||
)
|
||||
file(
|
||||
APPEND
|
||||
"${CMAKE_BINARY_DIR}/CMakeTmp/benchmsg.cmake"
|
||||
"message(\"and image files generated during the benchmark analysis.\")\n"
|
||||
)
|
||||
|
||||
cmakefiles(
|
||||
CMakeLists.txt
|
||||
pixcmp_test.cmake
|
||||
run.sh
|
||||
try.sh
|
||||
viewdiff.sh
|
||||
)
|
||||
|
||||
if(SH_EXEC AND TARGET m35.g AND BUILD_TESTING)
|
||||
# CTest enabled short run of the benchmark suite
|
||||
brlcad_add_test(NAME benchmark COMMAND ${SH_EXEC} "$<TARGET_FILE_DIR:bark>/benchmark" run TIMEFRAME=1)
|
||||
set_tests_properties(benchmark PROPERTIES LABELS "Benchmark")
|
||||
add_custom_target(
|
||||
benchmark-check
|
||||
COMMAND ${CMAKE_CTEST_COMMAND} -L Benchmark --output-on-failure
|
||||
DEPENDS rt pixcmp BENCHMARK_PIX_cp PIX_LOG_cp benchmark_cp
|
||||
)
|
||||
add_dependencies(
|
||||
benchmark-check
|
||||
bldg391.g
|
||||
m35.g
|
||||
moss.g
|
||||
sphflake.g
|
||||
star.g
|
||||
world.g
|
||||
)
|
||||
set_target_properties(benchmark-check PROPERTIES FOLDER "Benchmark")
|
||||
if(TARGET check)
|
||||
add_dependencies(check benchmark-check)
|
||||
endif(TARGET check)
|
||||
|
||||
# Full run of the benchmark suite
|
||||
add_custom_target(
|
||||
benchmark
|
||||
COMMAND ${SH_EXEC} $<TARGET_FILE_DIR:bark>/benchmark run
|
||||
COMMAND ${CMAKE_COMMAND} -P "${CMAKE_BINARY_DIR}/CMakeTmp/benchmsg.cmake"
|
||||
DEPENDS rt pixcmp BENCHMARK_PIX_cp PIX_LOG_cp benchmark_cp
|
||||
)
|
||||
add_dependencies(
|
||||
benchmark
|
||||
bldg391.g
|
||||
m35.g
|
||||
moss.g
|
||||
sphflake.g
|
||||
star.g
|
||||
world.g
|
||||
)
|
||||
set_target_properties(benchmark PROPERTIES FOLDER "Benchmark")
|
||||
|
||||
# benchmark cleanup targets
|
||||
add_custom_target(benchmark-clean ${SH_EXEC} ${CMAKE_BINARY_DIR}/bin/benchmark clean)
|
||||
set_target_properties(benchmark-clean PROPERTIES FOLDER "Benchmark")
|
||||
add_custom_target(benchmark-clobber ${SH_EXEC} ${CMAKE_BINARY_DIR}/bin/benchmark clobber)
|
||||
set_target_properties(benchmark-clobber PROPERTIES FOLDER "Benchmark")
|
||||
endif(SH_EXEC AND TARGET m35.g AND BUILD_TESTING)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* bench/Cakefile
|
||||
*/
|
||||
|
||||
#define SRCDIR bench
|
||||
#define PRODUCTS pixcmp
|
||||
#define SRCSUFF .c
|
||||
/* #define MANSECTION 9 */
|
||||
|
||||
#define FILES pixcmp
|
||||
|
||||
#include "../Cakefile.defs"
|
||||
|
||||
#ifdef NFS
|
||||
/* Pick up any shell scripts needed */
|
||||
%.sh: if exist ../SRCDIR/%.sh
|
||||
rm -f %.sh
|
||||
ln ../SRCDIR/%.sh %.sh
|
||||
#endif
|
||||
|
||||
#include "../Cakefile.prog"
|
||||
|
||||
clobber&: xxclober
|
||||
@echo "About to wipe out all pictures and binary files in this directory"
|
||||
@echo "Send SIGINT (typ. ^C) within 3 seconds to abort"
|
||||
@sleep 3
|
||||
rm -f *.log.* *.pix.* # old versions
|
||||
rm -f *.log *.pix # last try
|
||||
|
||||
#define clobber xxclober /* rename "clobber" in Cakefile.rules */
|
||||
|
||||
clean&:
|
||||
@echo "Removing object files and pixcmp"
|
||||
rm -f *.o pixcmp
|
||||
|
||||
pixcmp: OBJ
|
||||
CC LDFLAGS -o pixcmp OBJ
|
||||
|
||||
#include "../Cakefile.rules"
|
||||
@@ -1,953 +0,0 @@
|
||||
/* B E N C H M A R K . C
|
||||
* BRL-CAD
|
||||
*
|
||||
* Copyright (c) 2011-2026 United States Government as represented by
|
||||
* the U.S. Army Research Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/** @file benchmark.c
|
||||
*
|
||||
* This is the BRL-CAD Benchmark.
|
||||
*
|
||||
* The benchmark suite will test the performance of a system by
|
||||
* iteratively rendering several well-known datasets into 512x512
|
||||
* images where performance metrics are documented and fairly well
|
||||
* understood. The local machine's performance is compared to the
|
||||
* base system (called VGR) and a numeric "VGR" multiplier of
|
||||
* performance is computed. This number is a simplified metric from
|
||||
* which one may qualitatively compare cpu and cache performance,
|
||||
* versions of BRL-CAD, and different compiler characteristics.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
/* TODO - fall back on https://github.com/sandsmark/winuname for Windows? */
|
||||
#ifdef HAVE_SYS_UTSNAME_H
|
||||
# include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
#include "bio.h"
|
||||
|
||||
#include "bu.h"
|
||||
|
||||
|
||||
/* TODO: !!! probably will need variants of these */
|
||||
int bu_exec(const char *program, void *data, struct bu_vls *out, struct bu_vls *err) {if (!program || !out || !err || !data) return 1; return 0;}
|
||||
int bu_grep(const char *pattern, const char *input, int(*callback)(const char *line, void *data), void *data) {if (!pattern || !input || !data) return 1; if (!callback) bu_log("TODO: need default callback!!!\n"); return 0;}
|
||||
int bu_file_glob(const char *pattern, char **paths) {if (!pattern || !paths) return 1; return 0;}
|
||||
const char *format_elapsed(double elapsed) {if (elapsed > 0) return "0 1 2"; return "-0 -1 -2";}
|
||||
int perf(const struct bu_vls *vp, const char *items, const char *args[]) {if (!vp || !items || !args) return -1; return 0;}
|
||||
double calculate_vgr(const struct bu_vls *summary) {if (!summary) return -0.0; return 0.0;}
|
||||
extern int bench(const char *cmd);
|
||||
|
||||
|
||||
/**
|
||||
* this routine writes the provided argument(s) to a log file as well
|
||||
* as echoing them to stdout if we're not in quiet mode.
|
||||
*/
|
||||
static void
|
||||
record(const char *fmt, ...)
|
||||
{
|
||||
struct bu_vls str = BU_VLS_INIT_ZERO;
|
||||
va_list ap;
|
||||
|
||||
const char *LOGFILE = getenv("LOGFILE");
|
||||
const char *QUIET = getenv("QUIET");
|
||||
|
||||
if (!fmt) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
bu_vls_vprintf(&str, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (!BU_STR_EQUAL(LOGFILE, "")) {
|
||||
FILE *fp = fopen(LOGFILE, "a");
|
||||
fprintf(fp, "%s", bu_vls_addr(&str));
|
||||
fclose(fp);
|
||||
}
|
||||
if (bu_str_false(QUIET)) {
|
||||
bu_log("%s", bu_vls_addr(&str));
|
||||
}
|
||||
|
||||
bu_vls_free(&str);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
display(const char *fmt, ...)
|
||||
{
|
||||
struct bu_vls str = BU_VLS_INIT_ZERO;
|
||||
va_list ap;
|
||||
|
||||
if (!fmt) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
bu_vls_vprintf(&str, fmt, ap);
|
||||
va_end(ap);
|
||||
bu_log("%s", bu_vls_cstr(&str));
|
||||
|
||||
bu_vls_free(&str);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sink(const char *fmt, ...)
|
||||
{
|
||||
if (!fmt) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
* search for resources *
|
||||
************************/
|
||||
typedef enum {
|
||||
executable=0x1,
|
||||
file=0x2,
|
||||
directory=0x4,
|
||||
script=0x8
|
||||
} look_for_type_t;
|
||||
|
||||
#define TYPE2STR(_t) \
|
||||
((_t) == executable) ? "executable" : \
|
||||
((_t) == file) ? "file" : \
|
||||
((_t) == directory) ? "directory" : \
|
||||
((_t) == script) ? "script" : \
|
||||
"unknown"
|
||||
|
||||
static void
|
||||
look_for(void (*verbose)(const char *, ...), look_for_type_t type, const char *label, const char *var, const char*paths[])
|
||||
{
|
||||
char *val;
|
||||
|
||||
/* utility function to search for a certain filesystem object in a
|
||||
* list of paths.
|
||||
*/
|
||||
|
||||
if (!var || !paths) {
|
||||
return;
|
||||
}
|
||||
if (!verbose) {
|
||||
verbose = sink;
|
||||
}
|
||||
|
||||
verbose("Looking for %s\n", label);
|
||||
|
||||
/* get the value of the variable */
|
||||
val = getenv(var);
|
||||
|
||||
if (val && (strlen(val) > 0)) {
|
||||
if (label) {
|
||||
verbose("...using %s from %s variable setting\n", val, var);
|
||||
}
|
||||
} else {
|
||||
while (paths && *paths) {
|
||||
int failed=0;
|
||||
|
||||
switch (type) {
|
||||
default:
|
||||
case directory:
|
||||
/* should work without read bit */
|
||||
if (!bu_file_directory(*paths)) {
|
||||
failed=1;
|
||||
}
|
||||
/* fall through */
|
||||
case executable:
|
||||
case script:
|
||||
if (!bu_file_executable(*paths)) {
|
||||
failed=1;
|
||||
}
|
||||
break;
|
||||
case file:
|
||||
if (!bu_file_exists(*paths, NULL)) {
|
||||
failed=1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!failed) {
|
||||
verbose("...found %s %s\n", TYPE2STR(type), *paths);
|
||||
bu_setenv(var, *paths, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
paths++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_if_unset(void (*echo)(const char *, ...), void (*verbose)(const char *, ...), const char *var, const char *val)
|
||||
{
|
||||
if (!var || !val) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *setval = getenv(var);
|
||||
|
||||
if (!echo) {
|
||||
echo = sink;
|
||||
}
|
||||
|
||||
if (!verbose) {
|
||||
verbose = sink;
|
||||
}
|
||||
|
||||
if (!setval || (strlen(setval) == 0)) {
|
||||
verbose("%s=\"%s\"\n", var, val);
|
||||
bu_setenv(var, val, 1);
|
||||
}
|
||||
|
||||
setval = getenv(var);
|
||||
echo("Using [%s] for %s\n", setval ? setval : "", var);
|
||||
}
|
||||
|
||||
|
||||
/* callback to bu_grep() */
|
||||
static int
|
||||
stashline(const char *line, void *data)
|
||||
{
|
||||
struct bu_vls *vls = (struct bu_vls *)data;
|
||||
|
||||
BU_CK_VLS(vls);
|
||||
|
||||
bu_vls_printf(vls, "%s\n", line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int ac, char *av[])
|
||||
{
|
||||
int arg;
|
||||
struct bu_vls rtargs = BU_VLS_INIT_ZERO;
|
||||
struct bu_vls str = BU_VLS_INIT_ZERO;
|
||||
|
||||
const char *RT = NULL;
|
||||
const char *DB = NULL;
|
||||
const char *PIX = NULL;
|
||||
const char *LOG = NULL;
|
||||
const char *CMP = NULL;
|
||||
const char *ELP = NULL;
|
||||
|
||||
char root[MAXPATHLEN] = {0};
|
||||
char db[MAXPATHLEN] = {0};
|
||||
char pix[MAXPATHLEN] = {0};
|
||||
char thisp[MAXPATHLEN] = {0};
|
||||
char *argv[MAXPATHLEN] = {NULL};
|
||||
struct bu_vls vp = BU_VLS_INIT_ZERO;
|
||||
|
||||
long MAXTIME = 0;
|
||||
long TIMEFRAME = 0;
|
||||
|
||||
int64_t start = 0;
|
||||
int ret = 0;
|
||||
|
||||
void (*verbose_echo)(const char *, ...) = sink;
|
||||
void (*echo)(const char *, ...) = record;
|
||||
|
||||
bu_setprogname(av[0]);
|
||||
|
||||
/* process the argument list for commands */
|
||||
for (arg=1; arg<ac; arg++) {
|
||||
if (BU_STR_EQUAL(av[arg], "clean")) {
|
||||
bu_setenv("CLEAN", "1", 1);
|
||||
continue;
|
||||
}
|
||||
if (BU_STR_EQUAL(av[arg], "clobber")) {
|
||||
bu_setenv("CLEAN", "1", 1);
|
||||
bu_setenv("CLOBBER", "1", 1);
|
||||
continue;
|
||||
}
|
||||
if (BU_STR_EQUAL(av[arg], "h")) {
|
||||
bu_setenv("HELP", "1", 1);
|
||||
continue;
|
||||
}
|
||||
if (BU_STR_EQUAL(av[arg], "help")) {
|
||||
bu_setenv("HELP", "1", 1);
|
||||
continue;
|
||||
}
|
||||
if (bu_strncasecmp(av[arg], "instruct", 8)) {
|
||||
bu_setenv("INSTRUCTIONS", "1", 1);
|
||||
continue;
|
||||
}
|
||||
if (BU_STR_EQUAL(av[arg], "start")) {
|
||||
continue;
|
||||
}
|
||||
if (BU_STR_EQUAL(av[arg], "quiet")) {
|
||||
bu_setenv("QUIET", "1", 1);
|
||||
continue;
|
||||
}
|
||||
if (BU_STR_EQUAL(av[arg], "verbose")) {
|
||||
bu_setenv("VERBOSE", "1", 1);
|
||||
continue;
|
||||
}
|
||||
if (BU_STR_EQUAL(av[arg], "run")) {
|
||||
bu_setenv("RUN", "1", 1);
|
||||
continue;
|
||||
}
|
||||
if (strchr(av[arg], '=')) {
|
||||
/* TODO: !!! make sure this still works */
|
||||
char *var = bu_strdup(av[arg]);
|
||||
char *val = strtok(var, "=");
|
||||
if (var && val) {
|
||||
bu_setenv(var, val, 1);
|
||||
}
|
||||
bu_free(var, "strdup av[arg]");
|
||||
continue;
|
||||
}
|
||||
bu_log("WARNING: Passing unknown option [%s] to RT\n", av[arg]);
|
||||
bu_vls_printf(&rtargs, " %s", av[arg]);
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* handle help before main processing
|
||||
***/
|
||||
if (bu_str_true(getenv("HELP"))) {
|
||||
bu_log("Usage: %s [command(s)] [OPTION=value] [RT_OPTIONS]\n", av[0]);
|
||||
bu_log("\n");
|
||||
bu_log("Available commands:\n");
|
||||
bu_log(" clean\n");
|
||||
bu_log(" clobber\n");
|
||||
bu_log(" help (this is what you are reading right now)\n");
|
||||
bu_log(" instructions\n");
|
||||
bu_log(" quiet\n");
|
||||
bu_log(" verbose\n");
|
||||
bu_log(" run (this is probably what you want)\n");
|
||||
bu_log("\n");
|
||||
bu_log("Available options:\n");
|
||||
bu_log(" RT=/path/to/rt_binary (e.g., rt)\n");
|
||||
bu_log(" DB=/path/to/reference/geometry (e.g. ../db)\n");
|
||||
bu_log(" PIX=/path/to/reference/images (e.g., ../pix)\n");
|
||||
bu_log(" LOG=/path/to/reference/logs (e.g., ../pix)\n");
|
||||
bu_log(" CMP=/path/to/pixcmp_tool (e.g., pixcmp)\n");
|
||||
bu_log(" ELP=/path/to/time_tool (e.g., elapsed.sh)\n");
|
||||
bu_log(" TIMEFRAME=#seconds (default 32)\n");
|
||||
bu_log(" MAXTIME=#seconds (default 300)\n");
|
||||
bu_log(" DEVIATION=%%deviation (default 3)\n");
|
||||
bu_log(" AVERAGE=#frames (default 3)\n");
|
||||
bu_log("\n");
|
||||
bu_log("Available RT options:\n");
|
||||
bu_log(" -P# (e.g., -P1 to force single CPU)\n");
|
||||
bu_log(" See the 'rt' manpage for additional options\n");
|
||||
bu_log("\n");
|
||||
bu_log("The BRL-CAD Benchmark tests the overall performance of a system\n");
|
||||
bu_log("compared to a stable well-known baseline. The Benchmark calculates a\n");
|
||||
bu_log("figure-of-merit for this system that may be directly compared to other\n");
|
||||
bu_log("Benchmark runs on other system configurations.\n");
|
||||
bu_log("\n");
|
||||
bu_log("BRL-CAD is a powerful cross-platform open source solid modeling system.\n");
|
||||
bu_log("For more information about BRL-CAD, see http://brlcad.org\n");
|
||||
bu_log("\n");
|
||||
bu_log("Run '%s instructions' or see the manpage for additional information.\n", av[0]);
|
||||
bu_exit(1, NULL);
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* handle instructions before main processing
|
||||
***/
|
||||
if (bu_str_true(getenv("INSTRUCTIONS"))) {
|
||||
bu_log("\n");
|
||||
bu_log("This program runs the BRL-CAD Benchmark. The benchmark suite will\n");
|
||||
bu_log("test the performance of a system by iteratively rendering several\n");
|
||||
bu_log("well-known datasets into 512x512 images where performance metrics are\n");
|
||||
bu_log("documented and fairly well understood. The local machine's\n");
|
||||
bu_log("performance is compared to the base system (called VGR) and a numeric\n");
|
||||
bu_log("\"VGR\" multiplier of performance is computed. This number is a\n");
|
||||
bu_log("simplified metric from which one may qualitatively compare cpu and\n");
|
||||
bu_log("cache performance, versions of BRL-CAD, and different compiler\n");
|
||||
bu_log("characteristics.\n");
|
||||
bu_log("\n");
|
||||
bu_log("The suite is intended to be run from a source distribution of BRL-CAD\n");
|
||||
bu_log("after the package has been compiled either directly or via a make\n");
|
||||
bu_log("build system target. There are, however, several environment\n");
|
||||
bu_log("variables that will modify how the BRL-CAD benchmark behaves so that\n");
|
||||
bu_log("it may be run in a stand-alone environment:\n");
|
||||
bu_log("\n");
|
||||
bu_log(" RT - the rt binary (e.g. ../src/rt/rt or /usr/brlcad/bin/rt)\n");
|
||||
bu_log(" DB - the directory containing the reference geometry (e.g. ../db)\n");
|
||||
bu_log(" PIX - the directory containing the reference images (e.g. ../pix)\n");
|
||||
bu_log(" LOG - the directory containing the reference logs (e.g. ../pix)\n");
|
||||
bu_log(" CMP - the name of a pixcmp tool (e.g. ./pixcmp or cmp)\n");
|
||||
bu_log(" ELP - the name of an elapsed time tool (e.g. ../sh/elapsed.sh)\n");
|
||||
bu_log(" TIMEFRAME - the minimum number of seconds each trace needs to take\n");
|
||||
bu_log(" MAXTIME - the maximum number of seconds to spend on any test\n");
|
||||
bu_log(" DEVIATION - the minimum sufficient %% deviation from the average\n");
|
||||
bu_log(" AVERAGE - how many frames to average together\n");
|
||||
bu_log(" VERBOSE - turn on extra debug output for testing/development\n");
|
||||
bu_log(" QUIET - turn off all printing output (writes results to summary)\n");
|
||||
bu_log(" INSTRUCTIONS - display detailed instructions\n");
|
||||
bu_log(" RUN - start a benchmark analysis\n");
|
||||
bu_log("\n");
|
||||
bu_log("The TIMEFRAME, MAXTIME, DEVIATION, and AVERAGE options control how the\n");
|
||||
bu_log("benchmark will proceed including how long it should take. Each\n");
|
||||
bu_log("individual benchmark run will consume at least a minimum TIMEFRAME of\n");
|
||||
bu_log("wallclock time so that the results can stabilize. After consuming at\n");
|
||||
bu_log("least the minimum TIMEFRAME, additional frames may be computed until\n");
|
||||
bu_log("the standard deviation from the last AVERAGE count of frames is below\n");
|
||||
bu_log("the specified DEVIATION. When a test is run and it completes in less\n");
|
||||
bu_log("than TIMEFRAME, the raytrace is restarted using double the number of\n");
|
||||
bu_log("rays from the previous run. If the machine is fast enough, the\n");
|
||||
bu_log("benchmark may accelerate the number or rays being fired. These\n");
|
||||
bu_log("additional rays are hypersampled but without any jitter, so it's\n");
|
||||
bu_log("effectively performing a multiplier amount of work over the initial\n");
|
||||
bu_log("frame.\n");
|
||||
bu_log("\n");
|
||||
bu_log("Please send your BRL-CAD Benchmark results to the developers along with\n");
|
||||
bu_log("detailed system information to <devs@brlcad.org>. Include at least:\n");
|
||||
bu_log("\n");
|
||||
bu_log(" 0) Compiler name and version (e.g. gcc --version)\n");
|
||||
bu_log(" 1) All generated log files (i.e. *.log* after benchmark completes)\n");
|
||||
bu_log(" 2) Anything else you think might be relevant to performance\n");
|
||||
bu_log("\n");
|
||||
bu_log("The manual page has even more information and specific usage examples.\n");
|
||||
bu_log("Run 'brlman benchmark'.\n");
|
||||
bu_log("\n");
|
||||
bu_exit(0, NULL);
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* handle clean/clobber before main processing
|
||||
***/
|
||||
if (bu_str_true(getenv("CLEAN"))) {
|
||||
size_t i;
|
||||
size_t cnt;
|
||||
size_t num;
|
||||
char cwd[MAXPATHLEN] = {0};
|
||||
const char *tests[] = {"moss", "world", "star", "bldg391", "m35", "sphflake", NULL};
|
||||
char **paths = NULL;
|
||||
int printed = 0;
|
||||
|
||||
bu_log("\n");
|
||||
if (bu_str_true(getenv("CLOBBER"))) {
|
||||
bu_log("About to wipe out all benchmark images and log files in %s\n", bu_getcwd(cwd, MAXPATHLEN));
|
||||
bu_log("Send SIGINT (type ^C) within 5 seconds to abort\n");
|
||||
sleep(5);
|
||||
} else {
|
||||
bu_log("Deleting most benchmark images and log files in %s\n", bu_getcwd(cwd, MAXPATHLEN));
|
||||
bu_log("Running '%s clobber' will remove run logs.\n", av[0]);
|
||||
}
|
||||
bu_log("\n");
|
||||
|
||||
for (i=0; tests[i]; i++) {
|
||||
struct bu_vls pattern_str = BU_VLS_INIT_ZERO;
|
||||
char *pattern[5] = {NULL, NULL, NULL, NULL, NULL};
|
||||
size_t j;
|
||||
|
||||
/* rm -f $i.log $i.pix $i-[0-9]*.log $i-[0-9]*.pix */
|
||||
bu_vls_printf(&pattern_str, "%s.log %s.pix %s-[0-9]*.log %s-[0-9]*.pix", tests[i], tests[i], tests[i], tests[i]);
|
||||
bu_log("rm -f %s\n", bu_vls_cstr(&pattern_str));
|
||||
|
||||
j = bu_argv_from_string(pattern, 4, bu_vls_addr(&pattern_str));
|
||||
while (j > 0) {
|
||||
num = bu_file_glob(pattern[j-1], paths);
|
||||
if (!num || !paths || !paths[0]) {
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
cnt = num;
|
||||
while (num > 0) {
|
||||
bu_file_delete(paths[num-1]);
|
||||
num--;
|
||||
}
|
||||
bu_argv_free(cnt, paths);
|
||||
paths = NULL;
|
||||
j--;
|
||||
}
|
||||
bu_vls_free(&pattern_str);
|
||||
}
|
||||
|
||||
if (bu_str_true(getenv("CLOBBER"))) {
|
||||
/* NEVER automatically delete the summary file, but go
|
||||
* ahead with the rest.
|
||||
*/
|
||||
|
||||
num = bu_file_glob("benchmark-[0-9]*-run.log", paths);
|
||||
cnt = num;
|
||||
while (num > 0) {
|
||||
if (paths) {
|
||||
bu_log("rm -f %s\n", paths[num-1]);
|
||||
bu_file_delete(paths[num-1]);
|
||||
}
|
||||
num--;
|
||||
}
|
||||
bu_argv_free(cnt, paths);
|
||||
paths = NULL;
|
||||
}
|
||||
|
||||
if (bu_file_exists("summary", NULL)) {
|
||||
if (!printed) {
|
||||
bu_log("\nThe following files must be removed manually:\n");
|
||||
printed=1;
|
||||
}
|
||||
bu_log("summary ");
|
||||
}
|
||||
num = bu_file_glob("benchmark-[0-9]*-run.log", paths);
|
||||
cnt = num;
|
||||
while (num > 0) {
|
||||
if (!printed) {
|
||||
bu_log("\nThe following files must be removed manually:\n");
|
||||
printed=1;
|
||||
}
|
||||
if (paths)
|
||||
bu_log("%s ", paths[num-1]);
|
||||
num--;
|
||||
}
|
||||
bu_argv_free(cnt, paths);
|
||||
paths = NULL;
|
||||
|
||||
if (printed) {
|
||||
bu_log("\n");
|
||||
}
|
||||
|
||||
if (bu_str_true(getenv("CLOBBER"))) {
|
||||
bu_log("\nBenchmark clobber complete.\n");
|
||||
} else {
|
||||
bu_log("\nBenchmark clean complete.\n");
|
||||
}
|
||||
bu_exit(0, NULL);
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* B E G I N
|
||||
***/
|
||||
|
||||
if (bu_str_false(getenv("RUN"))) {
|
||||
bu_exit(1, "Type '%s help' for usage.\n", av[0]);
|
||||
}
|
||||
|
||||
/* where to write results */
|
||||
{
|
||||
int fd;
|
||||
const char *logfile;
|
||||
bu_vls_printf(&str, "run-%d-benchmark.log", bu_pid());
|
||||
logfile = bu_vls_addr(&str);
|
||||
bu_setenv("LOGFILE", logfile, 1);
|
||||
fd = open(logfile, O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0 || !bu_file_writable(logfile)) {
|
||||
if (!BU_STR_EQUAL(logfile, "/dev/null")) {
|
||||
bu_log("ERROR: Unable to log to %s\n", logfile);
|
||||
}
|
||||
/* FIXME: not valid logfile on windows, use 'nul' */
|
||||
bu_setenv("LOGFILE", "/dev/null", 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (bu_str_true(getenv("QUIET"))) {
|
||||
if (bu_str_true(getenv("VERBOSE"))) {
|
||||
bu_log("Verbose output quelled by quiet option. Further output disabled.\n");
|
||||
}
|
||||
} else {
|
||||
if (bu_str_true(getenv("VERBOSE"))) {
|
||||
verbose_echo=display;
|
||||
bu_log("Verbose output enabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
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);
|
||||
strftime(rfc2822, sizeof(rfc2822), "%a, %d %b %Y %H:%M:%S %Z", localtime(&t));
|
||||
|
||||
if (uname(&n) == 0) {
|
||||
bu_vls_printf(&v, "%s %s %s %s %s", n.sysname, n.nodename, n.release, n.version, n.machine);
|
||||
} else {
|
||||
bu_vls_strcat(&v, "unknown");
|
||||
}
|
||||
#endif
|
||||
|
||||
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("%s\n\n", bu_vls_addr(&v));
|
||||
}
|
||||
|
||||
|
||||
bu_dir(root, MAXPATHLEN, BU_DIR_BIN, NULL);
|
||||
bu_dir(db, MAXPATHLEN, BU_DIR_DATA, "db", NULL);
|
||||
bu_dir(pix, MAXPATHLEN, BU_DIR_DATA, "pix" , NULL);
|
||||
bu_dir(thisp, MAXPATHLEN, BU_DIR_CURR, NULL);
|
||||
|
||||
bu_vls_printf(&vp,
|
||||
"%s/rt "
|
||||
"%s/rt "
|
||||
"./rt",
|
||||
root, thisp);
|
||||
bu_argv_from_string(argv, 32, bu_vls_addr(&vp));
|
||||
look_for(verbose_echo, executable, "the BRL-CAD raytracer", "RT", (const char **)argv);
|
||||
bu_vls_trunc(&vp, 0);
|
||||
|
||||
bu_vls_printf(&vp,
|
||||
"%s/moss.g "
|
||||
"%s/db/moss.g "
|
||||
"%s/../db/moss.g "
|
||||
"./db/moss.g "
|
||||
"./moss.g",
|
||||
db, thisp, thisp);
|
||||
bu_argv_from_string(argv, 32, bu_vls_addr(&vp));
|
||||
look_for(verbose_echo, file, "a benchmark geometry directory", "DB", (const char **)argv);
|
||||
bu_vls_trunc(&vp, 0);
|
||||
if (getenv("DB") && !bu_file_directory(getenv("DB"))) {
|
||||
bu_setenv("DB", bu_path_dirname(getenv("DB")), 1);
|
||||
}
|
||||
|
||||
bu_vls_printf(&vp,
|
||||
"%s/moss.pix "
|
||||
"%s/pix/moss.pix "
|
||||
"%s/../pix/moss.pix "
|
||||
"%s/../../pix/moss.pix "
|
||||
"%s/../../../pix/moss.pix "
|
||||
"./pix/moss.pix "
|
||||
"./moss.pix",
|
||||
pix, thisp, thisp, thisp, thisp);
|
||||
bu_argv_from_string(argv, 32, bu_vls_addr(&vp));
|
||||
look_for(verbose_echo, file, "a benchmark reference image directory", "PIX", (const char **)argv);
|
||||
bu_vls_trunc(&vp, 0);
|
||||
if (getenv("PIX") && !bu_file_directory(getenv("PIX"))) {
|
||||
bu_setenv("PIX", bu_path_dirname(getenv("PIX")), 1);
|
||||
}
|
||||
|
||||
const char *pix_env = getenv("PIX");
|
||||
bu_vls_printf(&vp,
|
||||
"%s "
|
||||
"%s "
|
||||
"%s/pix "
|
||||
"%s/../pix "
|
||||
"%s/../../pix "
|
||||
"%s/../../../pix "
|
||||
"./pix",
|
||||
pix_env ? pix_env : "", 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);
|
||||
|
||||
bu_vls_printf(&vp,
|
||||
"%s/pixcmp "
|
||||
"%s/pixcmp "
|
||||
"%s/bench/pixcmp "
|
||||
"%s/../bench/pixcmp "
|
||||
"./pixcmp",
|
||||
root, thisp, thisp, thisp);
|
||||
bu_argv_from_string(argv, 32, bu_vls_addr(&vp));
|
||||
look_for(verbose_echo, executable, "a pixel comparison utility", "CMP", (const char **)argv);
|
||||
bu_vls_trunc(&vp, 0);
|
||||
|
||||
/* FIXME: elapsed is no more */
|
||||
bu_vls_printf(&vp,
|
||||
"%s/elapsed.sh "
|
||||
"%s/elapsed.sh "
|
||||
"%s/sh/elapsed.sh "
|
||||
"%s/../sh/elapsed.sh "
|
||||
"%s/../../sh/elapsed.sh "
|
||||
"%s/../../../sh/elapsed.sh "
|
||||
"./elapsed.sh",
|
||||
root, thisp, thisp, thisp, thisp, thisp);
|
||||
bu_argv_from_string(argv, 32, bu_vls_addr(&vp));
|
||||
look_for(verbose_echo, script, "a time elapsed utility", "ELP", (const char **)argv);
|
||||
bu_vls_trunc(&vp, 0);
|
||||
|
||||
/*********************
|
||||
* output parameters *
|
||||
*********************/
|
||||
|
||||
/* sanity check, output all the final settings together */
|
||||
RT = getenv("RT");
|
||||
if (RT && strlen(RT) > 0) {
|
||||
echo("Using [%s] for RT\n", RT);
|
||||
} else {
|
||||
bu_exit(1, "ERROR: Could not find the BRL-CAD raytracer\n");
|
||||
}
|
||||
|
||||
DB = getenv("DB");
|
||||
if (DB && strlen(DB) > 0) {
|
||||
echo("Using [%s] for DB\n", DB);
|
||||
} else {
|
||||
bu_exit(1, "ERROR: Could not find the BRL-CAD database directory\n");
|
||||
}
|
||||
|
||||
PIX = getenv("PIX");
|
||||
if (PIX && strlen(PIX) > 0) {
|
||||
echo("Using [%s] for PIX\n", PIX);
|
||||
} else {
|
||||
bu_exit(1, "ERROR: Could not find the BRL-CAD reference images\n");
|
||||
}
|
||||
|
||||
LOG = getenv("LOG");
|
||||
if (LOG && strlen(LOG) > 0) {
|
||||
echo("Using [%s] for LOG\n", LOG);
|
||||
} else {
|
||||
bu_exit(1, "ERROR: Could not find the BRL-CAD reference logs\n");
|
||||
}
|
||||
|
||||
CMP = getenv("CMP");
|
||||
if (CMP && strlen(CMP) > 0) {
|
||||
echo("Using [%s] for CMP\n", CMP);
|
||||
} else {
|
||||
bu_exit(1, "ERROR: Could not find the BRL-CAD pixel comparison utility\n");
|
||||
}
|
||||
|
||||
ELP = getenv("ELP");
|
||||
if (ELP && strlen(ELP) > 0) {
|
||||
echo("Using [%s] for ELP\n", ELP);
|
||||
} else {
|
||||
bu_exit(1, "ERROR: Could not find the BRL-CAD time elapsed script\n");
|
||||
}
|
||||
|
||||
/* determine the minimum time requirement in seconds for a single test run */
|
||||
set_if_unset(echo, verbose_echo, "TIMEFRAME", "32");
|
||||
|
||||
/* approximate maximum time in seconds that a given test is allowed to take */
|
||||
set_if_unset(echo, verbose_echo, "MAXTIME", "300");
|
||||
{
|
||||
char *mtimestr = getenv("MAXTIME");
|
||||
MAXTIME = (mtimestr) ? strtol(mtimestr, NULL, 0) : 300;
|
||||
char *timeframestr = getenv("TIMEFRAME");
|
||||
TIMEFRAME = (timeframestr) ? strtol(timeframestr, NULL, 0) : 32;
|
||||
if (MAXTIME < TIMEFRAME) {
|
||||
bu_exit(1, "ERROR: MAXTIME must be greater or equal to TIMEFRAME\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* maximum deviation percentage */
|
||||
set_if_unset(echo, verbose_echo, "DEVIATION", "3");
|
||||
|
||||
/* maximum number of iterations to average */
|
||||
set_if_unset(echo, verbose_echo, "AVERAGE", "3");
|
||||
|
||||
/* end of settings, separate the output */
|
||||
echo("\n");
|
||||
|
||||
|
||||
/**************************
|
||||
* output run-time status *
|
||||
**************************/
|
||||
|
||||
/* determine raytracer version */
|
||||
echo("RT reports the following version information:\n");
|
||||
{
|
||||
struct bu_vls rtout = BU_VLS_INIT_ZERO;
|
||||
struct bu_vls grep1 = BU_VLS_INIT_ZERO;
|
||||
struct bu_vls grep2 = BU_VLS_INIT_ZERO;
|
||||
|
||||
RT = getenv("RT");
|
||||
|
||||
bu_exec(RT, NULL, &rtout, &rtout);
|
||||
bu_grep("BRL-CAD", bu_vls_cstr(&rtout), stashline, (void *)&grep1);
|
||||
bu_grep("Release", bu_vls_cstr(&grep1), stashline, (void *)&grep2);
|
||||
if (bu_vls_strlen(&grep2) > 0) {
|
||||
echo("%s\n", bu_vls_addr(&grep2));
|
||||
} else {
|
||||
echo("Unknown\n\n");
|
||||
}
|
||||
|
||||
bu_vls_free(&grep2);
|
||||
bu_vls_free(&grep1);
|
||||
bu_vls_free(&rtout);
|
||||
}
|
||||
|
||||
/* let the user know about how long this might take */
|
||||
{
|
||||
struct bu_vls elapsed = BU_VLS_INIT_ZERO;
|
||||
double mintime = 6.0 * TIMEFRAME;
|
||||
double maxtime = 6.0 * MAXTIME;
|
||||
double estimate = 3.0 * mintime;
|
||||
|
||||
if (mintime < 1.0)
|
||||
mintime = 0; /* zero is okay */
|
||||
bu_vls_sprintf(&elapsed, "%s", format_elapsed(mintime));
|
||||
echo("Minimum run time is %s\n", bu_vls_cstr(&elapsed));
|
||||
|
||||
if (maxtime < 1.0)
|
||||
maxtime = 1.0; /* zero would be misleading */
|
||||
bu_vls_sprintf(&elapsed, "%s", format_elapsed(maxtime));
|
||||
echo("Maximum run time is %s\n", bu_vls_cstr(&elapsed));
|
||||
|
||||
if (estimate > maxtime)
|
||||
estimate = maxtime;
|
||||
|
||||
echo("Estimated time is %s\n", format_elapsed(estimate));
|
||||
}
|
||||
|
||||
/************************
|
||||
* Run the actual tests *
|
||||
************************/
|
||||
|
||||
start = bu_gettime();
|
||||
echo("Running the BRL-CAD Benchmark tests... please wait ...\n\n");
|
||||
|
||||
ret += bench("moss");
|
||||
ret += bench("world");
|
||||
ret += bench("star");
|
||||
ret += bench("bldg391");
|
||||
ret += bench("m35");
|
||||
ret += bench("sphflake");
|
||||
|
||||
echo("\n... Done.\n");
|
||||
echo("Total testing time elapsed: %.2lfs\n", format_elapsed(bu_gettime() - start));
|
||||
|
||||
if (ret != 0) {
|
||||
echo("\n");
|
||||
echo("THE BENCHMARK ANALYSIS DID NOT COMPLETE SUCCESSFULLY.\n");
|
||||
echo("\n");
|
||||
echo("A benchmark failure means this is not a viable install of BRL-CAD. This may be\n");
|
||||
echo("a new bug or (more likely) is a compilation configuration error. Ensure your\n");
|
||||
echo("compiler has strict aliasing disabled, compilation is optimized, and you have\n");
|
||||
echo("installed BRL-CAD (some platforms require this). If you still get a failure,\n");
|
||||
echo("please report your configuration information to benchmark@brlcad.org\n");
|
||||
echo("\n");
|
||||
echo("Output was saved to %s from %s\n", LOG, bu_dir(NULL, 0, BU_DIR_CURR, NULL));
|
||||
echo("Run '%s clean' to remove generated pix files.\n", av[0]);
|
||||
echo("Benchmark testing failed.\n");
|
||||
return 2;
|
||||
}
|
||||
|
||||
/******************************
|
||||
* compute and output results *
|
||||
******************************/
|
||||
{
|
||||
struct bu_vls performance = BU_VLS_INIT_ZERO;
|
||||
ret = perf(&performance, /*...!!!...*/"moss world star bldg391 m35 sphflake", (const char **)argv);
|
||||
|
||||
if (ret == 0) {
|
||||
/* !!! write performance to summary */
|
||||
}
|
||||
|
||||
echo("\n");
|
||||
echo("The following files have been generated and/or modified:\n");
|
||||
echo(" *.log ..... final log files for each individual raytrace test\n");
|
||||
echo(" *.pix ..... final pix image files for each individual raytrace test\n");
|
||||
echo(" *.log.* ... log files for previous frames and raytrace tests\n");
|
||||
echo(" *.pix.* ... pix image files for previous frames and raytrace tests\n");
|
||||
echo(" summary ... performance results summary, 2 lines per run\n");
|
||||
echo("\n");
|
||||
echo("Run '%s clean' to remove generated pix files.\n", av[0]);
|
||||
echo("\n");
|
||||
|
||||
echo("Summary:\n");
|
||||
echo("%s\n", bu_vls_cstr(&performance));
|
||||
|
||||
{
|
||||
double vgr = calculate_vgr(&performance);
|
||||
|
||||
if (vgr > 0.0) {
|
||||
echo("\n");
|
||||
echo("#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#\n");
|
||||
echo("Benchmark results indicate an approximate VGR performance metric of %ld\n", (long int)vgr);
|
||||
echo("Logarithmic VGR metric is %.2lf (natural logarithm is %.2lf)\n", log10(vgr), log(vgr));
|
||||
echo("#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#\n");
|
||||
echo("\n");
|
||||
echo("These numbers seem to indicate that this machine is approximately %ld times", (long int)vgr);
|
||||
echo("faster than the reference machine being used for comparison, a VAX 11/780\n");
|
||||
echo("running 4.3 BSD named VGR. These results are in fact approximately %.2lf", log10(vgr));
|
||||
echo("orders of magnitude faster than the reference.\n");
|
||||
echo("\n");
|
||||
|
||||
echo("Here are some other approximated VGR results for perspective:\n");
|
||||
echo(" 120 on a 200MHz R5000 running IRIX 6.5\n");
|
||||
echo(" 250 on a 500 MHz Pentium III running RedHat 7.1\n");
|
||||
echo(" 550 on a dual 450 MHz UltraSPARC II running SunOS 5.8\n");
|
||||
echo(" 1000 on a dual 500 MHz G4 PowerPC running Mac OS X 10.2\n");
|
||||
echo(" 1500 on a dual 1.66 GHz Athlon MP 2000+ running RedHat 7.3\n");
|
||||
echo(" 52000 on a 4x4 CPU 2.93 GHz Xeon running RHEL Server 5.4\n");
|
||||
echo(" 65000 on a 512 CPU 400 MHz R12000 Running IRIX 6.5\n");
|
||||
echo("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/* TODO: !!! determine if this build is optimized or not */
|
||||
/* TODO: !!! determine if this build has run-time debugging */
|
||||
/* TODO: !!! determine if this build has compile-time debugging */
|
||||
}
|
||||
|
||||
/* if this was a valid benchmark run, encourage submission of results. */
|
||||
echo("You are encouraged to submit your benchmark results and system\n");
|
||||
echo("configuration information to benchmark@brlcad.org\n");
|
||||
echo(" ~~~~~~~~~~~~~~~~~~~~\n");
|
||||
|
||||
/* include information about the operating system and hardware in the log */
|
||||
echo("Including additional kernel and hardware information in the log.\n\n");
|
||||
|
||||
/* TODO: !!! print out system information via sysctl/prtdiag/prtconf/hinv/etc */
|
||||
bu_vls_free(&rtargs);
|
||||
|
||||
bu_vls_printf(&vp,
|
||||
"%s/../share/brlcad/*.*.*/doc/benchmark.tr "
|
||||
"%s/share/brlcad/*.*.*/doc/benchmark.tr "
|
||||
"%s/share/brlcad/doc/benchmark.tr "
|
||||
"%s/share/doc/benchmark.tr "
|
||||
"%s/doc/benchmark.tr "
|
||||
"%s/../doc/benchmark.tr "
|
||||
"./benchmark.tr",
|
||||
thisp, thisp, thisp, thisp, thisp, thisp);
|
||||
bu_argv_from_string(argv, 32, bu_vls_addr(&vp));
|
||||
|
||||
look_for(NULL, file, "BENCHMARK_TR", "benchmark", (const char **)argv);
|
||||
bu_vls_trunc(&vp, 0);
|
||||
|
||||
/* TODO: look for benchmark document here? */
|
||||
|
||||
echo("Output was saved to %s from %s\n", LOG, bu_dir(NULL, 0, BU_DIR_CURR, NULL));
|
||||
echo("Benchmark testing complete.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* tab-width: 8
|
||||
* mode: C
|
||||
* indent-tabs-mode: t
|
||||
* c-file-style: "stroustrup"
|
||||
* End:
|
||||
* ex: shiftwidth=4 tabstop=8
|
||||
*/
|
||||
@@ -1,96 +0,0 @@
|
||||
/* C L E A N . C
|
||||
* BRL-CAD
|
||||
*
|
||||
* Copyright (c) 2011-2026 United States Government as represented by
|
||||
* the U.S. Army Research Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/** @file clean.c
|
||||
*
|
||||
* utility functions to clean output files
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "bu/file.h"
|
||||
#include "bu/str.h"
|
||||
#include "bu/vls.h"
|
||||
|
||||
|
||||
/* TODO: !!! needed */
|
||||
//int bu_file_move(const char *fn1, const char *fn2) {if (!fn1 || !fn2) return -1; return 0;}
|
||||
|
||||
extern int bu_file_copy(const char *fn1, const char *fn2);
|
||||
|
||||
|
||||
/**
|
||||
* conditionally removes or saves any .pix or .log files output.
|
||||
*/
|
||||
void
|
||||
clean_obstacles(const char *base_filename, int id)
|
||||
{
|
||||
struct bu_vls vp = BU_VLS_INIT_ZERO;
|
||||
struct bu_vls vpid = BU_VLS_INIT_ZERO;
|
||||
|
||||
if (BU_STR_EMPTY(base_filename))
|
||||
return;
|
||||
|
||||
/* look for an image file */
|
||||
bu_vls_printf(&vp, "%s.pix", base_filename);
|
||||
if (bu_file_exists(bu_vls_cstr(&vp), NULL)) {
|
||||
bu_vls_printf(&vpid, "%s-%d.pix", base_filename, id);
|
||||
if (bu_file_exists(bu_vls_cstr(&vpid), NULL)) {
|
||||
bu_file_delete(bu_vls_cstr(&vp));
|
||||
}
|
||||
//bu_file_move(bu_vls_cstr(&vp), bu_vls_cstr(&vpid));
|
||||
}
|
||||
|
||||
/* look for a log file */
|
||||
bu_vls_printf(&vp, "%s.log", base_filename);
|
||||
if (bu_file_exists(bu_vls_cstr(&vp), NULL)) {
|
||||
bu_vls_printf(&vpid, "%s-%d.log", base_filename, id);
|
||||
if (bu_file_exists(bu_vls_cstr(&vpid), NULL)) {
|
||||
bu_file_delete(bu_vls_cstr(&vp));
|
||||
}
|
||||
//bu_file_move(bu_vls_cstr(&vp), bu_vls_cstr(&vpid));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* tab-width: 8
|
||||
* mode: C
|
||||
* indent-tabs-mode: t
|
||||
* c-file-style: "stroustrup"
|
||||
* End:
|
||||
* ex: shiftwidth=4 tabstop=8
|
||||
*/
|
||||
@@ -1,96 +0,0 @@
|
||||
/* C O M P U T E . C
|
||||
* BRL-CAD
|
||||
*
|
||||
* Copyright (c) 2011-2026 United States Government as represented by
|
||||
* the U.S. Army Research Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/** @file compute.c
|
||||
*
|
||||
* run and computation functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/**
|
||||
* average [..numbers..]
|
||||
*
|
||||
* computes the integer average for a set of given numbers
|
||||
*/
|
||||
double
|
||||
average(int ac, double av[])
|
||||
{
|
||||
double total = 0.0;
|
||||
|
||||
if (ac < 1)
|
||||
return -0.0;
|
||||
|
||||
while (ac-- > 0) {
|
||||
total += av[ac];
|
||||
}
|
||||
return total / ac;
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
variance(int ac, double av[])
|
||||
{
|
||||
double avg;
|
||||
double err = 0.0;
|
||||
double num = ac;
|
||||
|
||||
if (ac < 1)
|
||||
return -0.0;
|
||||
else if (ac == 1)
|
||||
return 0.0;
|
||||
|
||||
avg = average(ac, av);
|
||||
|
||||
/* compute variance numerator for the population */
|
||||
while (ac-- > 0) {
|
||||
err += (av[ac] - avg) * (av[ac] - avg);
|
||||
}
|
||||
|
||||
/* return the sample variance */
|
||||
return err / (num - 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* tab-width: 8
|
||||
* mode: C
|
||||
* indent-tabs-mode: t
|
||||
* c-file-style: "stroustrup"
|
||||
* End:
|
||||
* ex: shiftwidth=4 tabstop=8
|
||||
*/
|
||||
Executable
+158
@@ -0,0 +1,158 @@
|
||||
#!/bin/sh
|
||||
# A Shell script to test LGT
|
||||
# @(#)$Header$ (BRL)
|
||||
|
||||
# Ensure /bin/sh
|
||||
export PATH || (echo "This isn't sh."; sh $0 $*; kill $$)
|
||||
|
||||
eval `machinetype.sh -b` # sets MACHINE, UNIXTYPE, HAS_TCP
|
||||
if test -f ../.lgt.$MACHINE/lgt
|
||||
then
|
||||
LGT=../.lgt.$MACHINE/lgt
|
||||
DB=../.db.$MACHINE
|
||||
LD_LIBRARY_PATH=../.libcursor.$MACHINE:../.libtermio.$MACHINE:../.libbu.$MACHINE:../.libbn.$MACHINE:../.librt.$MACHINE:../.libfb.$MACHINE:../.libpkg.$MACHINE:../.libsysv.$MACHINE:$LD_LIBRARY_PATH
|
||||
else
|
||||
if test -f ../lgt/lgt
|
||||
then
|
||||
echo "Can't find LGT"
|
||||
exit 1
|
||||
fi
|
||||
LGT=../lgt/lgt
|
||||
DB=../db
|
||||
LD_LIBRARY_PATH=../libcursor:../libtermio:../libbu:../libbn:../librt:../libfb:../libpkg:../libsysv:$LD_LIBRARY_PATH
|
||||
fi
|
||||
export LD_LIBRARY_PATH
|
||||
|
||||
CMP=./pixcmp
|
||||
if test ! -f $CMP
|
||||
then
|
||||
cake pixcmp
|
||||
fi
|
||||
|
||||
# Alliant NFS hack
|
||||
if test x${MACHINE} = xfx
|
||||
then
|
||||
cp ${LGT} /tmp/lgt
|
||||
cp ${CMP} /tmp/pixcmp
|
||||
LGT=/tmp/lgt
|
||||
CMP=/tmp/pixcmp
|
||||
fi
|
||||
|
||||
# This test of LGT assumes a "live" framebuffer here.
|
||||
if test x$FB_FILE = x
|
||||
then
|
||||
echo "Environment variable FB_FILE must be set to a real framebuffer"
|
||||
echo "for this test of LGT to operate correctly."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run the first set of tests
|
||||
|
||||
${LGT} ${DB}/lgt-test.g all.g << EOF
|
||||
# read light source data base
|
||||
v ../db/lgt-test.ldb
|
||||
# read material data base
|
||||
w ../db/lgt-test.mdb
|
||||
# force display window to be 512x512 pixels, should cause 8-to-1 zoom
|
||||
T 512
|
||||
# clear frame buffer
|
||||
E
|
||||
# set maximum bounces to 20
|
||||
K 20
|
||||
# turn hidden-line drawing off
|
||||
k 0
|
||||
# configure grid: 64 rays across
|
||||
G 64 0 0 0.0
|
||||
# turn perspective off
|
||||
p 0
|
||||
# change background to mauve
|
||||
b 111 66 66
|
||||
# read key frame
|
||||
j ../db/lgt-test.key
|
||||
# display view #3
|
||||
R
|
||||
# save image in file
|
||||
H lgt3a.pix
|
||||
# change frame buffer to disk file
|
||||
o lgt3b.pix
|
||||
# save a script of previous commands, to produce the "b" version.
|
||||
S script3
|
||||
# disable reading of key frame file
|
||||
j
|
||||
# change frame buffer back to default
|
||||
o
|
||||
# configure grid: 2.45 mm cells, centered about model origin, view size 225 mm
|
||||
G 2.45 1 1 225.0
|
||||
# change background to firebrick
|
||||
b 142 35 35
|
||||
# force frame buffer size to be 455 pixels across, should cause 4-to-1 zoom
|
||||
T 455
|
||||
# set automatic perspective at 0.25
|
||||
p 0.25
|
||||
# set anti-aliasing over-sampling factor to 2
|
||||
A 2
|
||||
# set maximum bounces to 20
|
||||
K 20
|
||||
# display view #1
|
||||
R
|
||||
# save image in file
|
||||
H lgt1a.pix
|
||||
# change frame buffer to disk file
|
||||
o lgt1b.pix
|
||||
# save a script
|
||||
S script1
|
||||
# change frame buffer back to default
|
||||
o
|
||||
# turn off anti-aliasing
|
||||
A 1
|
||||
# revert to auto-sizing of frame buffer
|
||||
T 0
|
||||
# set automatic perspective at 0.25
|
||||
p 0.25
|
||||
# select hidden-line drawing, reverse video
|
||||
k 2
|
||||
# configure grid: 128 rays across, centered at model RPP, view size 225mm
|
||||
G 128 0 0 225.0
|
||||
# display view #2
|
||||
R
|
||||
# save image in file
|
||||
H lgt2a.pix
|
||||
# change frame buffer to disk file
|
||||
o lgt2b.pix
|
||||
# save a script
|
||||
S script2
|
||||
# change frame buffer back to default
|
||||
o
|
||||
# bye
|
||||
q
|
||||
EOF
|
||||
if test $? = 0
|
||||
then :;
|
||||
else echo "Abnormal lgt exit"; exit 1
|
||||
fi
|
||||
|
||||
# Run the second set of tests. The scripts were created above.
|
||||
./script1 < /dev/null &&
|
||||
./script2 < /dev/null &&
|
||||
./script3 < /dev/null || { echo "Script test failed."; exit 1; }
|
||||
|
||||
FAIL=0
|
||||
for i in 1 2 3
|
||||
do
|
||||
if ${CMP} ../pix/lgt${i}.pix lgt${i}a.pix
|
||||
then :;
|
||||
else echo "Test $i A failed."; FAIL=1
|
||||
fi
|
||||
if ${CMP} ../pix/lgt${i}.pix lgt${i}b.pix
|
||||
then :;
|
||||
else echo "Test $i B failed."; FAIL=1
|
||||
fi
|
||||
done
|
||||
if test "$FAIL" -eq 0
|
||||
then
|
||||
echo "LGT Tested OK."
|
||||
exit 0
|
||||
fi
|
||||
echo "*** LGT does NOT work on this platform ***"
|
||||
exit 2
|
||||
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/bin/sh
|
||||
# A Shell script to extract the benchmark statistics, and build an
|
||||
# entry suitable for the tables in doc/benchmark.doc.
|
||||
# Note well that the command-line args may have embedded spaces.
|
||||
# Mike Muuss & Susan Muuss, 11-Sept-88.
|
||||
# @(#)$Header$ (BRL)
|
||||
|
||||
# Ensure /bin/sh
|
||||
export PATH || (sh $0 $*; kill $$)
|
||||
|
||||
NAME=$0
|
||||
if test "x$1" = x
|
||||
then
|
||||
echo "Usage: $NAME hostname [note1] [note2]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Save three args, because arg list will be reused below.
|
||||
# They may have embedded spaces in them.
|
||||
HOST="$1"
|
||||
NOTE1="$2"
|
||||
NOTE2="$3"
|
||||
|
||||
NEW_FILES="moss.log world.log star.log bldg391.log m35.log sphflake.log"
|
||||
REF_FILES="../pix/moss.log ../pix/world.log ../pix/star.log \
|
||||
../pix/bldg391.log ../pix/m35.log ../pix/sphflake.log"
|
||||
|
||||
for i in $NEW_FILES $REF_FILES
|
||||
do
|
||||
if test ! -f $i
|
||||
then
|
||||
echo "${NAME}: file $i does not exist, aborting"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Use TR to convert newlines to tabs.
|
||||
VGRREF=`grep RTFM $REF_FILES | \
|
||||
sed -n -e 's/^.*= *//' -e 's/ rays.*//p' | \
|
||||
tr '\012' '\011' `
|
||||
CURVALS=`grep RTFM $NEW_FILES | \
|
||||
sed -n -e 's/^.*= *//' -e 's/ rays.*//p' | \
|
||||
tr '\012' '\011' `
|
||||
|
||||
RATIO_LIST=""
|
||||
|
||||
# Trick: Force args $1 through $6 to the numbers in $CURVALS
|
||||
# This should be "set -- $CURVALS", but 4.2BSD /bin/sh can't handle it,
|
||||
# and CURVALS are all positive (ie, no leading dashes), so this is safe.
|
||||
set $CURVALS
|
||||
|
||||
while test $# -lt 6
|
||||
do echo "${NAME}: Warning, only $# times found, adding a zero."
|
||||
CURVALS="${CURVALS}0 "
|
||||
set $CURVALS
|
||||
done
|
||||
|
||||
for ref in $VGRREF
|
||||
do
|
||||
cur=$1
|
||||
shift
|
||||
RATIO=`echo "2k $cur $ref / p" | dc`
|
||||
# Note: append new value and a trail TAB to existing list.
|
||||
RATIO_LIST="${RATIO_LIST}$RATIO "
|
||||
done
|
||||
|
||||
# The number of plus signs must be one less than the number of elements.
|
||||
MEAN_ABS=`echo 2k $CURVALS +++++ 6/ p | dc`
|
||||
MEAN_REL=`echo 2k $RATIO_LIST +++++ 6/ p | dc`
|
||||
|
||||
# Note: Both RATIO_LIST and CURVALS have an extra trailing tab.
|
||||
# The question mark is for the mean field
|
||||
echo "Abs ${HOST} ${CURVALS}${MEAN_ABS} $NOTE1"
|
||||
echo "*vgr ${HOST} ${RATIO_LIST}${MEAN_REL} $NOTE2"
|
||||
+108
-488
@@ -1,514 +1,134 @@
|
||||
/* P I X C M P . C
|
||||
* BRL-CAD
|
||||
/*
|
||||
* P I X C M P . C
|
||||
*
|
||||
* Copyright (c) 2004-2026 United States Government as represented by
|
||||
* the U.S. Army Research Laboratory.
|
||||
* Compute the difference between two .pix files.
|
||||
* To establish context, a monochrome image is produced when there
|
||||
* are no differences; otherwise the channels that differ are
|
||||
* highlighted on differing pixels.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* version 2.1 as published by the Free Software Foundation.
|
||||
* This routine operates on a pixel-by-pixel basis, and thus
|
||||
* is independent of the resolution of the image.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this file; see the file named COPYING for more
|
||||
* information.
|
||||
*
|
||||
*/
|
||||
/** @file pixcmp.c
|
||||
*
|
||||
* Compute and summarily report differences between two .pix files.
|
||||
*
|
||||
* This routine operates on a pixel-by-pixel basis, and thus
|
||||
* is independent of the resolution of the image.
|
||||
* Author -
|
||||
* Charles M. Kennedy
|
||||
* Michael John Muuss
|
||||
*
|
||||
* Source -
|
||||
* SECAD/VLD Computing Consortium, Bldg 394
|
||||
* The U. S. Army Ballistic Research Laboratory
|
||||
* Aberdeen Proving Ground, Maryland 21005
|
||||
*
|
||||
* Copyright Notice -
|
||||
* This software is Copyright (C) 1988-2004 by the United States Army.
|
||||
* All rights reserved.
|
||||
*/
|
||||
#ifndef lint
|
||||
static const char RCSid[] = "@(#)$Header$ (BRL)";
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include "conf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
#include "bio.h"
|
||||
|
||||
// TODO - replace with std::filesystem::is_fifo
|
||||
#ifndef S_ISFIFO
|
||||
# ifdef S_IFIFO
|
||||
# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
|
||||
# else
|
||||
# define S_ISFIFO(mode) (0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include "bu/app.h"
|
||||
#include "bu/getopt.h"
|
||||
#include "bu/log.h"
|
||||
#include "bu/file.h"
|
||||
#include "bu/str.h"
|
||||
long matching;
|
||||
long off1;
|
||||
long offmany;
|
||||
|
||||
/* exit codes for argument processing errors */
|
||||
#define OPTS_ERROR 127
|
||||
#define FILE_ERROR 126
|
||||
char usage[] = "Usage: pixcmp f1.pix f2.pix\n";
|
||||
|
||||
/* exit codes for normal operation */
|
||||
#define EXIT_OFF_BY_NONE 0
|
||||
#define EXIT_OFF_BY_ONE 1
|
||||
#define EXIT_OFF_BY_MANY 2
|
||||
|
||||
enum diff {
|
||||
MATCHING,
|
||||
OFF_BY_ONE,
|
||||
OFF_BY_MANY,
|
||||
MISSING
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
usage(const char *name)
|
||||
{
|
||||
const char *unknown = "pixcmp";
|
||||
if (!name) {
|
||||
name = unknown;
|
||||
}
|
||||
|
||||
/* split to fit within ISO C90 max static string length < 509 chars */
|
||||
bu_log("Usage: %s [OPTIONS] FILE1 [FILE2 [SKIP1 [SKIP2]]]\n"
|
||||
"\n"
|
||||
" Compare two PIX files pixel by pixel (or byte by byte), optionally"
|
||||
" skipping initial pixels (or bytes) in one or both input files.\n"
|
||||
"\n", name);
|
||||
bu_log("Options:"
|
||||
" -b Iterate and print by bytes instead of by pixels.\n"
|
||||
" -s Print all that have the same matching values.\n"
|
||||
" -d Print all that have different values.\n"
|
||||
" -q Quiet. Suppress printing header and summary.\n"
|
||||
" -i SKIP\n"
|
||||
" Discard initial SKIP pixels (or bytes w/ -b) in FILE1 and FILE2 input.\n"
|
||||
" -i SKIP1:SKIP2\n"
|
||||
" Skip initial SKIP1 pixels (or bytes w/ -b) in FILE1 and SKIP2 in FILE2.\n"
|
||||
" -n COUNT\n"
|
||||
" Compare COUNT pixels (or bytes w/ -b). Stops by default at EOF.\n"
|
||||
"\n");
|
||||
bu_log("If either FILE is `-' or is missing, then input is read from standard input.\n"
|
||||
"If FILE1 and FILE2 are both standard input, then values must be interleaved.\n"
|
||||
"If the `-b' option is used, SKIP and COUNT values are bytes instead of pixels.\n"
|
||||
"Pixel numbers and bytes are indexed linearly from one.\n"
|
||||
"\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
handle_range_opt(const char *arg, size_t *skip1, size_t *skip2)
|
||||
{
|
||||
const char *endptr = arg;
|
||||
long val;
|
||||
|
||||
if ((arg == NULL) || ((skip1 == NULL) && (skip2 == NULL))) {
|
||||
/* nothing to do */
|
||||
return;
|
||||
}
|
||||
while ((endptr != NULL) && (endptr[0] != ':') && (endptr[0] != '\0')) {
|
||||
endptr++;
|
||||
}
|
||||
if (endptr == arg) {
|
||||
/* probably empty string */
|
||||
if (skip2) {
|
||||
endptr++;
|
||||
val = strtol(endptr, NULL, 10);
|
||||
*skip2 = (val < 0) ? 0 : val;
|
||||
}
|
||||
} else if ((endptr == NULL) || (endptr[0] == '\0')) {
|
||||
/* no : found */
|
||||
if (skip2) {
|
||||
val = strtol(arg, NULL, 10);
|
||||
*skip2 = (val < 0) ? 0 : val;
|
||||
}
|
||||
if (skip1 && skip2) {
|
||||
*skip1 = *skip2;
|
||||
}
|
||||
} else if (endptr[0] == ':') {
|
||||
/* found : */
|
||||
if (skip1) {
|
||||
val = strtol(arg, NULL, 10);
|
||||
*skip1 = (val < 0) ? 0 : val;
|
||||
}
|
||||
if (skip2) {
|
||||
endptr++; /* skip over : */
|
||||
val = strtol(endptr, NULL, 10);
|
||||
*skip2 = (val < 0) ? 0 : val;
|
||||
}
|
||||
} else {
|
||||
bu_exit(OPTS_ERROR, "Unexpected input processing [%s]\n", arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static enum diff
|
||||
compare_rgb(int r1, int g1, int b1, int r2, int g2, int b2, size_t *matching, size_t *off1, size_t *offmany, size_t *missing)
|
||||
{
|
||||
enum diff result = MISSING;
|
||||
|
||||
if ((r1 == r2 && r1 != -1)
|
||||
&& (g1 == g2 && g1 != -1)
|
||||
&& (b1 == b2 && b1 != -1))
|
||||
{
|
||||
result = 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 */
|
||||
if (r1 != r2) {
|
||||
if ((r1 > r2 ? r1 - r2 : r2 - r1) > 1) {
|
||||
result = OFF_BY_MANY;
|
||||
}
|
||||
}
|
||||
if (g1 != g2) {
|
||||
if ((g1 > g2 ? g1 - g2 : g2 - g1) > 1) {
|
||||
result = OFF_BY_MANY;
|
||||
}
|
||||
}
|
||||
if (b1 != b2) {
|
||||
if ((b1 > b2 ? b1 - b2 : b2 - b1) > 1) {
|
||||
result = OFF_BY_MANY;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result == OFF_BY_ONE) {
|
||||
(*off1)++;
|
||||
} else if (result == OFF_BY_MANY) {
|
||||
(*offmany)++;
|
||||
} else if (result == MATCHING) {
|
||||
(*matching)++;
|
||||
} else {
|
||||
(*missing)++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
int main(int argc, char **argv);
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const char *argv0 = argv[0];
|
||||
register FILE *f1, *f2;
|
||||
|
||||
FILE *f1 = NULL;
|
||||
FILE *f2 = NULL;
|
||||
struct stat sf1;
|
||||
struct stat sf2;
|
||||
|
||||
memset(&sf1, 0, sizeof(struct stat));
|
||||
memset(&sf2, 0, sizeof(struct stat));
|
||||
|
||||
size_t matching = 0;
|
||||
size_t off1 = 0;
|
||||
size_t offmany = 0;
|
||||
size_t missing = 0;
|
||||
|
||||
int c;
|
||||
int list_diff = 0;
|
||||
int list_same = 0;
|
||||
int print_bytes = 0;
|
||||
int quiet = 0;
|
||||
|
||||
size_t bytes = 0;
|
||||
size_t f1_skip = 0;
|
||||
size_t f2_skip = 0;
|
||||
size_t stop_after = 0;
|
||||
|
||||
bu_setprogname(argv[0]);
|
||||
|
||||
/* process opts */
|
||||
while ((c = bu_getopt(argc, argv, "sdbi:n:q?")) != -1) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
list_same = 1;
|
||||
break;
|
||||
case 'd':
|
||||
list_diff = 1;
|
||||
break;
|
||||
case 'b':
|
||||
print_bytes = 1;
|
||||
break;
|
||||
case 'i':
|
||||
handle_range_opt(bu_optarg, &f1_skip, &f2_skip);
|
||||
break;
|
||||
case 'n':
|
||||
{
|
||||
long num = strtol(bu_optarg, NULL, 10);
|
||||
stop_after = (num < 0) ? 0 : num;
|
||||
break;
|
||||
}
|
||||
case 'q':
|
||||
quiet = 1;
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
usage(argv0);
|
||||
return 0;
|
||||
default:
|
||||
exit(OPTS_ERROR);
|
||||
}
|
||||
}
|
||||
argc -= bu_optind;
|
||||
argv += bu_optind;
|
||||
|
||||
/* validate what is left over */
|
||||
if (argc < 1 || argc > 4) {
|
||||
bu_log("ERROR: incorrect number of arguments provided\n\n");
|
||||
usage(argv0);
|
||||
exit(OPTS_ERROR);
|
||||
}
|
||||
if ((argc > 0 && !argv[0]) || (argc > 1 && !argv[1])) {
|
||||
bu_log("ERROR: bad filename\n\n");
|
||||
usage(argv0);
|
||||
exit(OPTS_ERROR);
|
||||
}
|
||||
if ((argc > 2 && !argv[2]) || (argc > 3 && !argv[3])) {
|
||||
bu_log("ERROR: bad skip value\n\n");
|
||||
usage(argv0);
|
||||
exit(OPTS_ERROR);
|
||||
}
|
||||
|
||||
/* handle optional SKIP1 and SKIP2 following filenames */
|
||||
if (argc > 2) {
|
||||
char range[64] = {0};
|
||||
if (argc > 3) {
|
||||
snprintf(range, 64, "%s:%s", argv[2], argv[3]);
|
||||
} else {
|
||||
snprintf(range, 64, "%s", argv[2]);
|
||||
}
|
||||
handle_range_opt(range, &f1_skip, &f2_skip);
|
||||
}
|
||||
|
||||
if (!print_bytes) {
|
||||
if ((f1_skip > ((size_t)-1)/3)
|
||||
|| (f2_skip > ((size_t)-1)/3))
|
||||
{
|
||||
bu_log("ERROR: overflow, -i skip value(s) are too big {%zu:%zu}\n", f1_skip, f2_skip);
|
||||
exit(OPTS_ERROR);
|
||||
}
|
||||
f1_skip *= 3;
|
||||
f2_skip *= 3;
|
||||
if (stop_after > ((size_t)-1)/3)
|
||||
{
|
||||
bu_log("ERROR: overflow, -n number is too big {%zu}\n", stop_after);
|
||||
exit(OPTS_ERROR);
|
||||
}
|
||||
stop_after *= 3;
|
||||
}
|
||||
|
||||
if (BU_STR_EQUAL(argv[0], "-")) {
|
||||
f1 = stdin;
|
||||
} else if ((f1 = fopen(argv[0], "rb")) == NULL) {
|
||||
perror(argv[0]);
|
||||
exit(FILE_ERROR);
|
||||
}
|
||||
|
||||
if ((argc < 2) || BU_STR_EQUAL(argv[1], "-")) {
|
||||
f2 = stdin;
|
||||
} else if ((f2 = fopen(argv[1], "rb")) == NULL) {
|
||||
perror(argv[1]);
|
||||
exit(FILE_ERROR);
|
||||
}
|
||||
|
||||
setmode(fileno(stdin), O_BINARY);
|
||||
/* we're writing out ascii */
|
||||
/* setmode(fileno(stdout), O_BINARY); */
|
||||
|
||||
if (f1_skip != f2_skip && f1 == stdin && f2 == stdin) {
|
||||
bu_exit(OPTS_ERROR, "ERROR: cannot skip the same input stream by different amounts\n");
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if (fstat(fileno(f1), &sf1)) {
|
||||
bu_log("Warning - f1 fstat failed: %s\n", strerror(errno));
|
||||
}
|
||||
errno = 0;
|
||||
if (fstat(fileno(f2), &sf2)) {
|
||||
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); */
|
||||
|
||||
if (!quiet && ((sf1.st_size - f1_skip) != (sf2.st_size - f2_skip))) {
|
||||
bu_log("WARNING: Different image sizes detected\n");
|
||||
if (print_bytes) {
|
||||
bu_log("\t%s: %7zu bytes (%8zu bytes, skipping %7zu)\n",
|
||||
argv[0], (size_t)sf1.st_size - f1_skip, (size_t)sf1.st_size, f1_skip);
|
||||
bu_log("\t%s: %7zu bytes (%8zu bytes, skipping %7zu)\n",
|
||||
argv[1], (size_t)sf2.st_size - f2_skip, (size_t)sf2.st_size, f2_skip);
|
||||
} else {
|
||||
bu_log("\t%s: %7zu pixels (%8zu bytes, skipping %7zu)\n",
|
||||
argv[0], ((size_t)sf1.st_size - f1_skip)/3, (size_t)sf1.st_size, f1_skip);
|
||||
bu_log("\t%s: %7zu pixels (%8zu bytes, skipping %7zu)\n",
|
||||
argv[1], ((size_t)sf2.st_size - f2_skip)/3, (size_t)sf2.st_size, f2_skip);
|
||||
}
|
||||
}
|
||||
|
||||
/* make sure we read all bytes */
|
||||
if (stop_after == 0) {
|
||||
stop_after = FMAX((sf1.st_size - f1_skip), (sf2.st_size - f2_skip));
|
||||
if (f1 == stdin && f2 == stdin) {
|
||||
/* dual stdin is interleaved */
|
||||
stop_after = (stop_after+1)/2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
bu_log("mode is [%d] and [%d]\n", S_ISFIFO(sf1.st_mode), S_ISFIFO(sf2.st_mode));
|
||||
bu_log("tty is [%d] and [%d]\n", isatty(fileno(f1)), isatty(fileno(f2)));
|
||||
*/
|
||||
|
||||
/* skip requested pixels/bytes in FILE1 */
|
||||
if (f1_skip) {
|
||||
if (S_ISFIFO(sf1.st_mode)) {
|
||||
size_t skipped = 0;
|
||||
for (skipped = 0; skipped < f1_skip; skipped++) {
|
||||
(void)fgetc(f1);
|
||||
}
|
||||
} else if (fseek(f1, (long)f1_skip, SEEK_SET)) {
|
||||
bu_log("ERROR: Unable to seek %zd %s%s in FILE1\n",
|
||||
f1_skip,
|
||||
print_bytes?"byte":"pixel",
|
||||
f1_skip==1?"":"s");
|
||||
perror("FILE1 fseek failure");
|
||||
exit(FILE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* skip requested pixels in FILE2 */
|
||||
if (f2_skip) {
|
||||
if (S_ISFIFO(sf2.st_mode)) {
|
||||
size_t skipped = 0;
|
||||
for (skipped = 0; skipped < f2_skip; skipped++) {
|
||||
(void)fgetc(f2);
|
||||
}
|
||||
} else if (fseek(f2, (long)f2_skip, SEEK_SET)) {
|
||||
bu_log("ERROR: Unable to seek %zd %s%s in FILE2\n",
|
||||
f2_skip,
|
||||
print_bytes?"byte":"pixel",
|
||||
f2_skip==1?"":"s");
|
||||
perror("FILE2 fseek failure");
|
||||
exit(FILE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* print header to stderr, output to stdout */
|
||||
if (!quiet && (list_same || list_diff)) {
|
||||
if (print_bytes) {
|
||||
bu_log("#Byte FILE1 FILE2 LABEL\n");
|
||||
} else {
|
||||
bu_log("#Pixel\t(FILE1 R, G, B) (FILE2 R, G, B)\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* iterate over the pixels/bytes in the files */
|
||||
while (bytes < stop_after) {
|
||||
enum diff result;
|
||||
int r1 = -1;
|
||||
int r2 = -1;
|
||||
int g1 = -1;
|
||||
int g2 = -1;
|
||||
int b1 = -1;
|
||||
int b2 = -1;
|
||||
|
||||
/* bu_log("\tbytes[%zu] < stop[%zu\n", bytes, stop_after); */
|
||||
|
||||
r1 = fgetc(f1);
|
||||
r2 = fgetc(f2);
|
||||
bytes++;
|
||||
|
||||
if (print_bytes) {
|
||||
/* replicate */
|
||||
b1 = g1 = 0;
|
||||
b2 = g2 = 0;
|
||||
} else {
|
||||
g1 = fgetc(f1);
|
||||
g2 = fgetc(f2);
|
||||
bytes++;
|
||||
b1 = fgetc(f1);
|
||||
b2 = fgetc(f2);
|
||||
bytes++;
|
||||
if( argc != 3 ) {
|
||||
fprintf(stderr, "%s", usage);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
result = compare_rgb(r1, g1, b1, r2, g2, b2, &matching, &off1, &offmany, &missing);
|
||||
|
||||
/* print them? */
|
||||
if ((result==MATCHING && list_same)
|
||||
|| (result!=MATCHING && list_diff))
|
||||
{
|
||||
const char *label = NULL;
|
||||
switch (result) {
|
||||
case MATCHING:
|
||||
label = "MATCHING";
|
||||
break;
|
||||
case OFF_BY_MANY:
|
||||
label = "OFF_BY_MANY";
|
||||
break;
|
||||
case OFF_BY_ONE:
|
||||
label = "OFF_BY_ONE";
|
||||
break;
|
||||
case MISSING:
|
||||
default:
|
||||
label = "MISSING";
|
||||
break;
|
||||
}
|
||||
if (print_bytes) {
|
||||
printf("%zu %3d %3d %s\n", bytes, r1, r2, label);
|
||||
} else {
|
||||
printf("%zu\t(%3d, %3d, %3d)\t(%3d, %3d, %3d) %s\n", bytes / 3, r1, g1, b1, r2, g2, b2, label);
|
||||
}
|
||||
if( strcmp( argv[1], "-" ) == 0 )
|
||||
f1 = stdin;
|
||||
else if( (f1 = fopen( argv[1], "r" ) ) == NULL ) {
|
||||
perror( argv[1] );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* print summary */
|
||||
if (!quiet) {
|
||||
printf("pixcmp %s: %8zd matching, %8zd off by 1, %8zd off by many",
|
||||
print_bytes?"bytes":"pixels", matching, off1, offmany);
|
||||
if (missing) {
|
||||
printf(", %8zd missing\n", missing);
|
||||
} else {
|
||||
printf("\n");
|
||||
if( strcmp( argv[2], "-" ) == 0 )
|
||||
f2 = stdin;
|
||||
else if( (f2 = fopen( argv[2], "r" ) ) == NULL ) {
|
||||
perror( argv[2] );
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
while(1) {
|
||||
register int r1, g1, b1;
|
||||
int r2, g2, b2;
|
||||
|
||||
/* check for errors */
|
||||
if (ferror(f1) || ferror(f2)) {
|
||||
perror("pixcmp file error");
|
||||
return FILE_ERROR;
|
||||
}
|
||||
r1 = fgetc( f1 );
|
||||
g1 = fgetc( f1 );
|
||||
b1 = fgetc( f1 );
|
||||
r2 = fgetc( f2 );
|
||||
g2 = fgetc( f2 );
|
||||
b2 = fgetc( f2 );
|
||||
if( feof(f1) || feof(f2) ) break;
|
||||
|
||||
/* indicate how many differences there were overall */
|
||||
if (offmany || missing) {
|
||||
return EXIT_OFF_BY_MANY;
|
||||
}
|
||||
if (off1) {
|
||||
return EXIT_OFF_BY_ONE;
|
||||
}
|
||||
if( r1 != r2 || g1 != g2 || b1 != b2 ) {
|
||||
register int i;
|
||||
|
||||
/* Success! */
|
||||
return EXIT_OFF_BY_NONE;
|
||||
/* Highlight differing channels */
|
||||
if( r1 != r2 ) {
|
||||
if( (i = r1 - r2) < 0 ) i = -i;
|
||||
if( i > 1 ) {
|
||||
offmany++;
|
||||
} else {
|
||||
off1++;
|
||||
}
|
||||
} else {
|
||||
matching++;
|
||||
}
|
||||
if( g1 != g2 ) {
|
||||
if( (i = g1 - g2) < 0 ) i = -i;
|
||||
if( i > 1 ) {
|
||||
offmany++;
|
||||
} else {
|
||||
off1++;
|
||||
}
|
||||
} else {
|
||||
matching++;
|
||||
}
|
||||
if( b1 != b2 ) {
|
||||
if( (i = b1 - b2) < 0 ) i = -i;
|
||||
if( i > 1 ) {
|
||||
offmany++;
|
||||
} else {
|
||||
off1++;
|
||||
}
|
||||
} else {
|
||||
matching++;
|
||||
}
|
||||
} else {
|
||||
/* Common case: equal. Give B&W NTSC average */
|
||||
matching += 3;
|
||||
}
|
||||
}
|
||||
fprintf(stderr,
|
||||
"pixcmp bytes: %8ld matching, %8ld off by 1, %8ld off by many\n",
|
||||
matching, off1, offmany );
|
||||
|
||||
/* If files were of different lengths, that is an error */
|
||||
if( feof(f1) != feof(f2) )
|
||||
exit(2);
|
||||
|
||||
/* If any pixels were off by more than +/- 1, that is an error */
|
||||
if( offmany)
|
||||
exit(1);
|
||||
|
||||
/* Success! */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: t
|
||||
* c-file-style: "stroustrup"
|
||||
* End:
|
||||
* ex: shiftwidth=4 tabstop=8
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
)
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
export PATH || (echo "This isn't sh."; sh $0 $*; kill $$)
|
||||
eval `machinetype.sh -b` # sets MACHINE, UNIXTYPE, HAS_TCP
|
||||
if test -f ../.rt.$MACHINE/rt
|
||||
then
|
||||
RT=../.rt.$MACHINE/rt
|
||||
DB=../.db.$MACHINE
|
||||
LD_LIBRARY_PATH=../.libbu.$MACHINE:../.libbn.$MACHINE:../.librt.$MACHINE:../.libfb.$MACHINE:../.libpkg.$MACHINE:../.libsysv.$MACHINE:$LD_LIBRARY_PATH
|
||||
else
|
||||
if test ! -f ../rt/rt
|
||||
then
|
||||
echo "Can't find RT"
|
||||
exit 1
|
||||
fi
|
||||
RT=../rt/rt
|
||||
DB=../db
|
||||
LD_LIBRARY_PATH=../libbu:../libbn:../librt:../libfb:../libpkg:../libsysv:$LD_LIBRARY_PATH
|
||||
fi
|
||||
export LD_LIBRARY_PATH
|
||||
|
||||
# Alliant NFS hack
|
||||
if test x${MACHINE} = xfx
|
||||
then
|
||||
cp ${RT} /tmp/rt
|
||||
RT=/tmp/rt
|
||||
fi
|
||||
|
||||
# WARNING THIS IS A REAL CPU HOG
|
||||
if test -f cube.pix; then mv -f cube.pix cube.pix.$$; fi
|
||||
if test -f cube.log; then mv -f cube.log cube.log.$$; fi
|
||||
$RT -p90 -f1024 -H3 -M $*\
|
||||
-o cube.pix\
|
||||
$DB/cube.g\
|
||||
'all.g' \
|
||||
2> cube.log\
|
||||
<<EOF
|
||||
6.847580140e+03
|
||||
3.699276190e+03 3.032924070e+03 3.658674860e+03
|
||||
-5.735762590e-01 8.191521640e-01 0.000000000e+00 0.000000000e+00
|
||||
-3.461885920e-01 -2.424037690e-01 9.063078880e-01 0.000000000e+00
|
||||
7.424040310e-01 5.198366640e-01 4.226181980e-01 0.000000000e+00
|
||||
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00
|
||||
EOF
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#!/bin/sh
|
||||
# A Shell script to re-check the most recent results of the benchmark
|
||||
# @(#)$Header$ (BRL)
|
||||
|
||||
# Ensure /bin/sh
|
||||
export PATH || (echo "This isn't sh."; sh $0 $*; kill $$)
|
||||
|
||||
eval `machinetype.sh -b` # sets MACHINE, UNIXTYPE, HAS_TCP
|
||||
if test -f ../.util.$MACHINE/pixdiff
|
||||
then
|
||||
PIXDIFF=../.util.$MACHINE/pixdiff
|
||||
PIX_FB=../.fb.$MACHINE/pix-fb
|
||||
LD_LIBRARY_PATH=../.libbu.$MACHINE:../.libbn.$MACHINE:../.librt.$MACHINE:../.libfb.$MACHINE:../.libpkg.$MACHINE:../.libsysv.$MACHINE:$LD_LIBRARY_PATH
|
||||
else
|
||||
if test -f ../util/pixdiff
|
||||
then
|
||||
PIXDIFF=../util/pixdiff
|
||||
PIX_FB=../fb/pix-fb
|
||||
else
|
||||
echo "Can't find pixdiff"
|
||||
exit 1
|
||||
fi
|
||||
LD_LIBRARY_PATH=../libbu:../libbn:../librt:../libfb:../libpkg:../libsysv:$LD_LIBRARY_PATH
|
||||
fi
|
||||
export LD_LIBRARY_PATH
|
||||
|
||||
# Alliant NFS hack
|
||||
if test x${MACHINE} = xfx
|
||||
then
|
||||
cp ${PIXDIFF} /tmp/pixdiff
|
||||
cp ${PIX_FB} /tmp/pix-fb
|
||||
PIXDIFF=/tmp/pixdiff
|
||||
PIX_FB=/tmp/pix-fb
|
||||
fi
|
||||
|
||||
echo +++++ moss.pix
|
||||
${PIXDIFF} ../pix/moss.pix moss.pix | ${PIX_FB}
|
||||
|
||||
echo +++++ world.pix
|
||||
${PIXDIFF} ../pix/world.pix world.pix | ${PIX_FB}
|
||||
|
||||
echo +++++ star.pix
|
||||
${PIXDIFF} ../pix/star.pix star.pix | ${PIX_FB}
|
||||
|
||||
echo +++++ bldg391.pix
|
||||
${PIXDIFF} ../pix/bldg391.pix bldg391.pix | ${PIX_FB}
|
||||
|
||||
echo +++++ m35.pix
|
||||
${PIXDIFF} ../pix/m35.pix m35.pix | ${PIX_FB}
|
||||
|
||||
echo +++++ sphflake.pix
|
||||
${PIXDIFF} ../pix/sphflake.pix sphflake.pix | ${PIX_FB}
|
||||
@@ -1,33 +0,0 @@
|
||||
set(
|
||||
BENCHMARK_PIX
|
||||
bldg391.pix
|
||||
m35.pix
|
||||
moss.pix
|
||||
sphflake.pix
|
||||
star.pix
|
||||
world.pix
|
||||
)
|
||||
|
||||
set(
|
||||
PIX_LOG
|
||||
bldg391.log
|
||||
m35.log
|
||||
moss.log
|
||||
sphflake.log
|
||||
star.log
|
||||
world.log
|
||||
)
|
||||
|
||||
brlcad_adddata(BENCHMARK_PIX pix)
|
||||
brlcad_adddata(PIX_LOG pix)
|
||||
|
||||
cmakefiles(${BENCHMARK_PIX})
|
||||
cmakefiles(${PIX_LOG})
|
||||
cmakefiles(CMakeLists.txt)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
-114
@@ -1,114 +0,0 @@
|
||||
/* R U N . C
|
||||
* BRL-CAD
|
||||
*
|
||||
* Copyright (c) 2011-2026 United States Government as represented by
|
||||
* the U.S. Army Research Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/** @file run.c
|
||||
*
|
||||
* run functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bu.h"
|
||||
|
||||
|
||||
/* TODO: !!! obviously */
|
||||
struct bu_vls bu_argv_to_string(int ac, const char *av[]) {struct bu_vls v = BU_VLS_INIT_ZERO; if (ac) {bu_vls_printf(&v, "%s", av[0]);} return v;}
|
||||
int (*echo)(const char *, ...) = &bu_log;
|
||||
extern int bu_exec(const char *program, void *data, struct bu_vls *out, struct bu_vls *err);
|
||||
|
||||
|
||||
/**
|
||||
* run file_prefix geometry hypersample [..rt args..]
|
||||
* runs a single benchmark test assuming the following are preset:
|
||||
*
|
||||
* RT := path/name of the raytracer to use
|
||||
* DB := path to the geometry file
|
||||
*
|
||||
* it is assumed that stdin will be the view/frame input
|
||||
*/
|
||||
int
|
||||
run(int ac, char *av[])
|
||||
{
|
||||
int retval;
|
||||
const char *run_geomname = av[0];
|
||||
const char *run_geometry = av[1];
|
||||
long int hypersample = strtod(av[2], NULL);
|
||||
av += 3;
|
||||
ac -= 3;
|
||||
|
||||
{
|
||||
struct bu_vls args = bu_argv_to_string(ac, (const char **)av);
|
||||
echo("DEBUG: Running %s -B -M -s512 -H%ld -J0 %s -o %s.pix %s/%s.g %s\n", av[0], hypersample, args, run_geomname, run_geomname, run_geometry);
|
||||
bu_vls_free(&args);
|
||||
}
|
||||
|
||||
/* pipe(stdin_for_bu_exec); */
|
||||
retval = bu_exec("program", NULL, NULL, NULL);
|
||||
echo("DEBUG: Running %s returned %d\n", av[0], retval);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* runs a series of benchmark tests assuming the following are preset:
|
||||
*
|
||||
* TIMEFRAME := maximum amount of wallclock time to spend per test
|
||||
*
|
||||
* is is assumed that stdin will be the view/frame input
|
||||
*/
|
||||
int
|
||||
bench(const char *test_name)
|
||||
{
|
||||
if (!test_name)
|
||||
return -1;
|
||||
|
||||
/* FIXME: !!! lots missing here */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* tab-width: 8
|
||||
* mode: C
|
||||
* indent-tabs-mode: t
|
||||
* c-file-style: "stroustrup"
|
||||
* End:
|
||||
* ex: shiftwidth=4 tabstop=8
|
||||
*/
|
||||
+261
-1594
File diff suppressed because it is too large
Load Diff
+123
-64
@@ -1,74 +1,133 @@
|
||||
#!/bin/sh
|
||||
# T R Y . S H
|
||||
# BRL-CAD
|
||||
#
|
||||
# Copyright (c) 2004-2026 United States Government as represented by
|
||||
# the U.S. Army Research Laboratory.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
#
|
||||
# 3. The name of the author may not be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
###
|
||||
# A Shell script to run the BRL-CAD Benchmark, with output going to
|
||||
# a framebuffer rather than to a file.
|
||||
#
|
||||
# Authors -
|
||||
# Mike Muuss
|
||||
# Christopher Sean Morrison
|
||||
#
|
||||
# A Shell script to run the BRL-CAD Benchmark Test,
|
||||
# with output going to the current framebuffer, rather than a file.
|
||||
# @(#)$Header$ (BRL)
|
||||
|
||||
# Ensure /bin/sh
|
||||
export PATH || (echo "This isn't sh."; sh $0 $*; kill $$)
|
||||
path_to_this=`dirname $0`
|
||||
|
||||
# force locale setting to C so things like date output as expected
|
||||
LC_ALL=C
|
||||
eval `machinetype.sh -b` # sets MACHINE, UNIXTYPE, HAS_TCP
|
||||
if test -f ../.rt.$MACHINE/rt
|
||||
then
|
||||
RT=../.rt.$MACHINE/rt
|
||||
DB=../.db.$MACHINE
|
||||
LD_LIBRARY_PATH=../.libbu.$MACHINE:../.libbn.$MACHINE:../.librt.$MACHINE:../.libfb.$MACHINE:../.libpkg.$MACHINE:../.libsysv.$MACHINE:$LD_LIBRARY_PATH
|
||||
else
|
||||
if test ! -f ../rt/rt
|
||||
then
|
||||
echo "Can't find RT"
|
||||
exit 1
|
||||
fi
|
||||
RT=../rt/rt
|
||||
DB=../db
|
||||
LD_LIBRARY_PATH=../libbu:../libbn:../librt:../libfb:../libpkg:../libsysv:$LD_LIBRARY_PATH
|
||||
fi
|
||||
export LD_LIBRARY_PATH
|
||||
|
||||
TIMEFRAME=1 ; export TIMEFRAME
|
||||
MAXTIME=1 ; export MAXTIME
|
||||
|
||||
ARGS="-F/dev/Xl $*"
|
||||
|
||||
if test -f "$path_to_this/run.sh" ; then
|
||||
$path_to_this/run.sh $ARGS
|
||||
elif test -f "$path_to_this/benchmark" ; then
|
||||
$path_to_this/benchmark $ARGS
|
||||
elif test -f "/usr/brlcad/bin/benchmark" ; then
|
||||
/usr/brlcad/bin/benchmark $ARGS
|
||||
CMP=./pixcmp
|
||||
if test ! -f $CMP
|
||||
then
|
||||
cake pixcmp
|
||||
fi
|
||||
|
||||
# Alliant NFS hack
|
||||
if test x${MACHINE} = xfx
|
||||
then
|
||||
cp ${RT} /tmp/rt
|
||||
cp ${CMP} /tmp/pixcmp
|
||||
RT=/tmp/rt
|
||||
CMP=/tmp/pixcmp
|
||||
fi
|
||||
|
||||
# Run the tests
|
||||
|
||||
echo +++++ moss
|
||||
|
||||
time $RT -B -M -s512 $* \
|
||||
$DB/moss.g all.g \
|
||||
<< EOF
|
||||
viewsize 1.572026215e+02;
|
||||
eye_pt 6.379990387e+01 3.271768951e+01 3.366661453e+01;
|
||||
viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00
|
||||
0.000000000e+00 -3.461886346e-01 -2.424038798e-01 9.063078165e-01
|
||||
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 ;
|
||||
start 0;
|
||||
end;
|
||||
EOF
|
||||
|
||||
echo +++++ world
|
||||
|
||||
time $RT -B -M -s512 $* \
|
||||
$DB/world.g all.g \
|
||||
<< EOF
|
||||
viewsize 1.572026215e+02;
|
||||
eye_pt 6.379990387e+01 3.271768951e+01 3.366661453e+01;
|
||||
viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00
|
||||
0.000000000e+00 -3.461886346e-01 -2.424038798e-01 9.063078165e-01
|
||||
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 ;
|
||||
start 0;
|
||||
end;
|
||||
EOF
|
||||
|
||||
echo +++++ star
|
||||
|
||||
time $RT -B -M -s512 $* \
|
||||
$DB/star.g all \
|
||||
<<EOF
|
||||
viewsize 2.500000000e+05;
|
||||
eye_pt 2.102677960e+05 8.455500000e+04 2.934714650e+04;
|
||||
viewrot -6.733560560e-01 6.130643360e-01 4.132114880e-01 0.000000000e+00
|
||||
5.539599410e-01 4.823888300e-02 8.311441420e-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 ;
|
||||
start 0;
|
||||
end;
|
||||
EOF
|
||||
|
||||
echo +++++ bldg391
|
||||
|
||||
time $RT -B -M -s512 $* \
|
||||
$DB/bldg391.g all.g \
|
||||
<<EOF
|
||||
viewsize 1.800000000e+03;
|
||||
eye_pt 6.345012207e+02 8.633251343e+02 8.310771484e+02;
|
||||
viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00
|
||||
0.000000000e+00 -3.461886346e-01 -2.424038798e-01 9.063078165e-01
|
||||
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 ;
|
||||
start 0;
|
||||
end;
|
||||
EOF
|
||||
|
||||
echo +++++ m35
|
||||
|
||||
time $RT -B -M -s512 $* \
|
||||
$DB/m35.g all.g \
|
||||
<< EOF
|
||||
viewsize 6.787387985e+03;
|
||||
eye_pt 3.974533127e+03 1.503320754e+03 2.874633221e+03;
|
||||
viewrot -5.527838919e-01 8.332423558e-01 1.171090926e-02 0.000000000e+00
|
||||
-4.815587087e-01 -3.308784486e-01 8.115544728e-01 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 ;
|
||||
start 0;
|
||||
end;
|
||||
EOF
|
||||
|
||||
echo +++++ sphflake
|
||||
|
||||
time $RT -B -M -s512 $* \
|
||||
$DB/sphflake.g scene.r \
|
||||
<< 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;
|
||||
start 0;
|
||||
end;
|
||||
EOF
|
||||
|
||||
# Local Variables:
|
||||
# mode: sh
|
||||
# tab-width: 8
|
||||
# sh-indentation: 4
|
||||
# sh-basic-offset: 4
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=4 tabstop=8
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
#!/bin/sh
|
||||
# V I E W D I F F . S H
|
||||
# BRL-CAD
|
||||
#
|
||||
# Copyright (c) 2004-2026 United States Government as represented by
|
||||
# the U.S. Army Research Laboratory.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
#
|
||||
# 3. The name of the author may not be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
###
|
||||
# A Shell script to view the differences of a benchmark run,
|
||||
# displaying the results in a framebuffer window.
|
||||
#
|
||||
# The following environment variables will modify how the view diff
|
||||
# behaves (in case you're not running from a source distribution, for
|
||||
# example):
|
||||
#
|
||||
# PIX - the directory containing the pix files to be compare
|
||||
# PIXDIFF - the name of a pix diff tool
|
||||
# PIXFB - the name of a pix to framebuffer tool (e.g. pix-fb)
|
||||
#
|
||||
# Authors -
|
||||
# Mike Muuss
|
||||
# Christopher Sean Morrison
|
||||
#
|
||||
# @(#)$Header$
|
||||
|
||||
# Ensure /bin/sh
|
||||
export PATH || (echo "This isn't sh."; sh $0 $*; kill $$)
|
||||
path_to_this="`dirname $0`"
|
||||
|
||||
echo Looking for benchmark images ...
|
||||
# find pix reference image directory if we do not already know where
|
||||
# it is. PIX environment variable overrides
|
||||
if test "x${PIX}" = "x" ; then
|
||||
if test -f "$path_to_this/../pix/sphflake.pix" ; then
|
||||
echo ...found .pix image files in $path_to_this/../pix
|
||||
PIX="$path_to_this/../pix"
|
||||
elif test -f "$path_to_this/sphflake.pix" ; then
|
||||
echo ...found .pix image files in $path_to_this
|
||||
PIX="$path_to_this"
|
||||
elif test -f "$path_to_this/../share/brlcad/pix/sphflake.pix" ; then
|
||||
echo ...found .pix image files in $path_to_this/../share/brlcad/pix
|
||||
PIX="$path_to_this/../share/brlcad/pix"
|
||||
fi
|
||||
else
|
||||
echo ...using $PIX from PIX environment variable setting
|
||||
fi
|
||||
|
||||
|
||||
echo Checking for pixel diff utility...
|
||||
# find pixel diff utility
|
||||
# PIXDIFF environment variable overrides
|
||||
if test "x${PIXDIFF}" = "x" ; then
|
||||
if test -x $path_to_this/pixdiff ; then
|
||||
echo ...found $path_to_this/pixdiff
|
||||
PIXDIFF="$path_to_this/pixdiff"
|
||||
elif test -x $path_to_this/../src/util/pixdiff ; then
|
||||
echo ...found $path_to_this/../src/util/pixdiff
|
||||
PIXDIFF="$path_to_this/../src/util/pixdiff"
|
||||
else
|
||||
if test -f "$path_to_this/../src/util/pixdiff.c" ; then
|
||||
echo ...need to build pixdiff
|
||||
|
||||
for compiler in $CC gcc cc ; do
|
||||
COMPILE="$compiler"
|
||||
|
||||
if test "x$COMPILE" = "x" ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
$COMPILE -o pixdiff "$path_to_this/../src/util/pixdiff.c"
|
||||
if test "x$?" = "x0" ; then
|
||||
break
|
||||
fi
|
||||
if test -f "pixdiff" ; then
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
if test -f "pixdiff" ; then
|
||||
echo ...built pixdiff with $COMPILE -o pixdiff pixdiff.c
|
||||
PIXDIFF="./pixdiff"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo ...using $PIXDIFF from PIXDIFF environment variable setting
|
||||
fi
|
||||
|
||||
|
||||
echo Checking for pix to framebuffer utility...
|
||||
# find pix to framebuffer utility
|
||||
# PIXFB environment variable overrides
|
||||
if test "x${PIXFB}" = "x" ; then
|
||||
if test -x $path_to_this/pix-fb ; then
|
||||
echo ...found $path_to_this/pix-fb
|
||||
PIXFB="$path_to_this/pix-fb"
|
||||
elif test -x $path_to_this/../src/fb/pix-fb ; then
|
||||
echo ...found $path_to_this/../src/fb/pix-fb
|
||||
PIXFB="$path_to_this/../src/fb/pix-fb"
|
||||
else
|
||||
if test -f "$path_to_this/../src/fb/pix-fb.c" ; then
|
||||
echo ...need to build pix-fb
|
||||
|
||||
for compiler in $CC gcc cc ; do
|
||||
COMPILE="$compiler"
|
||||
|
||||
if test "x$COMPILE" = "x" ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
$COMPILE -o pix-fb "$path_to_this/../src/fb/pix-fb.c"
|
||||
if test "x$?" = "x0" ; then
|
||||
break
|
||||
fi
|
||||
if test -f "pix-fb" ; then
|
||||
break;
|
||||
fi
|
||||
done
|
||||
|
||||
if test -f "pix-fb" ; then
|
||||
echo ...built pix-fb with $COMPILE -o pix-fb pix-fb.c
|
||||
PIXFB="./pix-fb"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo ...using $PIXFB from PIXFB environment variable setting
|
||||
fi
|
||||
|
||||
echo +++++ moss.pix
|
||||
${PIXDIFF} ${PIX}/moss.pix moss.pix | ${PIXFB}
|
||||
|
||||
echo +++++ world.pix
|
||||
${PIXDIFF} ${PIX}/world.pix world.pix | ${PIXFB}
|
||||
|
||||
echo +++++ star.pix
|
||||
${PIXDIFF} ${PIX}/star.pix star.pix | ${PIXFB}
|
||||
|
||||
echo +++++ bldg391.pix
|
||||
${PIXDIFF} ${PIX}/bldg391.pix bldg391.pix | ${PIXFB}
|
||||
|
||||
echo +++++ m35.pix
|
||||
${PIXDIFF} ${PIX}/m35.pix m35.pix | ${PIXFB}
|
||||
|
||||
echo +++++ sphflake.pix
|
||||
${PIXDIFF} ${PIX}/sphflake.pix sphflake.pix | ${PIXFB}
|
||||
|
||||
# Local Variables:
|
||||
# mode: sh
|
||||
# tab-width: 8
|
||||
# sh-indentation: 4
|
||||
# sh-basic-offset: 4
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=4 tabstop=8
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* brlman/Cakefile
|
||||
*
|
||||
* Note: The file "awf" needs to know where ../awf/Cakefile put the
|
||||
* pieces (ETCDIR by default).
|
||||
*/
|
||||
#include "../Cakefile.defs"
|
||||
|
||||
#define PRODUCTS awf brlman
|
||||
#define SRCDIR brlman
|
||||
#define FILES /**/
|
||||
#define SRCSUFF /**/
|
||||
#define MANSECTION 1
|
||||
|
||||
#define STATIC_PRODUCTS PRODUCTS /* Force PRODUCTS into dist */
|
||||
|
||||
/*
|
||||
* There is nothing to compile.
|
||||
* The "install-prod" rule should install PRODUCTS,
|
||||
* and "inst-dist" rule shoudl take care of copying to distribution dir.
|
||||
* Nothing else to do.
|
||||
*/
|
||||
all&:
|
||||
@echo "SRCDIR: all done"
|
||||
|
||||
#include "../Cakefile.rules"
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#! /bin/sh
|
||||
eval `machinetype.sh -v` # BRL mod: sets $BASEDIR
|
||||
PATH=/bin:/usr/bin ; export PATH
|
||||
# AWFLIB is where the pieces live
|
||||
AWFLIB=${AWFLIB-$BASEDIR/etc} # BRL mod
|
||||
|
||||
tmp=/tmp/awp$$ # tempfile for building pass 2
|
||||
errs=/tmp/awe$$ # error messages (awk can't send to stderr)
|
||||
|
||||
case "$1" in
|
||||
-ms) mac=ms ;;
|
||||
-man) mac=man ;;
|
||||
*) echo "$0: must specify -ms or -man" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
|
||||
dev="$AWFLIB/dev.$TERM"
|
||||
if test ! -r $dev
|
||||
then
|
||||
dev="$AWFLIB/dev.dumb"
|
||||
fi
|
||||
|
||||
trap "rm -f $tmp $errs ; exit 0" 0 1 2
|
||||
|
||||
# build the full, macro-set-dependent, pass-2 awk program
|
||||
(
|
||||
sed -n '1,/^#include/p' $AWFLIB/pass2.base
|
||||
cat $AWFLIB/pass2.$mac
|
||||
sed -n '/^#include/,$p' $AWFLIB/pass2.base
|
||||
) >$tmp
|
||||
|
||||
# do it
|
||||
(
|
||||
echo ".^x $errs"
|
||||
echo ".^b"
|
||||
echo ".^# 1 <prolog>"
|
||||
cat $dev $AWFLIB/common $AWFLIB/mac.$mac
|
||||
if test " $*" = " "
|
||||
then
|
||||
echo ".^# 1 <stdin>"
|
||||
cat
|
||||
else
|
||||
for f
|
||||
do
|
||||
echo ".^# 1 $f"
|
||||
cat $f
|
||||
done
|
||||
fi
|
||||
echo ".^e"
|
||||
) | awk -f $AWFLIB/pass1 | awk -f $tmp | awk -f $AWFLIB/pass3
|
||||
|
||||
# error messages, if any
|
||||
if test -s $errs
|
||||
then
|
||||
cat $errs >&2
|
||||
exit 1
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
# B R L M A N
|
||||
#
|
||||
# A substitute for the "man" command for those systems that do not
|
||||
# have NROFF. Henry Spencer's "nroff -man" replacement called AWF
|
||||
# is used instead.
|
||||
#
|
||||
# Michael John Muuss, BRL, 23-June-1991.
|
||||
# Public Domain, Distribution Unlimited
|
||||
#
|
||||
# @(#) $Header$ (BRL)
|
||||
|
||||
if test $# -lt 1
|
||||
then
|
||||
echo "Usage: $0 command"
|
||||
echo " To obtain help about that command"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use MANPAGER, else use PAGER, else use "more" command.
|
||||
MORE="more -s -f"
|
||||
if test "$PAGER" != ""
|
||||
then
|
||||
MORE="${PAGER}"
|
||||
fi
|
||||
if test "${MANPAGER}" != ""
|
||||
then
|
||||
MORE="${MANPAGER}"
|
||||
fi
|
||||
|
||||
eval `machinetype.sh -v` # sets $BASEDIR
|
||||
|
||||
# Ensure that MANPATH is set and has BRL-CAD materials listed first.
|
||||
MANPATH=${BASEDIR}/man:${MANPATH}
|
||||
|
||||
PATH_ELEMENTS=`echo ${MANPATH} | sed 's/^://
|
||||
s/:://g
|
||||
s/:$//
|
||||
s/:\\.:/:/g
|
||||
s/:/ /g'`
|
||||
|
||||
for PLACE in ${PATH_ELEMENTS}
|
||||
do
|
||||
PATTERN="${PLACE}/man?/$1.?"
|
||||
TRY=`eval echo ${PATTERN}`
|
||||
if test "${TRY}" != "${PATTERN}"
|
||||
then
|
||||
# Found something(s), format it/them
|
||||
echo ${TRY}
|
||||
awf -man ${TRY} | ${MORE}
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,43 @@
|
||||
.TH BRLMAN 1 BRL/CAD
|
||||
.SH NAME
|
||||
brlman \- display manual pages for BRL-CAD software
|
||||
.SH SYNOPSIS
|
||||
.B brlman
|
||||
title
|
||||
.SH DESCRIPTION
|
||||
.I Brlman
|
||||
provides a substitute for the
|
||||
.I man
|
||||
command for those systems that do not
|
||||
have
|
||||
.I nroff.
|
||||
Henry Spencer's
|
||||
.I nroff -man
|
||||
replacement called
|
||||
.I awf
|
||||
is used instead.
|
||||
.I Brlman
|
||||
uses the environment variable
|
||||
.I MANPATH
|
||||
to determine where to search for the manual pages (
|
||||
.I /usr/brlcad/man
|
||||
is the default). The pager used is taken from the environment variable
|
||||
.I MANPAGER
|
||||
or, if that is nor set
|
||||
.I PAGER
|
||||
is used. The default is to use the
|
||||
.I more -s -f
|
||||
command.
|
||||
.SH "SEE ALSO"
|
||||
awf(1)
|
||||
.SH AUTHOR
|
||||
Michael John Muuss
|
||||
.SH SOURCE
|
||||
SECAD/VLD Computing Consortium, Bldg 394
|
||||
.br
|
||||
The U. S. Army Ballistic Research Laboratory
|
||||
.br
|
||||
Aberdeen Proving Ground, Maryland 21005
|
||||
.SH "BUG REPORTS"
|
||||
Reports of bugs or problems should be submitted via electronic
|
||||
mail to <CAD@ARL.ARMY.MIL>.
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* btclsh/Cakefile
|
||||
*
|
||||
*/
|
||||
#define CONFIGDEFS BTCLSH_CONFIG
|
||||
|
||||
#define SRCDIR bwish
|
||||
#define PRODUCTS btclsh
|
||||
#if 0
|
||||
#define STATIC_PRODUCTS btclsh.tcl
|
||||
#endif
|
||||
#define SRCSUFF .c
|
||||
#define MANSECTION 1
|
||||
|
||||
#define FILES main input tcl cmd
|
||||
|
||||
#include "../Cakefile.defs"
|
||||
#include "../Cakefile.prog"
|
||||
|
||||
#if HAS_TCP
|
||||
# define COMPLETE_LIBES \
|
||||
LIBPKG LIBWDB LIBRT LIBBN LIBBU LIBBU_LIBES LIBTERMIO BTCLSH_LIBES LIBES
|
||||
#else
|
||||
# define COMPLETE_LIBES \
|
||||
LIBWDB LIBRT LIBBN LIBBU LIBBU_LIBES LIBTERMIO BTCLSH_LIBES LIBES
|
||||
#endif
|
||||
|
||||
btclsh: OBJ LIBRT_DEP LIBBN_DEP LIBBU_DEP LIBWDB_DEP LIBTCL_DEP
|
||||
sh ../sh/newvers.sh version "BrlCad Tclsh (BTCLSH)"
|
||||
CC CFLAGS -c vers.c
|
||||
CC -o btclsh LDFLAGS OBJ COMPLETE_LIBES vers.o
|
||||
|
||||
#include "../Cakefile.rules"
|
||||
@@ -0,0 +1,4 @@
|
||||
char version[] = "\
|
||||
@(#) BRL-CAD Release 6.0 BrlCad Tclsh (BTCLSH)\n\
|
||||
Mon Apr 1 14:01:17 CST 2002, Compilation 1\n\
|
||||
root@Mustang:/disk1/brlcad6.0/btclsh\n";
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
burst/Cakefile
|
||||
|
||||
Author: Gary S. Moss
|
||||
U. S. Army Ballistic Research Laboratory
|
||||
Aberdeen Proving Ground
|
||||
Maryland 21005-5066
|
||||
|
||||
$Header$ (BRL)
|
||||
|
||||
*/
|
||||
#define CONFIGDEFS LGT_CONFIG -I. -U_POSIX_SOURCE /*-DDEBUG*/
|
||||
#define SRCDIR burst
|
||||
#define PRODUCTS burst
|
||||
#define SRCSUFF .c
|
||||
#define MANSECTION 1
|
||||
#define FILES burst error fb glob grid gridrotate idents paint plot prnt trie ui Hm HmGetc HmGlob Sc
|
||||
#include "../Cakefile.defs"
|
||||
#include "../Cakefile.prog"
|
||||
|
||||
PRODUCTS: OBJ LIBRT_DEP LIBBN_DEP LIBFB_DEP LIBBU_DEP LIBTERMIO_DEP
|
||||
CC LDFLAGS -o burst OBJ LIBRT LIBBN LIBBU LIBBU_LIBES LIBTERMIO LIBTERMLIB LIBFB LIBFB_LIBES LIBES -lm
|
||||
|
||||
all&: PRODUCTS
|
||||
|
||||
test&: ../.burst.MTYPE/burst tfiles/ktank.g
|
||||
../.burst.MTYPE/burst -b < tfiles/ktank.in
|
||||
@if test $? -ne 0
|
||||
then echo "Test failed." ; exit 1
|
||||
fi
|
||||
diff tfiles/ktank.burst tfiles/ktank.burst.bak4.0
|
||||
@if test $? -ne 0
|
||||
then echo "Test failed." ; exit 1
|
||||
fi
|
||||
diff tfiles/ktank.shotlines tfiles/ktank.shotlines.bak4.0
|
||||
@if test $? -ne 0
|
||||
then echo "Test failed." ; exit 1
|
||||
fi
|
||||
@echo "Tested OK."
|
||||
|
||||
untest&:
|
||||
rm -f tfiles/ktank.burst tfiles.ktank.shotlines tfiles/ktank.plot tfiles/ktank.pix tfiles/ktank.g tfiles/ktank.log
|
||||
|
||||
tfiles/ktank.g:
|
||||
asc2g < ../burst/tfiles/ktank.asc > tfiles/ktank.g
|
||||
|
||||
#include "../Cakefile.rules"
|
||||
+1336
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user