Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc130e1e7a | ||
|
|
de83ba5d30 | ||
|
|
31470287a1 | ||
|
|
dc3b4abaa1 | ||
|
|
3f1eb8f584 | ||
|
|
561b3c3aab | ||
|
|
d03b9838a1 | ||
|
|
48cd318a6d | ||
|
|
1f0193dbaf | ||
|
|
2e7e827ba0 | ||
|
|
342d8a9152 | ||
|
|
9e030edd60 | ||
|
|
b5bf1683a2 | ||
|
|
eb7e9cb38c | ||
|
|
84be85a74d | ||
|
|
3fd9ec8f4b | ||
|
|
7d2392d754 | ||
|
|
e7c61497df | ||
|
|
08da151a6e | ||
|
|
757bb76203 | ||
|
|
c70bab52c4 | ||
|
|
7929a747ad | ||
|
|
eac0f4d265 | ||
|
|
d6ae424de0 | ||
|
|
27ba3c4880 | ||
|
|
7ade8db130 | ||
|
|
e91023f354 | ||
|
|
303b90f7f1 | ||
|
|
875091f78a | ||
|
|
0716e4c842 | ||
|
|
ee6e1bebdc | ||
|
|
9d4f5bb124 | ||
|
|
21f442a4ad | ||
|
|
24d6f6f4cb | ||
|
|
d3e037a760 | ||
|
|
5a38423677 | ||
|
|
38113b1de7 | ||
|
|
fec9d07d43 | ||
|
|
4b09d6227f | ||
|
|
eab1e82de2 |
@@ -384,7 +384,7 @@ jobs:
|
||||
osx:
|
||||
name: macOS Clang
|
||||
needs: [linux]
|
||||
runs-on: macos-14
|
||||
runs-on: macos-15
|
||||
strategy:
|
||||
fail-fast: true
|
||||
steps:
|
||||
@@ -403,7 +403,7 @@ jobs:
|
||||
- name: Prepare bext dependencies
|
||||
uses: ./brlcad/.github/actions/prepare-bext
|
||||
with:
|
||||
platform-channel: macos-14-${{ runner.arch }}-release
|
||||
platform-channel: macos-15-${{ runner.arch }}-release
|
||||
source-dir: ${{ github.workspace }}/brlcad
|
||||
output-dir: ${{ runner.temp }}/bext_output
|
||||
build-type: Release
|
||||
|
||||
@@ -177,7 +177,7 @@ jobs:
|
||||
osx_bext:
|
||||
name: macOS - BRL-CAD bext build
|
||||
needs: [linux_bext]
|
||||
runs-on: macos-14
|
||||
runs-on: macos-15
|
||||
strategy:
|
||||
fail-fast: true
|
||||
if: ${{ !cancelled() }}
|
||||
|
||||
@@ -231,7 +231,7 @@ set(CMAKE_FIND_USE_PACKAGE_REGISTRY FALSE)
|
||||
# Prepare to manage and build BRL-CAD's external dependencies. Specifies a
|
||||
# specific commit hash to use in the 'bext' repository.
|
||||
include(BRLCAD_ExternalDeps)
|
||||
brlcad_bext_init(0682795bcfe34644c17e5a4bdd0225c76f6bdc98)
|
||||
brlcad_bext_init(42d8d7ca57f9d2f61192b41f0b41a731f1ba6c47)
|
||||
|
||||
#---------------------------------------------------------------------
|
||||
# Define various utilities.
|
||||
@@ -352,9 +352,10 @@ set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||
# it should only be set to the installation value when actually installed.
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||
|
||||
# Add the automatically determined parts of the RPATH which point to
|
||||
# directories outside the build tree to the install RPATH
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
# Installed runtime paths are defined explicitly below. Do not append
|
||||
# directories discovered on the build host, since those paths may not exist
|
||||
# or may resolve to unrelated libraries on the installed system.
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
|
||||
|
||||
# The following logic is what allows binaries to run successfully in the build
|
||||
# directory AND install directory.
|
||||
|
||||
@@ -151,10 +151,13 @@ 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)
|
||||
* Acquire bext and its dependencies from another repository host
|
||||
|
||||
git clone --recurse-submodules https://github.com/BRL-CAD/brlcad
|
||||
cmake .. -DBRLCAD_REPOSITORY_ROOT=https://git.example.org/brlcad
|
||||
|
||||
* Acquire bext and its dependencies from local bare Git mirrors
|
||||
|
||||
cmake .. "-DBRLCAD_REPOSITORY_ROOT=/path/to/mirror/BRL-CAD"
|
||||
|
||||
* Have prebuilt bext outputs to reuse - BRL-CAD will simply copy and prepare
|
||||
the pre-existing files
|
||||
@@ -398,10 +401,40 @@ Aliases: ENABLE_RUNTIME_DEBUG, ENABLE_RUN_TIME_DEBUG, ENABLE_RUNTIME_DEBUGGING
|
||||
ENABLE_RUN_TIME_DEBUGGING
|
||||
|
||||
|
||||
--- BRLCAD_REPOSITORY_ROOT ---
|
||||
|
||||
Repository URL or local directory containing bext and its dependency
|
||||
repositories. Defaults to https://github.com/BRL-CAD. The root directly
|
||||
contains repositories such as bext.git and astyle.git; BRL-CAD does not
|
||||
append BRL-CAD to the root.
|
||||
|
||||
Remote Git URLs (including SSH), native paths, and file:// URLs are supported.
|
||||
Relative native paths are resolved against the BRL-CAD source directory.
|
||||
Quote the entire -D argument for paths containing spaces. The setting is
|
||||
cached and is also passed as BEXT_REPOSITORY_ROOT when BRL-CAD configures
|
||||
bext, including when BRLCAD_EXT_SOURCE_DIR supplies an existing checkout.
|
||||
Alternate roots require bext sources with BEXT_REPOSITORY_ROOT support.
|
||||
|
||||
Local roots restrict CMake-driven Git acquisition and queries to file
|
||||
transport, with no online fallback. Mirrors must contain all required pinned
|
||||
commits and recursive submodules. Dependencies outside bext's canonical URL
|
||||
prefix require their own Git URL mappings. This setting does not restrict
|
||||
network access by dependency build scripts or change persistent Git settings.
|
||||
BRLCAD_EXT_DIR still selects prebuilt outputs, and changing the repository
|
||||
root alone does not force those outputs to be rebuilt.
|
||||
|
||||
To return to the default source:
|
||||
|
||||
cmake .. -DBRLCAD_REPOSITORY_ROOT=https://github.com/BRL-CAD
|
||||
|
||||
|
||||
--- BRLCAD_EXT_DIR ---
|
||||
|
||||
If specified, BRL-CAD will look in this directory for bext compiled outputs to
|
||||
bundle and use during the build.
|
||||
bundle and use during the build. Relative paths are resolved against the
|
||||
BRL-CAD source directory. Distcheck subconfigures reuse this resolved output
|
||||
directory and preserve BRLCAD_REPOSITORY_ROOT, BRLCAD_EXT_SOURCE_DIR, and
|
||||
BRLCAD_EXT_PARALLEL when specified.
|
||||
|
||||
|
||||
--- BRLCAD_EXT_SOURCE_DIR ---
|
||||
@@ -409,7 +442,8 @@ bundle and use during the build.
|
||||
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.
|
||||
configure process manage producing bext build outputs. Relative paths are
|
||||
resolved against the BRL-CAD source directory.
|
||||
|
||||
|
||||
--- BRLCAD_EXT_PARALLEL ---
|
||||
|
||||
@@ -10,82 +10,113 @@ descriptive text that emphasizes or further describes significant
|
||||
changes made. See document footer for additional details.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
--- 20XX-XX-XX Release 7.46.0 ---
|
||||
--- 202X-XX-XX Release 7.48.0 ---
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
--- 2026-10-12 Release 7.46.0 ---
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This release expands geometry conversion and improves modeling
|
||||
reliability. STEP support adds AP203e2, AP214, and AP242
|
||||
import/export, native CSG round trips, and AP242 product and
|
||||
manufacturing information (PMI) import. IGES and JT conversion is
|
||||
expanded, and new OpenSCAD CSG import/export tools are available.
|
||||
|
||||
Facetization is more reliable, NMG solid ray tracing is 10-20 times
|
||||
faster, CSG ray tracing is faster, and BoT, DSP, and point-cloud ray
|
||||
intersections are corrected. MGED gains numerous fixes to primitive,
|
||||
sketch, and combination editing, drawing, dialogs, and preferences.
|
||||
|
||||
New tools support object nesting with arrange, building generation
|
||||
with mkbuilding, annotation editing, and primitive repair. Geometry
|
||||
analysis, image utilities, Windows support, documentation, and bundled
|
||||
dependencies also receive substantial updates.
|
||||
|
||||
* corrected Archer logic for saving window size - Cliff Yapp
|
||||
* fixed inside BoT rays, DSP surface normals, PNTS bounds - Cliff Yapp
|
||||
* improved mged fallback HTML manual viewer - Cliff Yapp
|
||||
* fixed gqa undefined densities and exit status - Chris McGregor
|
||||
* added ARBN support to the mged inside command - Cliff Yapp
|
||||
* improved HYP neck-ratio labels and BoT face selection - Cliff Yapp
|
||||
* fixed mged view panning, edit rotation, & ray queries - Cliff Yapp
|
||||
* preserved ARB, CLINE, TGC, & extrusion geometry edits - Cliff Yapp
|
||||
* restored mged command prompt focus at GUI startup - Cliff Yapp
|
||||
* new documentation on geometry representation schemes - Sean Morrison
|
||||
* improved pixscale & bwscale scaling and image piping - Sean Morrison
|
||||
* restored pixdiff behavior on .pix, added -b for .bw - Sean Morrison
|
||||
* updated MGED and Archer for Tcl 8.6.18 and Itcl/Itk 4 - Cliff Yapp
|
||||
* improved facetize fallback methods and reliability - Cliff Yapp
|
||||
* updated mged and Archer for Tcl 8.6.18 and Itcl/Itk 4 - Cliff Yapp
|
||||
* fixed writes to fileless geometry databases - Cliff Yapp
|
||||
* fixed nastran-g handling of large property IDs - Rupesh, Cliff Yapp
|
||||
* fixed dxf-g invalid polyface index crashes - Meghna45-code, Cliff Yapp
|
||||
* fixed Archer primitive editors under Itcl 4 - Cliff Yapp
|
||||
* fixed Archer shutdown menu cleanup errors - Cliff Yapp
|
||||
* fixed MGED Build Pattern dialog under Itcl 4 - Cliff Yapp
|
||||
* fixed dxf-g invalid polyface idx crash - Meghna45-code, Cliff Yapp
|
||||
* fixed TclCAD framebuffer listing and deletion - Cliff Yapp
|
||||
* fixed MGED Build Pattern progress updates - Cliff Yapp
|
||||
* fixed MGED search -exec reentry and Ctrl-C crashes - Cliff Yapp
|
||||
* fixed MGED asynchronous commands and clone progress - Cliff Yapp
|
||||
* accelerated large and repeated MGED path drawing - Cliff Yapp
|
||||
* fixed mged Build Pattern progress updates - Cliff Yapp
|
||||
* fixed mged search -exec reentry and Ctrl-C crashes - Cliff Yapp
|
||||
* fixed mged asynchronous commands and clone progress - Cliff Yapp
|
||||
* accelerated large and repeated mged path drawing - Cliff Yapp
|
||||
* fixed ARB7 inside solid construction - Cliff Yapp
|
||||
* fixed direct ARB face and edge-direction editing - Cliff Yapp
|
||||
* fixed rtwizard startup with framebuffer contention - Cliff Yapp
|
||||
* fixed Archer annotation line display updates - Cliff Yapp
|
||||
* fixed Archer sketch scale drift in non-mm databases - Cliff Yapp
|
||||
* fixed toggle arrow callbacks during setup - Cliff Yapp
|
||||
* fixed Tcl dialogs with multi-word titles and messages - Cliff Yapp
|
||||
* fixed Tcl dialogs with multi-word titles and msgs - Cliff Yapp
|
||||
* fixed Archer Tank Wizard gun generation - Cliff Yapp
|
||||
* fixed MGED and Archer sketch arc tangency editing - Cliff Yapp
|
||||
* fixed mged and Archer sketch arc tangency editing - Cliff Yapp
|
||||
* fixed Archer ARB4 point 3 editing - Cliff Yapp
|
||||
* fixed ARB4 storage from make and mk_arb4 - Cliff Yapp
|
||||
* fixed ARB4 and ARB6 center point calculations - Cliff Yapp
|
||||
* fixed concurrent MGED and rtwizard framebuffer use - Cliff Yapp
|
||||
* fixed MGED ShotVis editing and reload failures - Cliff Yapp
|
||||
* fixed concurrent mged and rtwizard framebuffer use - Cliff Yapp
|
||||
* fixed mged ShotVis editing and reload failures - Cliff Yapp
|
||||
* fixed Tcl widget geometry and selection defects - Cliff Yapp
|
||||
* fixed MGED BoT editor property handling - Cliff Yapp
|
||||
* fixed MGED LOD dialog and adaptive BoT wireframes - Cliff Yapp
|
||||
* fixed MGED Plot, PostScript, and manual launch tools - Cliff Yapp
|
||||
* fixed MGED Overlap Tool multi-object result handling - Cliff Yapp
|
||||
* fixed mged BoT editor property handling - Cliff Yapp
|
||||
* fixed mged LOD dialog and adaptive BoT wireframes - Cliff Yapp
|
||||
* fixed mged Plot, PostScript, and manual launch tools - Cliff Yapp
|
||||
* fixed mged Overlap Tool multi-object result handling - Cliff Yapp
|
||||
* eliminated 16-fold redundant gchecker grid analysis - Cliff Yapp
|
||||
* fixed Archer tree handling for object names with spaces - Cliff Yapp
|
||||
* fixed submodel transforms & relative database paths - Sean Morrison
|
||||
* fixed Archer tree handling for names with spaces - Cliff Yapp
|
||||
* fixed RtWizard multi-object edge occlusion handling - Cliff Yapp
|
||||
* fixed RtWizard title, About, and preference handling - Cliff Yapp
|
||||
* fixed MGED startup file false legacy-syntax warnings - Cliff Yapp
|
||||
* fixed MGED saved-view deletion and collaboration sync - Cliff Yapp
|
||||
* fixed MGED font preferences apply and persistence - Cliff Yapp
|
||||
* fixed mged startup file false legacy-syntax warnings - Cliff Yapp
|
||||
* fixed mged saved-view deletion and collaboration sync - Cliff Yapp
|
||||
* fixed mged font preferences apply and persistence - Cliff Yapp
|
||||
* fixed Archer combination edits changing Boolean trees - Cliff Yapp
|
||||
* fixed Archer command-line help startup crash - Cliff Yapp
|
||||
* fixed MGED Geometry Browser menu and close behavior - Cliff Yapp
|
||||
* fixed MGED collaboration view unshare crash - Cliff Yapp
|
||||
* added an override for Archer's preference file location - Cliff Yapp
|
||||
* fixed mged Geometry Browser menu and close behavior - Cliff Yapp
|
||||
* fixed mged collaboration view unshare crash - Cliff Yapp
|
||||
* added override for Archer's preference file location - Cliff Yapp
|
||||
* fixed embedded Archer display and mode menus - Cliff Yapp
|
||||
* added Archer -h and --help command-line options - Cliff Yapp
|
||||
* fixed Archer Help opening the documentation menu - Sean Morrison
|
||||
* improved fallback methodologies for facetize pipeline - Cliff Yapp
|
||||
* improved facetize pipeline robustness - Cliff Yapp
|
||||
* added arrange nest command for packing database objects - Sean Morrison
|
||||
* new mkbuilding tool for parametric/OSM/CityJSON models - Sean Morrison
|
||||
* added arrange nest command for packing db objects - Sean Morrison
|
||||
* added mkbuilding for parametric/OSM/CityJSON models - Sean Morrison
|
||||
* cross-platform BINUNIF and DSP byte-order handling - Sean Morrison
|
||||
* improved several cv default behaviors (s, 32, 64, n) - Sean Morrison
|
||||
* improved several cv default behaviors (s,32,64,n) - Sean Morrison
|
||||
* fixed invalid bot handling bug applying matrices - Sean Morrison
|
||||
* improved glTF import robustness via gcv - Sean Morrison
|
||||
* fixed bot dump glTF/GLB export; -F is now rejected - Cliff Yapp
|
||||
* faster NMG solid ray tracing (10-20x faster) - Sean Morrison
|
||||
* preserved primitive colors in shaded BoT and B-Rep drawing - Cliff Yapp
|
||||
* preserved B-Rep attributes through in-place geometry edits - Cliff Yapp
|
||||
* fixed gcv filter arguments containing one-character values - Cliff Yapp
|
||||
* preserved prim colors in shaded BoT and B-Rep drawing - Cliff Yapp
|
||||
* preserved B-Rep attrs through in-place geometry edits - Cliff Yapp
|
||||
* fixed gcv filter arguments w/ one-character values - Cliff Yapp
|
||||
* improved iges-g importer robustness - Cliff Yapp
|
||||
* expanded g-iges native CSG and B-Rep export support - Cliff Yapp
|
||||
* added IGES import and export support to gcv - Cliff Yapp
|
||||
* rt -b query option now supports a single value index - Sean Morrison
|
||||
* rt -b query option now supports a single value idx - Sean Morrison
|
||||
* fixed .dpix file format portability and icv support - Sean Morrison
|
||||
* expanded pixscale support for piped image data - Sean Morrison
|
||||
* fixed HYP volume and ARBN totals reported by analyze - Cliff Yapp
|
||||
* corrected rtarea sampling and exposed-area calculations - Cliff Yapp
|
||||
* fixed VOL data-file lookup and missing-data errors - Chris McGregor
|
||||
* corrected rtarea sampling/exposed-area calculations - Cliff Yapp
|
||||
* bot split now groups results and preserves mesh data - Cliff Yapp
|
||||
* bot decimate now preserves normals, UVs, and plate data - Cliff Yapp
|
||||
* bot decimate now preserves nrmls, UVs, and plate data - Cliff Yapp
|
||||
* added raytracing support for annotation objects - Cliff Yapp
|
||||
* fixed MGED X embedded framebuffer display manager crash - Cliff Yapp
|
||||
* fixed Windows subprocess quoting and empty arguments - Cliff Yapp
|
||||
* fixed mged X embedded framebuffer display manager crash - Cliff Yapp
|
||||
* fixed Windows drive-letter path handling - Cliff Yapp
|
||||
* added annotate command for managing annotation objects - Cliff Yapp
|
||||
* added repair command for supported invalid primitives - Cliff Yapp
|
||||
* changed default new-region material code from 1 to 0 - Keith Bowman
|
||||
@@ -107,26 +138,34 @@ changes made. See document footer for additional details.
|
||||
* added option validation to image & framebuffer tools - Sean Morrison
|
||||
* added contributor, API, command, & raytracing guides - Sean Morrison
|
||||
* added and updated command and library manual pages - Sean Morrison
|
||||
* added pnts write -f xyz export option - Chris McGregor
|
||||
* fixed mged ARB5 point editing - Cliff Yapp
|
||||
* fixed mged gqa and rtcheck stale overlap plots - Cliff Yapp
|
||||
* fixed procedural tree generator crashes - Sean Morrison, Cliff Yapp
|
||||
* added gaia Earth models with day/dusk/night textures - Sean Morrison
|
||||
* fixed fbcolor ramps & Windows input - Cliff Yapp, Sean Morrison
|
||||
* added parashot gravity trajectory path generator - Sean Morrison
|
||||
* added metaball point scaling (via metaball_move_pnt) - Sean Morrison
|
||||
* added metaball pnt scaling (via metaball_move_pnt) - Sean Morrison
|
||||
* all raytracing apps now report object prep failures - Sean Morrison
|
||||
* improved fast4-g robustness and error reporting - Cliff Yapp
|
||||
* improved robustness of g-vrml plate mode handling - Cliff Yapp
|
||||
* fixed MGED ARB5 point, pipe, and sketch editing - Cliff Yapp
|
||||
* added pnts write -f xyz export option - Chris McGregor
|
||||
* added support for tick drawing on MGED model axis - Cliff Yapp
|
||||
* added support for tick drawing on mged model axis - Cliff Yapp
|
||||
* added naca456 left and paired wing generation - Cliff Yapp
|
||||
* added patch-g -j option, specify object thicknesses - Sean Morrison
|
||||
* fixed fbcolor color ramp bug drawing the last color - Sean Morrison
|
||||
* corrected bwstat median and input error handling - Sean Morrison
|
||||
* fixed gist -Q quick preview option - Sean Morrison
|
||||
* rt preserves eye_pt setting in command scripts - Sean Morrison
|
||||
* removed trailing whitespace from nirt output - Sean Morrison
|
||||
* rt -l8 heat graphs now measure CPU time - Sean Morrison
|
||||
* documented gqa centroid & moments of inertia options - Sean Morrison
|
||||
* pixdiff now calculates pixel differences on bw files - Sean Morrison
|
||||
* fixed bwcrop single-axis crops and pixembed edge fill - Sean Morrison
|
||||
* fixed bwcrop single-axis crops & pixembed edge fill - Sean Morrison
|
||||
* fixed isize in non-mm databases - Josh Baker
|
||||
* fixed metaball adjust clearing points on errors - Sean Morrison
|
||||
* fixed benchmark+pixcmp correctness validation bug - Sean Morrison
|
||||
* fixed mged gqa option and value parsing - Sean Morrison
|
||||
* improved gist hierarchy overflow rendering - Chris McGregor
|
||||
* fixed rtxray -o grayscale/BW output - Sean Morrison
|
||||
* fbhelp writes help to stdout and rest to stderr - Sean Morrison
|
||||
* FB now supports /dev/stdout and /dev/stderr devices - Sean Morrison
|
||||
* fixed mged rt -C + -o background color to file bug - Sean Morrison
|
||||
@@ -135,7 +174,7 @@ changes made. See document footer for additional details.
|
||||
* added rtsil -o support for bw output - Sean Morrison
|
||||
* added cutting plane animation generation to rtwizard - Cliff Yapp
|
||||
* fixed pixdiff bug on Windows - Sean Morrison
|
||||
* fixed MGED startup window placement on Windows - Chris McGregor
|
||||
* fixed mged startup window placement on Windows - Chris McGregor
|
||||
* fixed pixborder utility right-side edge bug - Sean Morrison
|
||||
* fixed 'wavelet' image processing tool on Windows - Sean Morrison
|
||||
* quieted mged killtree spurious lookup failure output - Sean Morrison
|
||||
@@ -146,14 +185,16 @@ changes made. See document footer for additional details.
|
||||
* new doc guide, a visual overview of BRL-CAD objects - Sean Morrison
|
||||
* improved triangle quality produced by bot remesh - Cliff Yapp
|
||||
* updated numerous manpage command references - Josh Baker
|
||||
* fixed submodel paths relative to parent databases - Sean Morrison
|
||||
* improved performance making huge combinations - Sean Morrison
|
||||
* added PNTS get, adjust, form, & g2asc/asc2g support - Chris McGregor
|
||||
* fixed ANNOT get, adjust, & g2asc/asc2g support - Chris McGregor
|
||||
* added make -t primitive type listing - Chris McGregor
|
||||
* added gcv import conversion support for vrml/wrl 1.0 - Sean Morrison
|
||||
* fixed gcv appending to existing geometry databases - Sean Morrison
|
||||
* added CSS names, hex, HSL/HSV to libbu color parsing - Sean Morrison
|
||||
* improved OpenNURBS B-Rep import and adjustment safety - Cliff Yapp
|
||||
* improved Debian application menus and MIME associations - Jordi Sayol
|
||||
* improved Debian application menus/MIME associations - Jordi Sayol
|
||||
* updated Tcl/Tk dependency to v8.6.18 using bundled Itcl - Cliff Yapp
|
||||
* updated Clipper2 dependency to v1.5.4 - Cliff Yapp
|
||||
* updated Eigen dependency to v5.0.1 - Cliff Yapp
|
||||
* updated GDAL dependency to v3.13.3 - Cliff Yapp
|
||||
@@ -165,7 +206,6 @@ changes made. See document footer for additional details.
|
||||
* updated OpenNURBS dependency to v8.34.26223.11001 - Cliff Yapp
|
||||
* updated PROJ dependency to v9.8.1 - Cliff Yapp
|
||||
* updated PoissonRecon dependency to v18.75 - Cliff Yapp
|
||||
* updated Tcl/Tk dependency to v8.6.18, using bundled Itcl - Cliff Yapp
|
||||
* updated libjpeg-turbo dependency to v3.2.0 - Cliff Yapp
|
||||
* updated libosmesa dependency to SHA1 bfa90de - Cliff Yapp
|
||||
* updated libpng dependency to v1.6.58 - Cliff Yapp
|
||||
@@ -274,7 +314,7 @@ and extensively improving existing docs.
|
||||
* added metadata-aware image diff & nirt analysis - Cliff Yapp
|
||||
* added basic PNTS point-cloud ray tracing - Sean Morrison
|
||||
* improved nirt behavior in Windows bash consoles - Cliff Yapp
|
||||
* added g2asc/asc2g support for PNTS, DSP, and EBM - Sean Morrison
|
||||
* added g2asc/asc2g support for DSP and EBM - Sean Morrison
|
||||
* updated gct mesh decimation dependency to mmesh - Cliff Yapp
|
||||
* added procedural wing, propeller & tree generators - Cliff Yapp
|
||||
* added ISO tire dimensions & named tread presets - Cliff Yapp
|
||||
@@ -546,6 +586,7 @@ for more information.
|
||||
----------------------------------------------------------------------
|
||||
--- 2023-11-06 Release 7.38.0 ---
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This major release of BRL-CAD introduces significant improvements to
|
||||
the robustness of the facetize command by leveraging the Manifold
|
||||
library for boolean evaluation of meshes. Facetization is an operation
|
||||
@@ -584,6 +625,7 @@ processing high level assemblies in BRL-CAD's example geometry files:
|
||||
----------------------------------------------------------------------
|
||||
--- 2023-07-26 Release 7.36.0 ---
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This major release of BRL-CAD introduces significant updates to
|
||||
geometry conversion support. The update includes modernization for
|
||||
NURBS importing and interaction, BoT manipulation, and incorporates
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
BRL-CAD
|
||||
Release 7.44.2
|
||||
Release 7.46.0
|
||||
http://brlcad.org/
|
||||
|
||||
BRL-CAD is a powerful cross-platform open source combinatorial
|
||||
|
||||
@@ -2668,15 +2668,6 @@ DOCUMENTATION
|
||||
Comparison of how BRL-CAD overlaps feature-wise with various
|
||||
major commercial CAD systems.
|
||||
|
||||
* Solid Geometry Representation Comparisons
|
||||
Describe the implications, tradeoffs, and conversion issues
|
||||
involved when converting between different geometry
|
||||
representations. Includes describing implicit geometry,
|
||||
explicit polygonal boundary representations, explicit spline
|
||||
surface representations, volumetric models, wireframes,
|
||||
boolean operations, feature edit operations, and parametric
|
||||
modeling.
|
||||
|
||||
* BRL-CAD Open Source
|
||||
An overview of how BRL-CAD is organized as an open source
|
||||
project and community describing the developer meritocracy,
|
||||
|
||||
@@ -20,6 +20,7 @@ set(
|
||||
procedural_geometry.adoc
|
||||
projection_shader.adoc
|
||||
renderer_showcase.adoc
|
||||
solid_geometry_comparison.adoc
|
||||
taxonomy.adoc
|
||||
tire.adoc
|
||||
)
|
||||
@@ -227,6 +228,17 @@ set(
|
||||
images/renderer_gallery_rthide.png
|
||||
images/renderer_gallery_rtdepth.png
|
||||
images/renderer_gallery_rtxray.png
|
||||
images/solid_rep_csg.png
|
||||
images/solid_rep_brep_boolean.png
|
||||
images/solid_rep_brep_evaluated.png
|
||||
images/solid_rep_polygonal_boolean.png
|
||||
images/solid_rep_nmg.png
|
||||
images/solid_rep_bot.png
|
||||
images/solid_rep_revolve.png
|
||||
images/solid_rep_voxel_cells.png
|
||||
images/solid_rep_volume.png
|
||||
images/solid_rep_point_cloud.png
|
||||
images/solid_rep_wireframe.png
|
||||
images/adrt_castle_path.png
|
||||
images/adrt_castle_rt.png
|
||||
images/adrt_castle_rt_ao.png
|
||||
@@ -409,6 +421,54 @@ if(
|
||||
set_target_properties(renderer-gallery-snapshot PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1)
|
||||
endif()
|
||||
|
||||
# Solid geometry comparison -- opt-in regeneration of committed snapshots.
|
||||
#
|
||||
# The article and solid_rep_*.png images are normal committed documentation.
|
||||
# This target rebuilds the common pawn, derives each representation with the
|
||||
# built tools, and refreshes the images for review.
|
||||
option(
|
||||
BRLCAD_GENERATE_SOLID_REPRESENTATION_COMPARISON
|
||||
"Regenerate the solid geometry representation comparison snapshots"
|
||||
OFF
|
||||
)
|
||||
if(
|
||||
BRLCAD_GENERATE_SOLID_REPRESENTATION_COMPARISON
|
||||
AND TARGET mged
|
||||
AND TARGET rt
|
||||
AND TARGET g-voxel
|
||||
AND TARGET asc2pix
|
||||
AND TARGET fbclear
|
||||
AND TARGET plot3-fb
|
||||
AND TARGET fb-png
|
||||
)
|
||||
add_custom_target(
|
||||
solid-representation-comparison-snapshot
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
-DMGED=$<TARGET_FILE:mged>
|
||||
-DRT=$<TARGET_FILE:rt>
|
||||
-DGVOXEL=$<TARGET_FILE:g-voxel>
|
||||
-DASC2PIX=$<TARGET_FILE:asc2pix>
|
||||
-DFBCLEAR=$<TARGET_FILE:fbclear>
|
||||
-DPLOT3FB=$<TARGET_FILE:plot3-fb>
|
||||
-DFBPNG=$<TARGET_FILE:fb-png>
|
||||
-DMODEL_SCRIPT=${CMAKE_CURRENT_SOURCE_DIR}/solid_geometry_comparison/create_pawn.tcl
|
||||
-DIMGDIR=${CMAKE_CURRENT_SOURCE_DIR}/images
|
||||
-DWORKDIR=${CMAKE_CURRENT_BINARY_DIR}/solid_representation_comparison_work
|
||||
-DSIZE=512
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/solid_geometry_comparison/generate_comparison.cmake
|
||||
DEPENDS mged rt g-voxel asc2pix fbclear plot3-fb fb-png
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Regenerating solid geometry representation comparison snapshots"
|
||||
VERBATIM
|
||||
USES_TERMINAL
|
||||
)
|
||||
set_target_properties(
|
||||
solid-representation-comparison-snapshot
|
||||
PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1
|
||||
)
|
||||
endif()
|
||||
|
||||
# ADRT path-tracing gallery -- opt-in regeneration of the committed snapshot.
|
||||
#
|
||||
# Like the galleries above, the adrt_pathtrace.adoc article is hand-written and
|
||||
@@ -464,6 +524,8 @@ cmakefiles(
|
||||
gallery/generate_gallery.cmake
|
||||
renderer_gallery/renderer_gallery_manifest.cmake
|
||||
renderer_gallery/generate_renderer_gallery.cmake
|
||||
solid_geometry_comparison/create_pawn.tcl
|
||||
solid_geometry_comparison/generate_comparison.cmake
|
||||
adrt_gallery/generate_adrt_gallery.cmake
|
||||
gallery/inputs/pipe.stdin
|
||||
gallery/inputs/wire.stdin
|
||||
|
||||
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
@@ -0,0 +1,294 @@
|
||||
= Solid Geometry Representation Comparisons
|
||||
:doctype: article
|
||||
:toc:
|
||||
:toclevels: 2
|
||||
|
||||
The same shape can be stored in very different ways. This comparison uses a
|
||||
purpose-built chess pawn to show which information BRL-CAD retains, evaluates,
|
||||
or samples when moving among its principal geometry representations. It is a
|
||||
guide to semantics and conversion choices, not a claim that one representation
|
||||
is universally best.
|
||||
|
||||
== Common model and method
|
||||
|
||||
The reference pawn is a region containing seven overlapping ellipsoids. Their
|
||||
union is non-trivial enough to exercise curved surfaces, overlapping interiors,
|
||||
and several component boundaries while remaining reliable across the
|
||||
conversions shown here. The sketch-and-revolve version independently follows
|
||||
the same nominal profile; it is not an exact conversion of the seven-piece CSG
|
||||
model.
|
||||
|
||||
Every shaded image uses the same orthographic view, 512x512 image size,
|
||||
material, and single-threaded renderer. The wireframe uses the same view and
|
||||
image size. The faceting and sampling settings are intentionally coarse enough
|
||||
to remain visible. A similar silhouette therefore does not mean that two
|
||||
database objects have the same structure or numerical boundary.
|
||||
|
||||
NOTE: This article and its images are a committed snapshot. Developers can
|
||||
regenerate the figures from built BRL-CAD tools by configuring with
|
||||
`-DBRLCAD_GENERATE_SOLID_REPRESENTATION_COMPARISON=ON` and building the
|
||||
`solid-representation-comparison-snapshot` target.
|
||||
|
||||
== At a glance
|
||||
|
||||
[cols="2,2,1,2,4",options="header"]
|
||||
|===
|
||||
|Form
|
||||
|BRL-CAD storage
|
||||
|Solid?
|
||||
|Boolean state
|
||||
|Editing and conversion consequences
|
||||
|
||||
|Analytic CSG
|
||||
|Seven `ell` leaves in a combination
|
||||
|Yes
|
||||
|Retained
|
||||
|Compact primitive parameters and tree edits preserve construction intent.
|
||||
|
||||
|B-rep tree
|
||||
|Closed `brep` leaves in a combination
|
||||
|Yes
|
||||
|Retained
|
||||
|NURBS surfaces and trims replace analytic leaves, but the assembly tree remains.
|
||||
|
||||
|Evaluated B-rep
|
||||
|One closed `brep`
|
||||
|Yes
|
||||
|Evaluated
|
||||
|Direct face, edge, trim, and control-point editing is possible; original
|
||||
features and hierarchy are gone.
|
||||
|
||||
|Polygonal tree
|
||||
|Solid-mode `bot` leaves in a combination
|
||||
|Yes
|
||||
|Retained
|
||||
|Leaf tessellation is approximate, but components and their union tree remain
|
||||
independently replaceable.
|
||||
|
||||
|Evaluated NMG
|
||||
|One `nmg`
|
||||
|Yes
|
||||
|Evaluated
|
||||
|Stores explicit, topology-rich polygonal boundaries and can record
|
||||
non-manifold relationships.
|
||||
|
||||
|Evaluated triangle mesh
|
||||
|One solid-mode `bot`
|
||||
|Yes
|
||||
|Evaluated
|
||||
|Portable triangle connectivity, but curved geometry and construction history
|
||||
have been sampled away.
|
||||
|
||||
|Sketch and revolve
|
||||
|One `sketch` referenced by one `revolve`
|
||||
|Yes
|
||||
|Not needed here
|
||||
|The profile, axis, and sweep angle are compact, meaningful parameters.
|
||||
|
||||
|Voxel cells
|
||||
|A region containing many `arb8` boxes
|
||||
|Yes (sampled)
|
||||
|Cell union retained
|
||||
|Individual cells are ordinary CSG geometry; size grows rapidly as cells
|
||||
shrink.
|
||||
|
||||
|Sampled volume
|
||||
|A file-backed `vol` scalar grid
|
||||
|Yes (thresholded)
|
||||
|None
|
||||
|Compact regular-grid occupancy; resolution and threshold determine the boundary.
|
||||
|
||||
|Point cloud
|
||||
|One `pnts` object with positions and normals
|
||||
|No pawn interior
|
||||
|None
|
||||
|Useful as measured or sampled evidence, but it has no inherent connected
|
||||
boundary or inside/outside rule.
|
||||
|
||||
|Wireframe
|
||||
|Derived line display of the CSG object
|
||||
|No
|
||||
|Uses source tree
|
||||
|A view-dependent drawing aid, not an independent solid representation.
|
||||
|===
|
||||
|
||||
"Solid" in this table means that the stored object supplies usable
|
||||
inside/outside semantics for the pawn. An arbitrary B-rep or mesh is not
|
||||
automatically a solid: its boundary must be closed and consistently oriented.
|
||||
The point size used to render `pnts` makes each sample a small sphere, but those
|
||||
spheres do not reconstruct the pawn interior. A wireframe likewise does not
|
||||
become a solid merely because its curves appear closed in one view.
|
||||
|
||||
== Implicit and parametric forms
|
||||
|
||||
[cols="1,1"]
|
||||
[%noheader]
|
||||
|===
|
||||
|image:images/solid_rep_csg.png[Analytic CSG pawn,512]
|
||||
|image:images/solid_rep_revolve.png[Sketch and revolve pawn,512]
|
||||
|
||||
|*Analytic CSG.* Native primitives retain their equations and dimensions; the
|
||||
region evaluates their union during ray tracing.
|
||||
|*Sketch plus revolve.* A closed line-segment profile is swept through 360
|
||||
degrees. The stepped profile is intentional and remains editable in two
|
||||
dimensions.
|
||||
|===
|
||||
|
||||
Analytic CSG is an implicit representation: intersections with ideal primitive
|
||||
surfaces are computed as needed rather than read from a stored boundary mesh.
|
||||
It is usually the most compact form here and makes edits such as changing the
|
||||
head radius or stem proportions direct. Its Boolean hierarchy also records why the
|
||||
shape was assembled.
|
||||
|
||||
`sketch` plus `revolve` is another procedural, parameterized description. It
|
||||
works especially well for an axisymmetric part, although a sketch with only
|
||||
line segments produces conical and cylindrical bands rather than the pawn's
|
||||
original ellipsoidal surfaces. BRL-CAD supports primitive parameters, placement
|
||||
matrices, sketches, and sweeps; that should not be confused with a general
|
||||
constraint solver or an associative feature-history system.
|
||||
|
||||
== Spline boundary representations
|
||||
|
||||
[cols="1,1"]
|
||||
[%noheader]
|
||||
|===
|
||||
|image:images/solid_rep_brep_boolean.png[B-rep leaves with Boolean tree,512]
|
||||
|image:images/solid_rep_brep_evaluated.png[Single evaluated B-rep,512]
|
||||
|
||||
|*B-rep with Booleans.* Each analytic leaf becomes a closed B-rep whose
|
||||
boundaries are trimmed NURBS surfaces. The original union tree is retained.
|
||||
|*B-rep without Booleans.* Boolean evaluation produces one explicit boundary;
|
||||
operand identities and the construction tree no longer exist as editable
|
||||
features.
|
||||
|===
|
||||
|
||||
A B-rep stores faces, trims, edges, vertices, and their topology explicitly.
|
||||
Rational NURBS can represent the source quadrics exactly as surfaces, but that
|
||||
does not make every CSG-to-B-rep conversion exact: intersections, trimming,
|
||||
topology classification, and repair use numerical tolerances. Keeping a tree
|
||||
of B-rep leaves isolates conversion to each primitive and retains high-level
|
||||
editing. Evaluating the tree yields a more self-contained boundary for
|
||||
exchange and face-level work, at the cost of that history. This snapshot's
|
||||
evaluated result passes both `brep ... valid` and `brep ... solid`; conversion
|
||||
results should be checked rather than assumed to be closed.
|
||||
|
||||
== Polygonal boundaries
|
||||
|
||||
[cols="1,1,1"]
|
||||
[%noheader]
|
||||
|===
|
||||
|image:images/solid_rep_polygonal_boolean.png[BoT leaves with Boolean tree,512]
|
||||
|image:images/solid_rep_nmg.png[Evaluated NMG pawn,512]
|
||||
|image:images/solid_rep_bot.png[Evaluated BoT pawn,512]
|
||||
|
||||
|*Polygonal with Booleans.* Each leaf is independently tessellated to a BoT,
|
||||
then placed in the original union tree.
|
||||
|*Evaluated NMG.* One non-manifold geometry object records the evaluated
|
||||
polygonal boundary and its richer topology.
|
||||
|*Evaluated triangle mesh.* One solid, counter-clockwise BoT stores 982
|
||||
vertices and 1,960 triangular faces in this snapshot.
|
||||
|===
|
||||
|
||||
All three images expose the same coarse tessellation. Their similar appearance
|
||||
hides an important distinction: the first still has seven editable operands,
|
||||
whereas the NMG and single BoT are evaluated results. NMG can represent
|
||||
polygonal faces and non-manifold adjacency; BoT faces are triangles only.
|
||||
Neither recreates analytic curvature when converted back. Finer tessellation
|
||||
reduces visible error but increases storage and processing cost.
|
||||
|
||||
== Sampled forms
|
||||
|
||||
[cols="1,1,1"]
|
||||
[%noheader]
|
||||
|===
|
||||
|image:images/solid_rep_voxel_cells.png[Pawn represented by CSG voxel cells,512]
|
||||
|image:images/solid_rep_volume.png[Pawn represented by a VOL grid,512]
|
||||
|image:images/solid_rep_point_cloud.png[Pawn represented by surface points,512]
|
||||
|
||||
|*Explicit voxel cells.* `voxelize` tests 3 mm cells and creates a CSG union of
|
||||
699 boxes for cells exceeding the occupancy threshold.
|
||||
|*Sampled volume.* `g-voxel` samples a 2 mm grid; a file-backed `vol` interprets
|
||||
the resulting 17x17x30 byte array through an occupancy window.
|
||||
|*Point cloud.* `pnts gen` samples the analytic surface on a 2 mm grid. Small
|
||||
rendered spheres make the otherwise zero-area sample locations visible.
|
||||
|===
|
||||
|
||||
The two voxel images are deliberately separate. The `voxelize` command emits
|
||||
ordinary box primitives and a combination, while `vol` reads scalar samples on
|
||||
a regular grid and derives a threshold boundary at ray-trace time. Both are
|
||||
volumetric approximations whose accuracy, memory, and feature size depend on
|
||||
cell spacing. A point cloud samples only the surface and has no connectivity;
|
||||
surface reconstruction requires additional assumptions and may invent or omit
|
||||
geometry.
|
||||
|
||||
== Wireframe display
|
||||
|
||||
image::images/solid_rep_wireframe.png[Wireframe display of the analytic CSG pawn,512]
|
||||
|
||||
This wireframe is a view-plane plot of MGED's unevaluated display of the
|
||||
analytic CSG pawn; hidden lines are not removed. Wireframes are useful for
|
||||
selection, orientation, and seeing component curves, but they are ambiguous:
|
||||
curves alone do not say which side is material, which loops bound faces, or
|
||||
which surfaces enclose volume. Keep the solid that generated the display
|
||||
rather than treating the drawing as an equivalent conversion target.
|
||||
|
||||
== Conversion and editing consequences
|
||||
|
||||
A conversion command is not an equivalence guarantee. Before replacing source
|
||||
data, check at least these effects:
|
||||
|
||||
* *Tolerance and resolution:* B-rep Boolean evaluation uses intersection and
|
||||
topology tolerances; tessellation uses chord and angular tolerances; voxels
|
||||
and points use sample spacing and thresholds. Each can erase a feature
|
||||
smaller than its controlling tolerance.
|
||||
* *Construction intent:* evaluating a Boolean tree discards operand identity,
|
||||
primitive parameters, and ordering. Converting leaves while retaining the
|
||||
tree keeps more of that intent.
|
||||
* *Topology:* a visually plausible B-rep or mesh may contain gaps, duplicate
|
||||
faces, self-intersections, or inconsistent orientation. Validate closure
|
||||
and ray behavior, not only a shaded image.
|
||||
* *Attributes:* collapsing a hierarchy may change where region identifiers,
|
||||
materials, colors, and other attributes reside. Verify them separately
|
||||
from geometry.
|
||||
* *Round trips:* CSG to mesh to B-rep does not recover the original equations;
|
||||
points to a surface requires reconstruction; resampling a volume compounds
|
||||
discretization. Retain the highest-level trustworthy source.
|
||||
|
||||
For parameter changes and repeated design work, prefer analytic primitives,
|
||||
sketch sweeps, and preserved combination trees. Prefer a validated B-rep when
|
||||
trimmed-surface topology or exchange requires it. Use NMG for topology-rich
|
||||
polygonal processing and BoT for triangle-oriented interchange or algorithms.
|
||||
Use voxels for occupancy operations and point clouds for measured or sampled
|
||||
data, not as silent substitutes for a watertight solid.
|
||||
|
||||
BRL-CAD also supports specialized forms such as DSP height fields, EBM
|
||||
extrusions, ARS surfaces, metaballs, and legacy `poly` and `bspline` objects.
|
||||
They are not shown as interchangeable pawn encodings: DSP and EBM are
|
||||
domain-specific, metaballs change the modeling method, and BoT and B-rep are the
|
||||
preferred general successors to the legacy polygon and spline forms.
|
||||
|
||||
== Reproducing the conversions
|
||||
|
||||
The snapshot generator creates the database and runs these principal MGED
|
||||
operations (names shortened here only where noted):
|
||||
|
||||
[source]
|
||||
----
|
||||
brep comparison.csg.r brep --no-evaluation
|
||||
brep comparison.csg.r brep comparison.brep_evaluated.s
|
||||
facetize -n comparison.csg.r comparison.nmg.s
|
||||
facetize --methods NMG comparison.csg.r comparison.bot.s
|
||||
facetize --methods NMG base.s base.bot # repeated for all seven leaves
|
||||
voxelize -s "3 3 3" -d 4 -t 0.45 comparison.voxel_cells.r comparison.csg.r
|
||||
pnts gen -t 2 --surface --grid comparison.csg.r comparison.samples
|
||||
pnts write comparison.samples comparison.xyz
|
||||
pnts read -f xyzijk --size 0.45 comparison.xyz comparison.point_cloud.s
|
||||
----
|
||||
|
||||
The generator also runs `g-voxel` and expands its sparse occupied-cell report
|
||||
into the x-fastest byte array used by `vol`. It then renders every shaded
|
||||
object with `rt -B -M -P1` and the saved view; MGED's `plot -2d`, `plot3-fb`,
|
||||
and `fb-png` produce the wireframe image. See
|
||||
`solid_geometry_comparison/generate_comparison.cmake` and
|
||||
`solid_geometry_comparison/create_pawn.tcl` for the complete reproducible
|
||||
inputs.
|
||||
@@ -0,0 +1,24 @@
|
||||
# Create the shared pawn used by the solid-representation comparison.
|
||||
|
||||
title {Solid geometry representation comparison pawn}
|
||||
units mm
|
||||
|
||||
# Deliberate overlaps keep the pawn connected while exercising curved-surface
|
||||
# intersections during Boolean evaluation.
|
||||
db put base.s ell V {0 0 4.5} A {17 0 0} B {0 17 0} C {0 0 4.5}
|
||||
db put base_bead.s ell V {0 0 9.5} A {14 0 0} B {0 14 0} C {0 0 5}
|
||||
db put body.s ell V {0 0 18} A {12 0 0} B {0 12 0} C {0 0 9}
|
||||
db put stem.s ell V {0 0 29} A {7 0 0} B {0 7 0} C {0 0 13}
|
||||
db put collar.s ell V {0 0 39} A {9 0 0} B {0 9 0} C {0 0 3.5}
|
||||
db put neck.s ell V {0 0 43} A {6.5 0 0} B {0 6.5 0} C {0 0 5}
|
||||
db put head.s ell V {0 0 50} A {9 0 0} B {0 9 0} C {0 0 9}
|
||||
|
||||
db put comparison.csg.r comb region yes id 1000 los 100 GIFTmater 1 rgb {235 190 90} shader {plastic} tree {u {u {u {l base.s} {l base_bead.s}} {u {l body.s} {l stem.s}}} {u {u {l collar.s} {l neck.s}} {l head.s}}}
|
||||
|
||||
# The revolve uses a deliberately independent outline. Its single closed
|
||||
# sketch approximates the same pawn silhouette without copying the CSG tree.
|
||||
db put comparison.profile sketch V {0 0 0} A {1 0 0} B {0 0 1} VL {{0 0} {17 0} {17 2} {16.3 4} {15 6} {14 8} {15.4 7} {16 9} {15.4 11} {13.5 12.5} {11.2 14} {12 18} {11 21} {9.5 23} {8 26} {7.5 32} {6.5 36} {7.5 37} {9 39} {7.5 41} {6.5 42} {6.5 43} {7.5 44} {8.5 46} {9 50} {8.5 54} {6.7 56.5} {0 59}} SL {{line S 0 E 1} {line S 1 E 2} {line S 2 E 3} {line S 3 E 4} {line S 4 E 5} {line S 5 E 6} {line S 6 E 7} {line S 7 E 8} {line S 8 E 9} {line S 9 E 10} {line S 10 E 11} {line S 11 E 12} {line S 12 E 13} {line S 13 E 14} {line S 14 E 15} {line S 15 E 16} {line S 16 E 17} {line S 17 E 18} {line S 18 E 19} {line S 19 E 20} {line S 20 E 21} {line S 21 E 22} {line S 22 E 23} {line S 23 E 24} {line S 24 E 25} {line S 25 E 26} {line S 26 E 27} {line S 27 E 0}}
|
||||
db put comparison.revolve.s revolve V {0 0 0} axis {0 0 1} R {1 0 0} ang 6.283185307179586 sk_name comparison.profile
|
||||
db put comparison.revolve.r comb region yes id 1001 los 100 GIFTmater 1 rgb {235 190 90} shader {plastic} tree {l comparison.revolve.s}
|
||||
|
||||
q
|
||||
@@ -0,0 +1,372 @@
|
||||
# Regenerate the solid geometry representation comparison snapshots.
|
||||
#
|
||||
# The article is hand-written. This script builds its common pawn model,
|
||||
# derives each representation using BRL-CAD tools, and replaces the committed
|
||||
# images. All databases and sidecar data remain in WORKDIR.
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
foreach(v MGED RT GVOXEL ASC2PIX FBCLEAR PLOT3FB FBPNG
|
||||
MODEL_SCRIPT IMGDIR WORKDIR)
|
||||
if(NOT DEFINED ${v})
|
||||
message(FATAL_ERROR "generate_comparison: -D${v}=... is required")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT DEFINED SIZE)
|
||||
set(SIZE 512)
|
||||
endif()
|
||||
|
||||
set(RENDER_TIMEOUT 1800)
|
||||
set(PAWN_DB "${WORKDIR}/solid_representation_pawn.g")
|
||||
set(VIEW_SCRIPT "${WORKDIR}/pawn.view")
|
||||
set(MGED_SCRIPT "${WORKDIR}/assemble_variants.tcl")
|
||||
set(VOXELIZE_SCRIPT "${WORKDIR}/voxelize.tcl")
|
||||
set(VOXEL_LIST "${WORKDIR}/voxels1.txt")
|
||||
set(VOLUME_ASCII "${WORKDIR}/comparison_volume.asc")
|
||||
set(VOLUME_FILE "${WORKDIR}/comparison.vol")
|
||||
|
||||
file(REMOVE_RECURSE "${WORKDIR}")
|
||||
file(MAKE_DIRECTORY "${WORKDIR}")
|
||||
file(MAKE_DIRECTORY "${IMGDIR}")
|
||||
|
||||
function(run_process label)
|
||||
execute_process(
|
||||
COMMAND ${ARGN}
|
||||
WORKING_DIRECTORY "${WORKDIR}"
|
||||
TIMEOUT ${RENDER_TIMEOUT}
|
||||
RESULT_VARIABLE process_result
|
||||
OUTPUT_VARIABLE process_stdout
|
||||
ERROR_VARIABLE process_stderr
|
||||
)
|
||||
if(NOT process_result EQUAL 0)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"${label} failed (exit ${process_result})\n${process_stdout}${process_stderr}"
|
||||
)
|
||||
endif()
|
||||
message(STATUS "${label}")
|
||||
endfunction()
|
||||
|
||||
function(require_brep_property object property expected_output)
|
||||
execute_process(
|
||||
COMMAND "${MGED}" --no-rc -c "${PAWN_DB}" brep "${object}" "${property}"
|
||||
WORKING_DIRECTORY "${WORKDIR}"
|
||||
TIMEOUT ${RENDER_TIMEOUT}
|
||||
RESULT_VARIABLE property_result
|
||||
OUTPUT_VARIABLE property_stdout
|
||||
ERROR_VARIABLE property_stderr
|
||||
)
|
||||
set(property_output "${property_stdout}${property_stderr}")
|
||||
if(NOT property_result EQUAL 0 OR NOT property_output MATCHES "${expected_output}")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"B-rep ${object} is not ${property}\n${property_output}"
|
||||
)
|
||||
endif()
|
||||
message(STATUS "Validated B-rep ${object}: ${property}")
|
||||
endfunction()
|
||||
|
||||
execute_process(
|
||||
COMMAND "${MGED}" --no-rc -c "${PAWN_DB}"
|
||||
WORKING_DIRECTORY "${WORKDIR}"
|
||||
TIMEOUT ${RENDER_TIMEOUT}
|
||||
INPUT_FILE "${MODEL_SCRIPT}"
|
||||
RESULT_VARIABLE create_result
|
||||
OUTPUT_VARIABLE create_stdout
|
||||
ERROR_VARIABLE create_stderr
|
||||
)
|
||||
if(NOT create_result EQUAL 0 OR NOT EXISTS "${PAWN_DB}")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Creating the comparison pawn failed (exit ${create_result})\n${create_stdout}${create_stderr}"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Preserve one Boolean hierarchy as B-rep leaves, and evaluate another into a
|
||||
# single B-rep. The default suffix is intentional: supplying an explicit
|
||||
# suffix changes parsing in older MGED versions.
|
||||
set(PAWN_LEAVES base base_bead body stem collar neck head)
|
||||
run_process(
|
||||
"Created Boolean tree of B-rep leaves"
|
||||
"${MGED}" --no-rc -c "${PAWN_DB}" brep comparison.csg.r brep --no-evaluation
|
||||
)
|
||||
foreach(leaf IN LISTS PAWN_LEAVES)
|
||||
require_brep_property("${leaf}.s.brep" solid "brep is solid")
|
||||
endforeach()
|
||||
run_process(
|
||||
"Created evaluated B-rep"
|
||||
"${MGED}" --no-rc -c "${PAWN_DB}" brep comparison.csg.r brep comparison.brep_evaluated.s
|
||||
)
|
||||
require_brep_property(comparison.brep_evaluated.s valid "brep is valid")
|
||||
require_brep_property(comparison.brep_evaluated.s solid "brep is solid")
|
||||
|
||||
# Generate both the topology-rich NMG form and the triangle-only BoT form.
|
||||
run_process(
|
||||
"Created evaluated NMG"
|
||||
"${MGED}" --no-rc -c "${PAWN_DB}" facetize -n comparison.csg.r comparison.nmg.s
|
||||
)
|
||||
run_process(
|
||||
"Created evaluated BoT"
|
||||
"${MGED}" --no-rc -c "${PAWN_DB}" facetize --methods NMG comparison.csg.r comparison.bot.s
|
||||
)
|
||||
|
||||
# Tessellating leaves independently preserves the editable Boolean hierarchy.
|
||||
foreach(leaf IN LISTS PAWN_LEAVES)
|
||||
run_process(
|
||||
"Tessellated ${leaf}.s"
|
||||
"${MGED}" --no-rc -c "${PAWN_DB}" facetize --methods NMG "${leaf}.s" "${leaf}.bot"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
file(WRITE "${VOXELIZE_SCRIPT}" "voxelize -s {3 3 3} -d 4 -t 0.45 comparison.voxel_cells.r comparison.csg.r\nq\n")
|
||||
execute_process(
|
||||
COMMAND "${MGED}" --no-rc -c "${PAWN_DB}"
|
||||
WORKING_DIRECTORY "${WORKDIR}"
|
||||
TIMEOUT ${RENDER_TIMEOUT}
|
||||
INPUT_FILE "${VOXELIZE_SCRIPT}"
|
||||
RESULT_VARIABLE voxelize_result
|
||||
OUTPUT_VARIABLE voxelize_stdout
|
||||
ERROR_VARIABLE voxelize_stderr
|
||||
)
|
||||
if(NOT voxelize_result EQUAL 0)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Creating explicit voxel cells failed (exit ${voxelize_result})\n${voxelize_stdout}${voxelize_stderr}"
|
||||
)
|
||||
endif()
|
||||
message(STATUS "Created explicit voxel cells")
|
||||
|
||||
# PNTS stores point size at import time. The generator first writes all
|
||||
# sampled fields (xyzijk), then reads them back with a visible point diameter.
|
||||
run_process(
|
||||
"Sampled pawn surface"
|
||||
"${MGED}" --no-rc -c "${PAWN_DB}" pnts gen -t 2 --surface --grid
|
||||
comparison.csg.r comparison.samples
|
||||
)
|
||||
run_process(
|
||||
"Exported pawn point samples"
|
||||
"${MGED}" --no-rc -c "${PAWN_DB}" pnts write comparison.samples comparison.xyz
|
||||
)
|
||||
run_process(
|
||||
"Created visible point cloud"
|
||||
"${MGED}" --no-rc -c "${PAWN_DB}" pnts read -f xyzijk --size 0.45
|
||||
comparison.xyz comparison.point_cloud.s
|
||||
)
|
||||
|
||||
# g-voxel reports occupied cells. Expand that sparse report into the regular,
|
||||
# x-fastest byte array required by VOL. The pawn bounds are [-17,17] in X/Y
|
||||
# and [0,60] in Z; 2 mm cells therefore form a 17 x 17 x 30 grid.
|
||||
file(REMOVE "${VOXEL_LIST}")
|
||||
run_process(
|
||||
"Sampled VOL grid"
|
||||
"${GVOXEL}" -s "2 2 2" -d 4 -t 0.5 "${PAWN_DB}" comparison.csg.r
|
||||
)
|
||||
if(NOT EXISTS "${VOXEL_LIST}")
|
||||
message(FATAL_ERROR "g-voxel did not create ${VOXEL_LIST}")
|
||||
endif()
|
||||
|
||||
file(STRINGS "${VOXEL_LIST}" voxel_lines)
|
||||
list(LENGTH voxel_lines occupied_voxels)
|
||||
if(occupied_voxels EQUAL 0)
|
||||
message(FATAL_ERROR "g-voxel reported no occupied cells")
|
||||
endif()
|
||||
|
||||
foreach(line IN LISTS voxel_lines)
|
||||
string(
|
||||
REGEX MATCH
|
||||
"^\\((-?[0-9]+)\\.0+, (-?[0-9]+)\\.0+, (-?[0-9]+)\\.0+\\)[ \t]+[^ \t]+[ \t]+[0-9.]+$"
|
||||
parsed "${line}"
|
||||
)
|
||||
if(NOT parsed)
|
||||
message(FATAL_ERROR "Cannot parse g-voxel output: ${line}")
|
||||
endif()
|
||||
set(x_coord "${CMAKE_MATCH_1}")
|
||||
set(y_coord "${CMAKE_MATCH_2}")
|
||||
set(z_coord "${CMAKE_MATCH_3}")
|
||||
math(EXPR x_index "(${x_coord} + 16) / 2")
|
||||
math(EXPR y_index "(${y_coord} + 16) / 2")
|
||||
math(EXPR z_index "(${z_coord} - 1) / 2")
|
||||
if(x_index LESS 0 OR x_index GREATER 16 OR
|
||||
y_index LESS 0 OR y_index GREATER 16 OR
|
||||
z_index LESS 0 OR z_index GREATER 29)
|
||||
message(FATAL_ERROR "g-voxel coordinate outside the expected pawn grid: ${line}")
|
||||
endif()
|
||||
set("voxel_${x_index}_${y_index}_${z_index}" 255)
|
||||
endforeach()
|
||||
|
||||
set(volume_text "")
|
||||
foreach(z_index RANGE 0 29)
|
||||
foreach(y_index RANGE 0 16)
|
||||
foreach(x_index RANGE 0 16)
|
||||
if(DEFINED voxel_${x_index}_${y_index}_${z_index})
|
||||
set(sample ff)
|
||||
else()
|
||||
set(sample 00)
|
||||
endif()
|
||||
string(APPEND volume_text "${sample}\n")
|
||||
endforeach()
|
||||
endforeach()
|
||||
endforeach()
|
||||
file(WRITE "${VOLUME_ASCII}" "${volume_text}")
|
||||
|
||||
execute_process(
|
||||
COMMAND "${ASC2PIX}"
|
||||
WORKING_DIRECTORY "${WORKDIR}"
|
||||
TIMEOUT ${RENDER_TIMEOUT}
|
||||
INPUT_FILE "${VOLUME_ASCII}"
|
||||
OUTPUT_FILE "${VOLUME_FILE}"
|
||||
RESULT_VARIABLE asc2pix_result
|
||||
ERROR_VARIABLE asc2pix_error
|
||||
)
|
||||
if(NOT asc2pix_result EQUAL 0)
|
||||
message(FATAL_ERROR "asc2pix failed (exit ${asc2pix_result})\n${asc2pix_error}")
|
||||
endif()
|
||||
file(SIZE "${VOLUME_FILE}" volume_size)
|
||||
if(NOT volume_size EQUAL 8670)
|
||||
message(FATAL_ERROR "VOL sidecar is ${volume_size} bytes; expected 8670")
|
||||
endif()
|
||||
message(STATUS "Encoded ${occupied_voxels} occupied VOL cells")
|
||||
|
||||
# Wrap single primitives in regions so every shaded comparison uses the same
|
||||
# material. The polygonal tree repeats the original CSG union hierarchy with
|
||||
# BoT leaves. VOL references a sidecar basename resolved beside the database.
|
||||
file(WRITE "${MGED_SCRIPT}" [=[
|
||||
db put comparison.brep_evaluated.r comb region yes id 1010 los 100 GIFTmater 1 rgb {235 190 90} shader {plastic} tree {l comparison.brep_evaluated.s}
|
||||
db put comparison.nmg.r comb region yes id 1020 los 100 GIFTmater 1 rgb {235 190 90} shader {plastic} tree {l comparison.nmg.s}
|
||||
db put comparison.bot.r comb region yes id 1030 los 100 GIFTmater 1 rgb {235 190 90} shader {plastic} tree {l comparison.bot.s}
|
||||
db put comparison.polygonal_boolean.r comb region yes id 1040 los 100 GIFTmater 1 rgb {235 190 90} shader {plastic} tree {u {u {u {l base.bot} {l base_bead.bot}} {u {l body.bot} {l stem.bot}}} {u {u {l collar.bot} {l neck.bot}} {l head.bot}}}
|
||||
attr set comparison.voxel_cells.r region R region_id 1050 material_id 1 los 100 shader plastic color 235/190/90
|
||||
db put comparison.point_cloud.r comb region yes id 1060 los 100 GIFTmater 1 rgb {235 190 90} shader {plastic} tree {l comparison.point_cloud.s}
|
||||
db put comparison.volume.s vol file {comparison.vol} name {comparison.vol} src f w 17 n 17 d 30 lo 1 hi 255 size {2 2 2} mat {1 0 0 -17 0 1 0 -17 0 0 1 0 0 0 0 1}
|
||||
db put comparison.volume.r comb region yes id 1070 los 100 GIFTmater 1 rgb {235 190 90} shader {plastic} tree {l comparison.volume.s}
|
||||
q
|
||||
]=])
|
||||
|
||||
execute_process(
|
||||
COMMAND "${MGED}" --no-rc -c "${PAWN_DB}"
|
||||
WORKING_DIRECTORY "${WORKDIR}"
|
||||
TIMEOUT ${RENDER_TIMEOUT}
|
||||
INPUT_FILE "${MGED_SCRIPT}"
|
||||
RESULT_VARIABLE assemble_result
|
||||
OUTPUT_VARIABLE assemble_stdout
|
||||
ERROR_VARIABLE assemble_stderr
|
||||
)
|
||||
if(NOT assemble_result EQUAL 0)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Assembling comparison regions failed (exit ${assemble_result})\n${assemble_stdout}${assemble_stderr}"
|
||||
)
|
||||
endif()
|
||||
|
||||
file(WRITE "${VIEW_SCRIPT}" "viewsize 8.000000000000000e+01;\n")
|
||||
file(APPEND "${VIEW_SCRIPT}" "orientation 2.480970000000000e-01 4.765910000000000e-01 7.480970000000000e-01 3.894350000000000e-01;\n")
|
||||
file(APPEND "${VIEW_SCRIPT}" "eye_pt 4.199070000000000e+01 2.940060000000000e+01 5.329140000000000e+01;\n")
|
||||
file(APPEND "${VIEW_SCRIPT}" "start 0; clean;\n")
|
||||
file(APPEND "${VIEW_SCRIPT}" "end;\n")
|
||||
|
||||
function(copy_snapshot local_image)
|
||||
if(NOT EXISTS "${local_image}")
|
||||
message(FATAL_ERROR "Expected image was not created: ${local_image}")
|
||||
endif()
|
||||
file(SIZE "${local_image}" image_size)
|
||||
if(image_size EQUAL 0)
|
||||
message(FATAL_ERROR "Rendered image is empty: ${local_image}")
|
||||
endif()
|
||||
file(COPY "${local_image}" DESTINATION "${IMGDIR}")
|
||||
get_filename_component(image_name "${local_image}" NAME)
|
||||
file(
|
||||
CHMOD "${IMGDIR}/${image_name}"
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(render_snapshot name object)
|
||||
set(filename "solid_rep_${name}.png")
|
||||
set(local_image "${WORKDIR}/${filename}")
|
||||
file(REMOVE "${local_image}")
|
||||
execute_process(
|
||||
COMMAND "${RT}" -B -M -W "-s${SIZE}" -P1 -o "${filename}" "${PAWN_DB}" "${object}"
|
||||
WORKING_DIRECTORY "${WORKDIR}"
|
||||
TIMEOUT ${RENDER_TIMEOUT}
|
||||
INPUT_FILE "${VIEW_SCRIPT}"
|
||||
RESULT_VARIABLE render_result
|
||||
OUTPUT_VARIABLE render_stdout
|
||||
ERROR_VARIABLE render_stderr
|
||||
)
|
||||
if(NOT render_result EQUAL 0)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Rendering ${name} failed (exit ${render_result})\n${render_stdout}${render_stderr}"
|
||||
)
|
||||
endif()
|
||||
copy_snapshot("${local_image}")
|
||||
message(STATUS "Rendered ${filename}")
|
||||
endfunction()
|
||||
|
||||
render_snapshot(csg comparison.csg.r)
|
||||
render_snapshot(brep_boolean comparison.csg.r.brep)
|
||||
render_snapshot(brep_evaluated comparison.brep_evaluated.r)
|
||||
render_snapshot(polygonal_boolean comparison.polygonal_boolean.r)
|
||||
render_snapshot(nmg comparison.nmg.r)
|
||||
render_snapshot(bot comparison.bot.r)
|
||||
render_snapshot(revolve comparison.revolve.r)
|
||||
render_snapshot(voxel_cells comparison.voxel_cells.r)
|
||||
render_snapshot(volume comparison.volume.r)
|
||||
render_snapshot(point_cloud comparison.point_cloud.r)
|
||||
|
||||
# MGED exports its current wireframe display as view-plane plot3. Rasterize
|
||||
# that plot through a disk framebuffer so regeneration needs no display.
|
||||
set(WIREFRAME_PLOT "${WORKDIR}/solid_rep_wireframe.plot3")
|
||||
set(WIREFRAME_PNG "${WORKDIR}/solid_rep_wireframe.png")
|
||||
set(WIREFRAME_FB_NAME "solid_rep_wireframe.fb")
|
||||
set(WIREFRAME_SCRIPT "${WORKDIR}/wireframe.tcl")
|
||||
file(REMOVE "${WIREFRAME_PLOT}" "${WORKDIR}/${WIREFRAME_FB_NAME}" "${WIREFRAME_PNG}")
|
||||
file(WRITE "${WIREFRAME_SCRIPT}" [=[
|
||||
draw comparison.csg.r
|
||||
size 80
|
||||
orientation 0.248097 0.476591 0.748097 0.389435
|
||||
eye_pt 41.9907 29.4006 53.2914
|
||||
plot -2d solid_rep_wireframe.plot3
|
||||
q
|
||||
]=])
|
||||
execute_process(
|
||||
COMMAND "${MGED}" --no-rc -c "${PAWN_DB}"
|
||||
WORKING_DIRECTORY "${WORKDIR}"
|
||||
TIMEOUT ${RENDER_TIMEOUT}
|
||||
INPUT_FILE "${WIREFRAME_SCRIPT}"
|
||||
RESULT_VARIABLE wireframe_result
|
||||
OUTPUT_VARIABLE wireframe_stdout
|
||||
ERROR_VARIABLE wireframe_stderr
|
||||
)
|
||||
if(NOT wireframe_result EQUAL 0 OR NOT EXISTS "${WIREFRAME_PLOT}")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"MGED wireframe export failed (exit ${wireframe_result})\n${wireframe_stdout}${wireframe_stderr}"
|
||||
)
|
||||
endif()
|
||||
message(STATUS "Exported wireframe plot")
|
||||
run_process(
|
||||
"Cleared wireframe framebuffer"
|
||||
"${FBCLEAR}" -c -F "${WIREFRAME_FB_NAME}" -w "${SIZE}" -n "${SIZE}" 24 24 24
|
||||
)
|
||||
execute_process(
|
||||
COMMAND "${PLOT3FB}" -F "${WIREFRAME_FB_NAME}" -o -w "${SIZE}" -n "${SIZE}"
|
||||
WORKING_DIRECTORY "${WORKDIR}"
|
||||
TIMEOUT ${RENDER_TIMEOUT}
|
||||
INPUT_FILE "${WIREFRAME_PLOT}"
|
||||
RESULT_VARIABLE plot_result
|
||||
OUTPUT_VARIABLE plot_stdout
|
||||
ERROR_VARIABLE plot_stderr
|
||||
)
|
||||
if(NOT plot_result EQUAL 0)
|
||||
message(FATAL_ERROR "plot3-fb failed (exit ${plot_result})\n${plot_stdout}${plot_stderr}")
|
||||
endif()
|
||||
run_process(
|
||||
"Rasterized wireframe snapshot"
|
||||
"${FBPNG}" -F "${WIREFRAME_FB_NAME}" -w "${SIZE}" -n "${SIZE}"
|
||||
"solid_rep_wireframe.png"
|
||||
)
|
||||
copy_snapshot("${WIREFRAME_PNG}")
|
||||
|
||||
message(STATUS "Solid representation comparison: 11 snapshots regenerated")
|
||||
@@ -22,4 +22,5 @@ Task-focused guides and how-to articles.
|
||||
* link:articles/procedural_geometry.html[BRL-CAD Procedural Geometry Gallery]
|
||||
* link:articles/projection_shader.html[Using the Projection Shader]
|
||||
* link:articles/renderer_showcase.html[BRL-CAD Renderer Showcase]
|
||||
* link:articles/solid_geometry_comparison.html[Solid Geometry Representation Comparisons]
|
||||
* link:articles/tire.html[Vehicle Tire and Wheel Creation in BRL-CAD]
|
||||
|
||||
@@ -1 +1 @@
|
||||
45
|
||||
47
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
include(CMakeParseArguments)
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/BRLCAD_Repository.cmake")
|
||||
|
||||
# Try to locate a usable git executable. On Windows, Visual Studio may
|
||||
# provide git in non-standard locations; try common Program Files and
|
||||
@@ -88,6 +89,15 @@ function(brlcad_bext_init BEXT_SHA1)
|
||||
set(BRLCAD_EXT_DIR "${BRLCAD_EXT_DIR_ENV}")
|
||||
endif(BRLCAD_EXT_DIR_ENV AND NOT DEFINED BRLCAD_EXT_DIR)
|
||||
|
||||
# Resolve paths before probing them so later subconfigures use the same
|
||||
# directories even when launched from a different working directory.
|
||||
foreach(_brlcad_ext_path_var BRLCAD_EXT_DIR BRLCAD_EXT_SOURCE_DIR)
|
||||
if(DEFINED ${_brlcad_ext_path_var} AND NOT "${${_brlcad_ext_path_var}}" STREQUAL "")
|
||||
get_filename_component(${_brlcad_ext_path_var} "${${_brlcad_ext_path_var}}" ABSOLUTE BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||
set(${_brlcad_ext_path_var} "${${_brlcad_ext_path_var}}" PARENT_SCOPE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(_brlcad_ext_dir_specified FALSE)
|
||||
set(_brlcad_ext_dir_managed FALSE)
|
||||
|
||||
@@ -148,14 +158,14 @@ function(brlcad_bext_init BEXT_SHA1)
|
||||
elseif(NOT _brlcad_ext_dir_specified)
|
||||
message(
|
||||
WARNING
|
||||
"External dependencies will be downloaded, configured, and built automatically as-needed. Set BRLCAD_EXT_DIR to specify instead."
|
||||
"External dependencies will be acquired from ${_BRLCAD_REPOSITORY_ROOT}, configured, and built automatically as-needed. Set BRLCAD_EXT_DIR to specify instead."
|
||||
)
|
||||
endif()
|
||||
message(
|
||||
STATUS
|
||||
"BRLCAD_EXT_DIR specifies prebuilt external dependencies directory\n"
|
||||
"containing 'install' and 'noinstall' folders, outputs from installing\n"
|
||||
"https://github.com/BRL-CAD/bext.\n"
|
||||
"${_BRLCAD_BEXT_REPOSITORY}.\n"
|
||||
)
|
||||
endif(NOT BRLCAD_EXT_NOINSTALL_DIR OR NOT BRLCAD_EXT_INSTALL_DIR)
|
||||
|
||||
@@ -211,28 +221,24 @@ function(brlcad_rel_version BRLCAD_REL)
|
||||
set(${BRLCAD_REL} "rel-${VMAJOR}-${VMINOR}-${VPATCH}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Look up branch or tag SHA1 hashes from primary github.com repo
|
||||
# Branch/tag queries are advisory; an unavailable source cannot validate them.
|
||||
function(remote_sha1 SHA1_VAR BRANCH)
|
||||
set(${SHA1_VAR} "" PARENT_SCOPE)
|
||||
if(NOT GIT_EXEC)
|
||||
set(${SHA1_VAR} "" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
# This needs a working internet connection to succeed (and GitHub
|
||||
# must be up and working as well.)
|
||||
brlcad_repository_git_command(git_command)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXEC} ls-remote https://github.com/BRL-CAD/bext.git ${BRANCH}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
RESULT_VARIABLE LS_REMOTE_STATUS
|
||||
OUTPUT_VARIABLE LS_REMOTE_STR
|
||||
ERROR_VARIABLE LS_REMOTE_STR
|
||||
)
|
||||
if(NOT LS_REMOTE_STATUS AND LS_REMOTE_STR)
|
||||
string(REPLACE " " ";" LS_REMOTE_STR "${LS_REMOTE_STR}")
|
||||
string(REPLACE "\t" ";" LS_REMOTE_STR "${LS_REMOTE_STR}")
|
||||
list(GET LS_REMOTE_STR 0 REMOTE_SHA1)
|
||||
set(${SHA1_VAR} "${REMOTE_SHA1}" PARENT_SCOPE)
|
||||
else()
|
||||
set(${SHA1_VAR} "" PARENT_SCOPE)
|
||||
COMMAND "${CMAKE_COMMAND}" -E env GIT_TERMINAL_PROMPT=0 --
|
||||
${git_command} -c credential.helper= -c credential.interactive=false
|
||||
ls-remote "${_BRLCAD_BEXT_REPOSITORY}" "${BRANCH}"
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
RESULT_VARIABLE git_result
|
||||
OUTPUT_VARIABLE remote_refs
|
||||
ERROR_QUIET
|
||||
)
|
||||
if(git_result STREQUAL "0" AND remote_refs MATCHES "^([0-9a-f]+)[ \t]")
|
||||
set(${SHA1_VAR} "${CMAKE_MATCH_1}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@@ -367,24 +373,29 @@ function(setup_bext_dir)
|
||||
# no pre-existing sources, so we're cloning into the build dir
|
||||
set(BRLCAD_EXT_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/bext")
|
||||
|
||||
# Write current SHA1 for subsequent processing
|
||||
brlcad_repository_git_command(git_command)
|
||||
message(STATUS "Cloning bext from ${_BRLCAD_BEXT_REPOSITORY}")
|
||||
execute_process(
|
||||
COMMAND ${git_command} clone "${_BRLCAD_BEXT_REPOSITORY}" "${BRLCAD_EXT_SOURCE_DIR}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
RESULT_VARIABLE git_result
|
||||
)
|
||||
if(NOT git_result STREQUAL "0")
|
||||
message(FATAL_ERROR "Unable to clone bext from ${_BRLCAD_BEXT_REPOSITORY} (${git_result})")
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND ${git_command} -c advice.detachedHead=false checkout "${BEXT_SHA1}"
|
||||
WORKING_DIRECTORY "${BRLCAD_EXT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE git_result
|
||||
)
|
||||
if(NOT git_result STREQUAL "0")
|
||||
message(FATAL_ERROR "Unable to check out pinned bext commit ${BEXT_SHA1} from ${_BRLCAD_BEXT_REPOSITORY} (${git_result}); ensure the repository contains this commit")
|
||||
endif()
|
||||
|
||||
# Record the pin only after checkout succeeds.
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/bext.sha1" "${BEXT_SHA1}")
|
||||
distclean("${CMAKE_CURRENT_BINARY_DIR}/bext.sha1")
|
||||
|
||||
# Clone
|
||||
message("BRL-CAD bext clone command: ${GIT_EXEC} clone https://github.com/BRL-CAD/bext.git")
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXEC} clone https://github.com/BRL-CAD/bext.git
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
message("BRL-CAD bext checkout command: ${GIT_EXEC} -c advice.detachedHead=false checkout ${BEXT_SHA1}")
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXEC} -c advice.detachedHead=false checkout ${BEXT_SHA1}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bext
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
|
||||
# Configure process will need to clean up bext
|
||||
if (BRLCAD_BEXT_CLEANUP)
|
||||
set(BEXT_SRC_CLEANUP TRUE PARENT_SCOPE)
|
||||
@@ -425,6 +436,12 @@ function(brlcad_ext_setup)
|
||||
message(FATAL_ERROR "Invalid bext directory: ${BRLCAD_EXT_SOURCE_DIR}")
|
||||
endif()
|
||||
|
||||
if(NOT _BRLCAD_REPOSITORY_ROOT STREQUAL "${_BRLCAD_REPOSITORY_DEFAULT_ROOT}/"
|
||||
AND NOT EXISTS "${BRLCAD_EXT_SOURCE_DIR}/CMake/BextGit.cmake")
|
||||
message(FATAL_ERROR
|
||||
"bext sources in ${BRLCAD_EXT_SOURCE_DIR} do not support BEXT_REPOSITORY_ROOT; update bext before building with BRLCAD_REPOSITORY_ROOT=${BRLCAD_REPOSITORY_ROOT}")
|
||||
endif()
|
||||
|
||||
# We do allow the user to specify a build dir to be reused, however
|
||||
# this is unpredictable and may cause unexpected results depending
|
||||
# on what is or isn't rebuilt - use with care.
|
||||
@@ -463,11 +480,18 @@ function(brlcad_ext_setup)
|
||||
endif(BRLCAD_ENABLE_APPLESEED)
|
||||
|
||||
# Define CMake arguments we'll need regardless of mode
|
||||
set(bext_shallow_clone ON)
|
||||
if(_BRLCAD_REPOSITORY_LOCAL)
|
||||
set(bext_shallow_clone OFF)
|
||||
endif()
|
||||
set(CMAKE_CMD_ARGS
|
||||
-S ${BRLCAD_EXT_SOURCE_DIR} -B ${BRLCAD_EXT_BUILD_DIR} -DGIT_SHALLOW_CLONE=ON
|
||||
-DENABLE_ALL=${BEXT_ENABLE_ALL} -DUSE_GDAL=${BEXT_USE_GDAL} -DUSE_QT=${BEXT_USE_QT} -DUSE_TCL=${BEXT_USE_TCL}
|
||||
-DUSE_APPLESEED=${BEXT_USE_APPLESEED} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
-DCMAKE_INSTALL_PREFIX=${BRLCAD_EXT_INSTALL_DIR}
|
||||
-S "${BRLCAD_EXT_SOURCE_DIR}" -B "${BRLCAD_EXT_BUILD_DIR}"
|
||||
"-DBEXT_REPOSITORY_ROOT:STRING=${_BRLCAD_REPOSITORY_ROOT}"
|
||||
"-DGIT_SHALLOW_CLONE:BOOL=${bext_shallow_clone}"
|
||||
"-DENABLE_ALL=${BEXT_ENABLE_ALL}" "-DUSE_GDAL=${BEXT_USE_GDAL}"
|
||||
"-DUSE_QT=${BEXT_USE_QT}" "-DUSE_TCL=${BEXT_USE_TCL}"
|
||||
"-DUSE_APPLESEED=${BEXT_USE_APPLESEED}" "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
|
||||
"-DCMAKE_INSTALL_PREFIX=${BRLCAD_EXT_INSTALL_DIR}"
|
||||
)
|
||||
if(BRLCAD_X11_PROVIDER_RESOLVED STREQUAL "XMIN" AND BRLCAD_XMIN_ROOT)
|
||||
list(APPEND CMAKE_CMD_ARGS
|
||||
|
||||
@@ -1108,9 +1108,9 @@ function(brlcad_install_strclear_replace stamp_dir strclear source install_file
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(brlcad_install_binary_postprocess stamp_dir strclear source install_file install_type mode rpath_tool install_rpath build_lib_path rel_rpath use_selective_rpath verbose)
|
||||
function(brlcad_install_binary_postprocess stamp_dir strclear source install_file install_type mode rpath_tool install_rpath build_lib_path rel_rpath verbose)
|
||||
set(_brlcad_physical_file "$ENV{DESTDIR}${install_file}")
|
||||
set(_brlcad_signature "binary-postprocess|${install_type}|${mode}|${rpath_tool}|${install_rpath}|${build_lib_path}|${rel_rpath}|${use_selective_rpath}|${strclear}")
|
||||
set(_brlcad_signature "binary-postprocess|${install_type}|${mode}|${rpath_tool}|${install_rpath}|${build_lib_path}|${rel_rpath}|${strclear}")
|
||||
_brlcad_postprocess_needed(_brlcad_needed "${stamp_dir}" "${source}" "${_brlcad_physical_file}" "${_brlcad_signature}")
|
||||
if(NOT _brlcad_needed)
|
||||
return()
|
||||
@@ -1121,32 +1121,41 @@ function(brlcad_install_binary_postprocess stamp_dir strclear source install_fil
|
||||
message(FATAL_ERROR "Post-install copy did not create ${_brlcad_physical_file}")
|
||||
endif()
|
||||
set(_brlcad_result 0)
|
||||
set(_brlcad_rpath_output)
|
||||
set(_brlcad_rpath_error)
|
||||
if("${mode}" STREQUAL "RPATH_TOOL")
|
||||
set(_brlcad_selective_rpath_args)
|
||||
if(use_selective_rpath)
|
||||
set(_brlcad_selective_rpath_args --set-rpath-if-needed --set-rpath-if-needed-prepend --stale-rpath-prefix "${build_lib_path}")
|
||||
endif()
|
||||
# Install the exact project-defined search order. A selective update can
|
||||
# leave an existing relative-only RPATH without the canonical install path.
|
||||
execute_process(
|
||||
COMMAND "${rpath_tool}" --set-rpath "${install_rpath}" ${_brlcad_selective_rpath_args} "${_brlcad_physical_file}"
|
||||
COMMAND "${rpath_tool}" --set-rpath "${install_rpath}" "${_brlcad_physical_file}"
|
||||
RESULT_VARIABLE _brlcad_result
|
||||
OUTPUT_VARIABLE _brlcad_rpath_output
|
||||
ERROR_VARIABLE _brlcad_rpath_error
|
||||
)
|
||||
elseif("${mode}" STREQUAL "APPLE")
|
||||
execute_process(
|
||||
COMMAND install_name_tool -delete_rpath "${build_lib_path}" "${_brlcad_physical_file}"
|
||||
RESULT_VARIABLE _brlcad_result
|
||||
OUTPUT_VARIABLE _brlcad_output
|
||||
ERROR_VARIABLE _brlcad_error
|
||||
OUTPUT_VARIABLE _brlcad_rpath_output
|
||||
ERROR_VARIABLE _brlcad_rpath_error
|
||||
)
|
||||
if(_brlcad_result EQUAL 0)
|
||||
execute_process(
|
||||
COMMAND install_name_tool -add_rpath "${rel_rpath}" "${_brlcad_physical_file}"
|
||||
RESULT_VARIABLE _brlcad_result
|
||||
OUTPUT_VARIABLE _brlcad_rpath_output
|
||||
ERROR_VARIABLE _brlcad_rpath_error
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT _brlcad_result EQUAL 0)
|
||||
message(WARNING "Post-install RPATH update failed for ${_brlcad_physical_file}")
|
||||
message(
|
||||
WARNING
|
||||
"Post-install RPATH update failed for ${_brlcad_physical_file}\n"
|
||||
"stdout: ${_brlcad_rpath_output}\n"
|
||||
"stderr: ${_brlcad_rpath_error}"
|
||||
)
|
||||
return()
|
||||
endif()
|
||||
|
||||
@@ -1840,13 +1849,9 @@ endfunction()
|
||||
elseif(APPLE)
|
||||
set(_brlcad_install_postprocess_mode "APPLE")
|
||||
endif(P_RPATH_EXECUTABLE)
|
||||
set(_brlcad_install_use_selective_rpath FALSE)
|
||||
if(P_RPATH_SUPPORTS_SET_IF_NEEDED_PREPEND)
|
||||
set(_brlcad_install_use_selective_rpath TRUE)
|
||||
endif(P_RPATH_SUPPORTS_SET_IF_NEEDED_PREPEND)
|
||||
install(
|
||||
CODE
|
||||
"include(\"${BRLCAD_EXT_INSTALL_POSTPROCESS_SCRIPT}\")\nbrlcad_install_binary_postprocess(\"${BRLCAD_EXT_INSTALL_POSTPROCESS_STAMP_DIR}\" \"${STRCLEAR_EXECUTABLE}\" \"${CMAKE_BINARY_DIR}/${tf}\" \"\${CMAKE_INSTALL_PREFIX}/${tf}\" \"PROGRAM\" \"${_brlcad_install_postprocess_mode}\" \"${_brlcad_install_postprocess_tool}\" \"${_brlcad_install_postprocess_rpath}\" \"${CMAKE_BINARY_DIR}/${LIB_DIR}\" \"${REL_RPATH}\" \"${_brlcad_install_use_selective_rpath}\" \"${BRLCAD_VERBOSE}\")"
|
||||
"include(\"${BRLCAD_EXT_INSTALL_POSTPROCESS_SCRIPT}\")\nbrlcad_install_binary_postprocess(\"${BRLCAD_EXT_INSTALL_POSTPROCESS_STAMP_DIR}\" \"${STRCLEAR_EXECUTABLE}\" \"${CMAKE_BINARY_DIR}/${tf}\" \"\${CMAKE_INSTALL_PREFIX}/${tf}\" \"PROGRAM\" \"${_brlcad_install_postprocess_mode}\" \"${_brlcad_install_postprocess_tool}\" \"${_brlcad_install_postprocess_rpath}\" \"${CMAKE_BINARY_DIR}/${LIB_DIR}\" \"${REL_RPATH}\" \"${BRLCAD_VERBOSE}\")"
|
||||
)
|
||||
continue()
|
||||
endif("${tf}" IN_LIST ALL_BINARY_FILES)
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
# Copyright (c) 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.
|
||||
|
||||
include_guard(GLOBAL)
|
||||
|
||||
set(_BRLCAD_REPOSITORY_DEFAULT_ROOT "https://github.com/BRL-CAD")
|
||||
set(BRLCAD_REPOSITORY_ROOT "${_BRLCAD_REPOSITORY_DEFAULT_ROOT}" CACHE STRING
|
||||
"Repository URL or local mirror directory containing bext and its dependency repositories")
|
||||
|
||||
function(brlcad_repository_root out_root out_local)
|
||||
set(root "${BRLCAD_REPOSITORY_ROOT}")
|
||||
set(local FALSE)
|
||||
if(root STREQUAL "")
|
||||
message(FATAL_ERROR "BRLCAD_REPOSITORY_ROOT must be a repository URL or local mirror directory")
|
||||
endif()
|
||||
|
||||
# Match bext's URL handling, but resolve relative paths against BRL-CAD.
|
||||
# Drive paths must be checked before scp-style SSH locations.
|
||||
if(root MATCHES "^file://")
|
||||
set(local TRUE)
|
||||
string(REPLACE "=" "%3D" root "${root}")
|
||||
elseif(root MATCHES "^[A-Za-z]:[/\\\\]" OR
|
||||
NOT (root MATCHES "^[A-Za-z][A-Za-z0-9+.-]*://" OR root MATCHES "^[^/]+:.+"))
|
||||
set(local TRUE)
|
||||
string(REPLACE "\\" "/" root "${root}")
|
||||
if(WIN32 OR NOT root MATCHES "^[A-Za-z]:/")
|
||||
get_filename_component(root "${root}" ABSOLUTE BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||
endif()
|
||||
# Escape literal percent signs first so native paths cannot introduce
|
||||
# URL escapes. An equals sign also has meaning in Git's -c assignments.
|
||||
string(REPLACE "%" "%25" root "${root}")
|
||||
string(REPLACE " " "%20" root "${root}")
|
||||
string(REPLACE "#" "%23" root "${root}")
|
||||
string(REPLACE "?" "%3F" root "${root}")
|
||||
string(REPLACE "=" "%3D" root "${root}")
|
||||
if(root MATCHES "^[A-Za-z]:/")
|
||||
set(root "file:///${root}")
|
||||
elseif(root MATCHES "^//")
|
||||
set(root "file:${root}")
|
||||
else()
|
||||
set(root "file://${root}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT root MATCHES "^file:///*$")
|
||||
string(REGEX REPLACE "/+$" "" root "${root}")
|
||||
string(APPEND root "/")
|
||||
else()
|
||||
set(root "file:///")
|
||||
endif()
|
||||
set(${out_root} "${root}" PARENT_SCOPE)
|
||||
set(${out_local} "${local}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(brlcad_repository_git_command out_command)
|
||||
set(git_command "${GIT_EXEC}")
|
||||
if(WIN32)
|
||||
list(APPEND git_command -c core.longpaths=true)
|
||||
endif()
|
||||
if(_BRLCAD_REPOSITORY_LOCAL)
|
||||
list(APPEND git_command -c protocol.file.allow=always)
|
||||
# This also constrains recursive Git processes and user URL rewrites.
|
||||
list(PREPEND git_command "${CMAKE_COMMAND}" -E env GIT_ALLOW_PROTOCOL=file --)
|
||||
endif()
|
||||
set(${out_command} "${git_command}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
brlcad_repository_root(_BRLCAD_REPOSITORY_ROOT _BRLCAD_REPOSITORY_LOCAL)
|
||||
set(_BRLCAD_BEXT_REPOSITORY "${_BRLCAD_REPOSITORY_ROOT}bext.git")
|
||||
message(STATUS "BRL-CAD repository root: ${_BRLCAD_REPOSITORY_ROOT}")
|
||||
if(_BRLCAD_REPOSITORY_LOCAL)
|
||||
message(STATUS "BRL-CAD Git acquisition: file transport only")
|
||||
endif()
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: cmake
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=2 tabstop=8
|
||||
@@ -15,6 +15,7 @@ set(
|
||||
BRLCAD_Options.cmake
|
||||
BRLCAD_Probe_Validation.cmake
|
||||
BRLCAD_Regress_Util.cmake
|
||||
BRLCAD_Repository.cmake
|
||||
BRLCAD_Summary.cmake
|
||||
BRLCAD_Targets.cmake
|
||||
BRLCAD_Test_Wrappers.cmake
|
||||
|
||||
@@ -95,6 +95,33 @@ add_custom_target(
|
||||
)
|
||||
set_target_properties(distcheck-source_archives PROPERTIES FOLDER "BRL-CAD Distribution Checking")
|
||||
|
||||
# Dependency paths must survive CMake, build-tool, and shell parsing. Load
|
||||
# their values from a cache file rather than embedding them in command text.
|
||||
set(distcheck_dependency_cache "${CMAKE_CURRENT_BINARY_DIR}/CMakeTmp/distcheck_dependencies.cmake")
|
||||
set(distcheck_dependency_vars BRLCAD_REPOSITORY_ROOT BRLCAD_EXT_DIR)
|
||||
foreach(distcheck_optional_var BRLCAD_EXT_SOURCE_DIR BRLCAD_EXT_PARALLEL)
|
||||
if(DEFINED ${distcheck_optional_var})
|
||||
list(APPEND distcheck_dependency_vars ${distcheck_optional_var})
|
||||
endif()
|
||||
endforeach()
|
||||
file(WRITE "${distcheck_dependency_cache}" "")
|
||||
foreach(distcheck_var IN LISTS distcheck_dependency_vars)
|
||||
set(distcheck_value "${${distcheck_var}}")
|
||||
if(distcheck_var STREQUAL "BRLCAD_REPOSITORY_ROOT")
|
||||
set(distcheck_value "${_BRLCAD_REPOSITORY_ROOT}")
|
||||
endif()
|
||||
set(distcheck_type STRING)
|
||||
if(distcheck_var MATCHES "_DIR$")
|
||||
set(distcheck_type PATH)
|
||||
endif()
|
||||
string(REPLACE "\\" "\\\\" distcheck_value "${distcheck_value}")
|
||||
string(REPLACE "\"" "\\\"" distcheck_value "${distcheck_value}")
|
||||
string(REPLACE "$" "\\$" distcheck_value "${distcheck_value}")
|
||||
file(APPEND "${distcheck_dependency_cache}"
|
||||
"set(${distcheck_var} \"${distcheck_value}\" CACHE ${distcheck_type} \"Inherited dependency setting\" FORCE)\n")
|
||||
endforeach()
|
||||
distclean("${distcheck_dependency_cache}")
|
||||
|
||||
# Utility function for defining individual distcheck targets
|
||||
macro(
|
||||
create_distcheck
|
||||
@@ -120,7 +147,10 @@ macro(
|
||||
|
||||
# Need to set these locally so configure_file will pick them up...
|
||||
set(TARGET_SUFFIX ${TARGET_SUFFIX})
|
||||
set(CMAKE_OPTS ${CMAKE_OPTS_IN})
|
||||
# Keep machine-specific settings out of the options saved for CI above.
|
||||
# The shared cache replaces each variant's unquoted output argument.
|
||||
string(REPLACE "-DBRLCAD_EXT_DIR=${BRLCAD_EXT_DIR}" "" CMAKE_OPTS "${CMAKE_OPTS_IN}")
|
||||
string(APPEND CMAKE_OPTS " -C \"${distcheck_dependency_cache}\"")
|
||||
|
||||
# For configure_file, need to set these as variables not just input parameters
|
||||
set(source_dir "${source_dir}")
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
brlcad (7.46.0-0) unstable; urgency=low
|
||||
|
||||
* update brlcad version
|
||||
|
||||
-- Cliff Yapp <cyapp@brlcad.org> Thu, 07 Oct 2026 20:24:00 +0000
|
||||
|
||||
brlcad (7.44.0-0) unstable; urgency=low
|
||||
|
||||
* update brlcad version
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
\f0\i\b\fs72 \cf0 README
|
||||
\fs36 \
|
||||
|
||||
\f1\i0\b0\fs28 This is BRL-CAD 7.44.0 for Mac OS X. Please send any bugs, comments, questions, or suggestions to the project website.\
|
||||
\f1\i0\b0\fs28 This is BRL-CAD 7.46.0 for Mac OS X. Please send any bugs, comments, questions, or suggestions to the project website.\
|
||||
|
||||
\fs22 \
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
\margl1440\margr1440\vieww8020\viewh6280\viewkind0
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
|
||||
|
||||
\f0\fs22 \cf0 This installer will guide you through the installation of BRL-CAD 7.44.0 for Mac OS X and Darwin.\
|
||||
\f0\fs22 \cf0 This installer will guide you through the installation of BRL-CAD 7.46.0 for Mac OS X and Darwin.\
|
||||
\
|
||||
This distribution of BRL-CAD requires approximately 500 MB of available disk space and does not include source code.\
|
||||
\
|
||||
|
||||
@@ -79,7 +79,9 @@ endif(NOT EXISTS \"\${GCV_EXEC}\")\n"
|
||||
# setup conversion tests
|
||||
foreach(in_file ${INPUT_FILES})
|
||||
get_filename_component(curr_in_basename ${in_file} NAME_WLE)
|
||||
set(out_path "${CMAKE_CURRENT_BINARY_DIR}/conv-${curr_in_basename}")
|
||||
# Tests in the same directory may run concurrently, so their output paths
|
||||
# must not overlap.
|
||||
set(out_path "${CMAKE_CURRENT_BINARY_DIR}/conv-${TARGET_DIRECTION}-${curr_in_basename}")
|
||||
|
||||
# need to split suffix so we can distinguish from different converters
|
||||
if(${fmt}_EXPORTER)
|
||||
@@ -120,7 +122,7 @@ endif(NOT EXISTS \"\${GCV_EXEC}\")\n"
|
||||
)
|
||||
endif(${fmt}_GCV_OPTIONS)
|
||||
|
||||
set(out_distclean ${out_distclean}} "${out_path}-${out_fmt}${out_suffix}")
|
||||
set(out_distclean ${out_distclean} "${out_path}-${out_fmt}${out_suffix}")
|
||||
set(expected_output_files "${expected_output_files} \"${out_path}-${out_fmt}${out_suffix}\"")
|
||||
endforeach(out_fmt ${${fmt}_CONVERTERS})
|
||||
|
||||
@@ -162,19 +164,8 @@ execute_process(
|
||||
|
||||
file(APPEND \"\${LOGFILE}\" \"\${log_msg}\\n\")
|
||||
unset(log_msg)
|
||||
"
|
||||
)
|
||||
|
||||
set(OUTPUT_FILES ${OUTPUT_FILES} ${out_distclean})
|
||||
unset(expected_output_files)
|
||||
unset(out_distclean)
|
||||
endforeach(in_file ${INPUT_FILES})
|
||||
|
||||
file(
|
||||
APPEND
|
||||
${cmake_in_path}
|
||||
"
|
||||
# check output files exists and are a reasonable size
|
||||
# check output files exist and are a reasonable size
|
||||
foreach(out_file \${ofiles})
|
||||
if(NOT EXISTS \"\${out_file}\")
|
||||
file(APPEND \"\${LOGFILE}\" \"FAILURE: \${curr_result}, \${out_file} not found.\")
|
||||
@@ -191,13 +182,18 @@ foreach(out_file \${ofiles})
|
||||
file(APPEND \"\${LOGFILE}\" \"FAILURE: \${curr_result} file size is \${file_size} for \${out_file}\\n Expecting ${EXPECTED_FILE_SIZE} with delta ${FILE_SIZE_DELTA}\")
|
||||
message(FATAL_ERROR \"[gcv] Failure while converting ${in_file}, see \${LOGFILE} for more info.\")
|
||||
endif(\"\${size_delta}\" GREATER \"${FILE_SIZE_DELTA}\")
|
||||
endif(NOT EXISTS \"\${out_file}\")\n
|
||||
endif(NOT EXISTS \"\${out_file}\")
|
||||
|
||||
# cleanup file from build dir
|
||||
file(REMOVE \"\${out_file}\")
|
||||
endforeach(out_file \${ofiles})
|
||||
"
|
||||
)
|
||||
"
|
||||
)
|
||||
|
||||
set(OUTPUT_FILES ${OUTPUT_FILES} ${out_distclean})
|
||||
unset(expected_output_files)
|
||||
unset(out_distclean)
|
||||
endforeach(in_file ${INPUT_FILES})
|
||||
|
||||
# assume the fmt is the gcv dependency unless specified
|
||||
if(${fmt}_DEPS)
|
||||
|
||||
@@ -2,7 +2,7 @@ if(TARGET gcv-assetimport)
|
||||
gcv_regress_util("gltf" "tetra-gltf2.0.gltf;tetra-glb2.0.glb" DEPS "gcv;gcv-assetimport" GCV_OPTIONS "--input-format=assetimport")
|
||||
gcv_regress_util("glb" "tetra.g" DEPS "gcv;gcv-assetimport" GCV_OPTIONS "--output-format=assetimport" EXPECTED_FILE_SIZE "1476" EXPORTER)
|
||||
gcv_regress_util("gltf" "tetra.g" DEPS "gcv;gcv-assetimport" GCV_OPTIONS "--output-format=assetimport" EXPECTED_FILE_SIZE "3356" EXPORTER)
|
||||
distclean("${CMAKE_CURRENT_BINARY_DIR}/conv-tetra.bin")
|
||||
distclean("${CMAKE_CURRENT_BINARY_DIR}/conv-regress-g-gltf-tetra.bin")
|
||||
endif(TARGET gcv-assetimport)
|
||||
|
||||
if(TARGET gcv-gltf)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
if(TARGET gcv-assetimport)
|
||||
set(dep_str DEPS "gcv;gcv-obj;gcv-assetimport" CONVERTERS "assetimport")
|
||||
|
||||
distclean("${CMAKE_CURRENT_BINARY_DIR}/conv-tetra-assetimport.mtl") # hard to track companion files
|
||||
distclean("${CMAKE_CURRENT_BINARY_DIR}/conv-regress-g-obj-tetra-assetimport.mtl") # hard to track companion files
|
||||
else()
|
||||
set(dep_str "")
|
||||
endif(TARGET gcv-assetimport)
|
||||
@@ -9,7 +9,7 @@ endif(TARGET gcv-assetimport)
|
||||
gcv_regress_util("obj" "tetra.obj" ${dep_str})
|
||||
gcv_regress_util("obj_unnamed_group" "tetra-unnamed-group.obj" DEPS "gcv;gcv-obj")
|
||||
gcv_regress_util("obj" "tetra.g" ${dep_str} EXPORTER)
|
||||
distclean("${CMAKE_CURRENT_BINARY_DIR}/conv-tetra.mtl")
|
||||
distclean("${CMAKE_CURRENT_BINARY_DIR}/conv-regress-g-obj-tetra.mtl")
|
||||
|
||||
cmakefiles(
|
||||
CMakeLists.txt
|
||||
|
||||
@@ -144,6 +144,18 @@ if(BRLCAD_X11_PROVIDER_RESOLVED STREQUAL "XMIN" AND
|
||||
)
|
||||
brlcad_regression_test(regress-archer-embedded-xmin-gui
|
||||
"archer;bwish" STAND_ALONE TEST_DEFINED)
|
||||
|
||||
brlcad_add_gui_test(
|
||||
NAME regress-archer-geometry-xmin-gui
|
||||
TIMEOUT 120
|
||||
ENVIRONMENT ${_gui_smoke_environment}
|
||||
"GUI_TEST_LIBRARY=${_gui_test_library}"
|
||||
COMMAND "${SH_EXEC}" "${_gui_tcl_runner}" archer-geometry
|
||||
$<TARGET_FILE:bwish>
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/archer_geometry_xmin_gui.tcl"
|
||||
)
|
||||
brlcad_regression_test(regress-archer-geometry-xmin-gui
|
||||
"archer;bwish" STAND_ALONE TEST_DEFINED)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -201,6 +213,7 @@ cmakefiles(
|
||||
archer_action.sh
|
||||
archer_smoke.sh
|
||||
archer_embedded_xmin_gui.tcl
|
||||
archer_geometry_xmin_gui.tcl
|
||||
archer_menu_manifest.txt
|
||||
archer_xmin_gui.tcl
|
||||
qged_action.sh
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
# A R C H E R _ G E O M E T R Y _ X M I N _ G U I . T C L
|
||||
# BRL-CAD
|
||||
#
|
||||
# Copyright (c) 2026 United States Government as represented by
|
||||
# the U.S. Army Research Laboratory.
|
||||
#
|
||||
# This library 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 library 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.
|
||||
#
|
||||
###
|
||||
if {![info exists ::env(GUI_TEST_LIBRARY)]} {
|
||||
puts stderr "GUI_TEST_LIBRARY is required"
|
||||
exit 2
|
||||
}
|
||||
source $::env(GUI_TEST_LIBRARY)
|
||||
set ::env(ARCHER_PREFS_FILE) [file join $::env(GUI_TEST_DIR) .archerrc]
|
||||
|
||||
proc archer_geometry_preferences {{geometry ""}} {
|
||||
set channel [open $::env(ARCHER_PREFS_FILE) w]
|
||||
if {$geometry ne ""} {
|
||||
puts $channel [list set mWindowGeometry $geometry]
|
||||
}
|
||||
close $channel
|
||||
}
|
||||
|
||||
proc archer_geometry_saved {} {
|
||||
set channel [open $::env(ARCHER_PREFS_FILE) r]
|
||||
set contents [read $channel]
|
||||
close $channel
|
||||
if {[regexp -line {^set mWindowGeometry (.+)$} $contents -> geometry]} {
|
||||
return $geometry
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
proc archer_geometry_settle {} {
|
||||
# Allow MapNotify and the deferred geometry restore to reach the event loop.
|
||||
set settle_delay_ms 100
|
||||
after $settle_delay_ms [list set ::archer_geometry_settled 1]
|
||||
vwait ::archer_geometry_settled
|
||||
update
|
||||
::gui::test::require_no_background_errors
|
||||
}
|
||||
|
||||
if {[catch {
|
||||
package require Archer 1.0
|
||||
::gui::test::capture_background_errors
|
||||
wm withdraw .
|
||||
|
||||
set saved_geometry 900x650+120+90
|
||||
set startup_geometry 1000x700+20+30
|
||||
set updated_geometry 950x680+60+70
|
||||
set default_geometry 920x660+40+50
|
||||
|
||||
archer_geometry_preferences $saved_geometry
|
||||
Archer .unmapped
|
||||
::gui::test::require {[wm state .unmapped] eq "withdrawn"} \
|
||||
"startup fixture unexpectedly showed its window"
|
||||
::itcl::delete object .unmapped
|
||||
archer_geometry_settle
|
||||
::gui::test::require {[archer_geometry_saved] eq $saved_geometry} \
|
||||
"closing an unmapped Archer replaced its saved geometry"
|
||||
|
||||
archer_geometry_preferences
|
||||
Archer .unmapped_new
|
||||
::itcl::delete object .unmapped_new
|
||||
archer_geometry_settle
|
||||
::gui::test::require {[archer_geometry_saved] eq ""} \
|
||||
"closing an unmapped Archer saved an unfinished layout size"
|
||||
|
||||
archer_geometry_preferences $saved_geometry
|
||||
Archer .restore
|
||||
.restore configure -geometry $startup_geometry
|
||||
wm geometry .restore $startup_geometry
|
||||
event generate [.restore component hpane] <Map>
|
||||
archer_geometry_settle
|
||||
::gui::test::require {[wm geometry .restore] eq $startup_geometry} \
|
||||
"a child Map event restored the main window's geometry prematurely"
|
||||
|
||||
wm deiconify .restore
|
||||
archer_geometry_settle
|
||||
::gui::test::require {[wm geometry .restore] eq $saved_geometry} \
|
||||
"mapping the main window did not restore its saved geometry"
|
||||
|
||||
wm geometry .restore $updated_geometry
|
||||
event generate [.restore component hpane] <Map>
|
||||
archer_geometry_settle
|
||||
::gui::test::require {[wm geometry .restore] eq $updated_geometry} \
|
||||
"a later child Map event reset the resized main window"
|
||||
wm withdraw .restore
|
||||
::itcl::delete object .restore
|
||||
archer_geometry_settle
|
||||
::gui::test::require {[archer_geometry_saved] eq $updated_geometry} \
|
||||
"closing a previously mapped window did not save its latest geometry"
|
||||
|
||||
archer_geometry_preferences
|
||||
Archer .default
|
||||
wm geometry .default $default_geometry
|
||||
wm deiconify .default
|
||||
archer_geometry_settle
|
||||
::gui::test::require {[wm geometry .default] eq $default_geometry} \
|
||||
"an empty geometry option reset the window to its layout size"
|
||||
wm withdraw .default
|
||||
::itcl::delete object .default
|
||||
archer_geometry_settle
|
||||
} message options]} {
|
||||
puts stderr $message
|
||||
if {[dict exists $options -errorinfo]} {
|
||||
puts stderr [dict get $options -errorinfo]
|
||||
}
|
||||
puts "FAIL: Archer window geometry regression"
|
||||
exit 1
|
||||
}
|
||||
|
||||
puts "PASS: Archer window geometry restoration and startup cancellation"
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# tab-width: 8
|
||||
# mode: Tcl
|
||||
# tcl-indent-level: 4
|
||||
# indent-tabs-mode: t
|
||||
# End:
|
||||
# ex: shiftwidth=4 tabstop=8
|
||||
@@ -72,17 +72,15 @@ set(archer_wizard_FILES
|
||||
)
|
||||
|
||||
if(BRLCAD_ENABLE_TCL)
|
||||
brlcad_adddata(archer_utility_FILES plugins/archer/Utility)
|
||||
brlcad_adddata(archer_wizard_FILES plugins/archer/Wizards)
|
||||
# Archer scans only the plugin category directories for registration scripts.
|
||||
# Keep class definitions in their subdirectories so they are not sourced twice.
|
||||
foreach(plugin_file IN LISTS archer_utility_FILES archer_wizard_FILES)
|
||||
get_filename_component(plugin_dir "${plugin_file}" DIRECTORY)
|
||||
file(RELATIVE_PATH plugin_dir "${CMAKE_CURRENT_SOURCE_DIR}/plugins" "${CMAKE_CURRENT_SOURCE_DIR}/${plugin_dir}")
|
||||
brlcad_adddata("${plugin_file}" "plugins/archer/${plugin_dir}")
|
||||
endforeach()
|
||||
brlcad_adddata(plugins/Commands/README plugins/archer/Command)
|
||||
brlcad_adddata(plugins/Core/README plugins/archer/Core)
|
||||
brlcad_adddata(plugins/Utility/attrGroupsDisplayUtilityP/AttrGroupsDisplayUtilityP.tcl plugins/archer/Utility/attrGroupsDisplayUtilityP)
|
||||
brlcad_adddata(plugins/Utility/botUtilityP/BotUtilityP.tcl plugins/archer/Utility/botUtilityP)
|
||||
brlcad_adddata(plugins/Utility/lodUtilityP/LODUtilityP.tcl plugins/archer/Utility/lodUtilityP)
|
||||
brlcad_adddata(plugins/Wizards/humanwizard/HumanWizard.tcl plugins/archer/Wizards/humanwizard)
|
||||
brlcad_adddata(plugins/Wizards/tankwizard/TankWizard.tcl plugins/archer/Wizards/tankwizard)
|
||||
brlcad_adddata(plugins/Wizards/tankwizard/images/tank.png plugins/archer/Wizards/tankwizardIA/images)
|
||||
brlcad_adddata(plugins/Wizards/tirewizard/TireWizard.tcl plugins/archer/Wizards/tirewizard)
|
||||
endif(BRLCAD_ENABLE_TCL)
|
||||
|
||||
set(
|
||||
|
||||
@@ -63,7 +63,6 @@ extern int gettimeofday(struct timeval *, void *);
|
||||
|
||||
static constexpr int64_t usec_per_sec = 1000000;
|
||||
static constexpr int64_t nsec_per_sec = 1000000000;
|
||||
static constexpr int64_t nsec_per_usec = 1000;
|
||||
#if defined(HAVE_GETPROCESSTIMES) || defined(HAVE_GETTHREADTIMES)
|
||||
static constexpr int64_t nsec_per_windows_tick = 100;
|
||||
#endif
|
||||
@@ -107,7 +106,7 @@ timer_rusage(const struct rusage *usage)
|
||||
+ (int64_t)usage->ru_stime.tv_sec * usec_per_sec
|
||||
+ (int64_t)usage->ru_stime.tv_usec;
|
||||
|
||||
return usec * nsec_per_usec;
|
||||
return usec * (nsec_per_sec / usec_per_sec);
|
||||
}
|
||||
|
||||
|
||||
@@ -149,7 +148,7 @@ static int64_t
|
||||
timer_mach_time_val(const time_value_t *time_val)
|
||||
{
|
||||
return ((int64_t)time_val->seconds * nsec_per_sec
|
||||
+ (int64_t)time_val->microseconds * nsec_per_usec);
|
||||
+ (int64_t)time_val->microseconds * (nsec_per_sec / usec_per_sec));
|
||||
}
|
||||
|
||||
static int64_t
|
||||
|
||||
@@ -247,19 +247,41 @@ rt_in_rpp(struct xray *rp,
|
||||
}
|
||||
|
||||
|
||||
/* A name alone cannot distinguish transformed instances of a solid. */
|
||||
static struct soltab *
|
||||
rt_find_solid_with_mat(const struct rt_i *rtip,
|
||||
const struct directory *dp, const mat_t mat)
|
||||
{
|
||||
struct soltab *stp;
|
||||
|
||||
RT_VISIT_ALL_SOLTABS_START(stp, (struct rt_i *)rtip) {
|
||||
if (stp->st_dp != dp)
|
||||
continue;
|
||||
const fastf_t *st_mat = stp->st_matp ?
|
||||
stp->st_matp : bn_mat_identity;
|
||||
if (bn_mat_is_equal(mat, st_mat, &rtip->rti_tol))
|
||||
return stp;
|
||||
} RT_VISIT_ALL_SOLTABS_END;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Traverse the passed tree using rt_db_internals to show the way
|
||||
* This function supports rt_bound_internal and is internal to librt
|
||||
* Traverse the original database tree while tracking member transforms.
|
||||
*
|
||||
* Returns -
|
||||
* 0 success
|
||||
* -1 failure (tree_min and tree_max may have been altered)
|
||||
* Returns 0 on success, -1 if no bounds can be computed.
|
||||
*/
|
||||
int
|
||||
rt_traverse_tree(struct rt_i *rtip, const union tree *tp, fastf_t *tree_min, fastf_t *tree_max)
|
||||
static int
|
||||
rt_traverse_tree_mat(struct rt_i *rtip, const union tree *tp,
|
||||
fastf_t *tree_min, fastf_t *tree_max,
|
||||
const mat_t mat)
|
||||
{
|
||||
vect_t r_min, r_max; /* rpp for right side of tree */
|
||||
|
||||
if (!tp)
|
||||
return -1;
|
||||
|
||||
RT_CK_TREE(tp);
|
||||
|
||||
switch (tp->tr_op) {
|
||||
@@ -269,6 +291,8 @@ rt_traverse_tree(struct rt_i *rtip, const union tree *tp, fastf_t *tree_min, fas
|
||||
const struct soltab *stp;
|
||||
|
||||
stp = tp->tr_a.tu_stp;
|
||||
if (!stp)
|
||||
return -1;
|
||||
RT_CK_SOLTAB(stp);
|
||||
if (stp->st_aradius <= 0) {
|
||||
bu_log("rt_traverse_tree: encountered dead solid '%s'\n",
|
||||
@@ -293,16 +317,20 @@ rt_traverse_tree(struct rt_i *rtip, const union tree *tp, fastf_t *tree_min, fas
|
||||
case OP_XOR:
|
||||
case OP_UNION:
|
||||
/* BINARY type -- expand to contain both */
|
||||
if (rt_traverse_tree(rtip, tp->tr_b.tb_left, tree_min, tree_max) < 0 ||
|
||||
rt_traverse_tree(rtip, tp->tr_b.tb_right, r_min, r_max) < 0)
|
||||
if (rt_traverse_tree_mat(rtip, tp->tr_b.tb_left,
|
||||
tree_min, tree_max, mat) < 0 ||
|
||||
rt_traverse_tree_mat(rtip, tp->tr_b.tb_right,
|
||||
r_min, r_max, mat) < 0)
|
||||
return -1;
|
||||
VMIN(tree_min, r_min);
|
||||
VMAX(tree_max, r_max);
|
||||
break;
|
||||
case OP_INTERSECT:
|
||||
/* BINARY type -- find common area only */
|
||||
if (rt_traverse_tree(rtip, tp->tr_b.tb_left, tree_min, tree_max) < 0 ||
|
||||
rt_traverse_tree(rtip, tp->tr_b.tb_right, r_min, r_max) < 0)
|
||||
if (rt_traverse_tree_mat(rtip, tp->tr_b.tb_left,
|
||||
tree_min, tree_max, mat) < 0 ||
|
||||
rt_traverse_tree_mat(rtip, tp->tr_b.tb_right,
|
||||
r_min, r_max, mat) < 0)
|
||||
return -1;
|
||||
/* min = largest min, max = smallest max */
|
||||
VMAX(tree_min, r_min);
|
||||
@@ -313,7 +341,8 @@ rt_traverse_tree(struct rt_i *rtip, const union tree *tp, fastf_t *tree_min, fas
|
||||
* rt_gettree's subtractor shaker may have already discarded a
|
||||
* disjoint B (and its soltab) from the prepared tree, while this
|
||||
* routine may be walking the original database tree. */
|
||||
if (rt_traverse_tree(rtip, tp->tr_b.tb_left, tree_min, tree_max) < 0)
|
||||
if (rt_traverse_tree_mat(rtip, tp->tr_b.tb_left,
|
||||
tree_min, tree_max, mat) < 0)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
@@ -324,6 +353,8 @@ rt_traverse_tree(struct rt_i *rtip, const union tree *tp, fastf_t *tree_min, fas
|
||||
case OP_DB_LEAF:
|
||||
{
|
||||
const struct soltab *stp;
|
||||
struct directory *dp;
|
||||
mat_t leaf_mat;
|
||||
|
||||
if (rtip == NULL) {
|
||||
bu_log("rt_traverse_tree: A valid rtip was not passed for calculating bounds of '%s'\n",
|
||||
@@ -331,60 +362,44 @@ rt_traverse_tree(struct rt_i *rtip, const union tree *tp, fastf_t *tree_min, fas
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Good to go */
|
||||
MAT_COPY(leaf_mat, mat);
|
||||
if (tp->tr_l.tl_mat)
|
||||
bn_mat_mul(leaf_mat, mat, tp->tr_l.tl_mat);
|
||||
|
||||
/* Attempt to get a solid pointer, will fail for combs */
|
||||
stp = rt_find_solid(rtip, tp->tr_l.tl_name);
|
||||
dp = db_lookup(rtip->rti_dbip, tp->tr_l.tl_name,
|
||||
LOOKUP_QUIET);
|
||||
if (dp == RT_DIR_NULL)
|
||||
return -1;
|
||||
|
||||
stp = rt_find_solid_with_mat(rtip, dp, leaf_mat);
|
||||
if (stp == NULL) {
|
||||
|
||||
/* It was a comb! get an internal format and
|
||||
* repeat the whole thing that got us here in the
|
||||
* 1st place
|
||||
*/
|
||||
/* Recurse through combinations using their original
|
||||
* trees. A primitive without a matching prepared
|
||||
* instance has no valid bounds. */
|
||||
struct rt_db_internal intern;
|
||||
struct directory *dp;
|
||||
struct rt_comb_internal *combp;
|
||||
|
||||
/* Get the directory pointer */
|
||||
if ((dp=db_lookup(rtip->rti_dbip, tp->tr_l.tl_name, LOOKUP_QUIET)) == RT_DIR_NULL) {
|
||||
bu_log("rt_traverse_tree: db_lookup(%s) failed", tp->tr_l.tl_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Why does recursion work with the internal
|
||||
* format ? The internal format does have the
|
||||
* boolean op for a comb in the tr_a.tu_op field
|
||||
* in the root node, even though it has no prims
|
||||
* at the leaves. So recursive calls to load the
|
||||
* prim further down the tree, will return the
|
||||
* correct bb as we are going through the proper
|
||||
* switch case in each step down the tree
|
||||
*/
|
||||
if (!rt_db_lookup_internal(rtip->rti_dbip, tp->tr_l.tl_name, &dp, &intern, LOOKUP_NOISY)) {
|
||||
bu_log("rt_traverse_tree: rt_db_lookup_internal(%s) failed to get the internal form",
|
||||
tp->tr_l.tl_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The passed rt_db_internal should be a comb,
|
||||
* prepare a rt_comb_internal
|
||||
*/
|
||||
if (intern.idb_minor_type == ID_COMBINATION) {
|
||||
combp = (struct rt_comb_internal *)intern.idb_ptr;
|
||||
} else {
|
||||
/* if it's not a comb, then something else is
|
||||
* cooking.
|
||||
*/
|
||||
bu_log("rt_traverse_tree: WARNING : rt_db_lookup_internal(%s) got the internal form of a primitive when it should not, the bounds may not be correct", tp->tr_l.tl_name);
|
||||
if (intern.idb_minor_type != ID_COMBINATION) {
|
||||
bu_log("rt_traverse_tree: no prepared instance"
|
||||
" for '%s'\n", tp->tr_l.tl_name);
|
||||
rt_db_free_internal(&intern);
|
||||
return -1;
|
||||
}
|
||||
|
||||
combp = (struct rt_comb_internal *)intern.idb_ptr;
|
||||
RT_CK_COMB(combp);
|
||||
/* further down the rabbit hole */
|
||||
if (rt_traverse_tree(rtip, combp->tree, tree_min, tree_max)) {
|
||||
bu_log("rt_traverse_tree: rt_bound_tree() failed\n");
|
||||
int ret = rt_traverse_tree_mat(rtip, combp->tree,
|
||||
tree_min, tree_max, leaf_mat);
|
||||
rt_db_free_internal(&intern);
|
||||
if (ret)
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/* Got a solid pointer, get bounds and return */
|
||||
RT_CK_SOLTAB(stp);
|
||||
@@ -408,13 +423,24 @@ rt_traverse_tree(struct rt_i *rtip, const union tree *tp, fastf_t *tree_min, fas
|
||||
}
|
||||
|
||||
case OP_NOP:
|
||||
/* Implies that this tree has nothing in it */
|
||||
break;
|
||||
/* An empty tree has no bounds to return. */
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rt_traverse_tree(struct rt_i *rtip, const union tree *tp,
|
||||
fastf_t *tree_min, fastf_t *tree_max)
|
||||
{
|
||||
mat_t mat;
|
||||
|
||||
MAT_IDN(mat);
|
||||
return rt_traverse_tree_mat(rtip, tp, tree_min, tree_max, mat);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
rt_bound_instance(point_t *bmin, point_t *bmax,
|
||||
struct directory *dp,
|
||||
@@ -472,7 +498,8 @@ rt_bound_internal(struct db_i *dbip, struct directory *dp,
|
||||
struct rt_db_internal intern;
|
||||
struct rt_comb_internal *combp;
|
||||
vect_t tree_min, tree_max;
|
||||
union tree *tp;
|
||||
const union tree *tp;
|
||||
union tree primitive_tree;
|
||||
|
||||
/* Initialize RPP bounds */
|
||||
VSETALL(rpp_min, MAX_FASTF);
|
||||
@@ -494,7 +521,8 @@ rt_bound_internal(struct db_i *dbip, struct directory *dp,
|
||||
|
||||
|
||||
if (!rt_db_lookup_internal(dbip, dp->d_namep, &dp, &intern, LOOKUP_NOISY)) {
|
||||
bu_exit(1, "rt_bound_internal: rt_db_lookup_internal(%s) failed to get the internal form", dp->d_namep);
|
||||
bu_log("rt_bound_internal: lookup failed for '%s'\n",
|
||||
dp->d_namep);
|
||||
rt_i_destroy(rtip);
|
||||
return -1;
|
||||
}
|
||||
@@ -504,26 +532,18 @@ rt_bound_internal(struct db_i *dbip, struct directory *dp,
|
||||
*/
|
||||
if (intern.idb_minor_type == ID_COMBINATION) {
|
||||
combp = (struct rt_comb_internal *)intern.idb_ptr;
|
||||
RT_CK_COMB(combp);
|
||||
tp = combp->tree;
|
||||
} else {
|
||||
/* A primitive was passed, construct a struct rt_comb_internal
|
||||
* with a single leaf node.
|
||||
*/
|
||||
BU_ALLOC(combp, struct rt_comb_internal);
|
||||
RT_COMB_INTERNAL_INIT(combp);
|
||||
combp->region_flag = 0;
|
||||
|
||||
BU_GET(tp, union tree);
|
||||
RT_TREE_INIT(tp);
|
||||
tp->tr_l.tl_op = OP_SOLID;
|
||||
tp->tr_l.tl_name = bu_strdup("dummy");
|
||||
tp->tr_l.tl_mat = (matp_t)NULL;
|
||||
tp->tr_a.tu_stp = rt_find_solid(rtip, dp->d_namep);
|
||||
combp->tree = tp;
|
||||
/* A primitive uses its prepared solid directly. */
|
||||
RT_TREE_INIT(&primitive_tree);
|
||||
primitive_tree.tr_l.tl_op = OP_SOLID;
|
||||
primitive_tree.tr_a.tu_stp = rt_find_solid(rtip, dp->d_namep);
|
||||
tp = &primitive_tree;
|
||||
}
|
||||
|
||||
RT_CK_COMB(combp);
|
||||
if (rt_traverse_tree(rtip, combp->tree, tree_min, tree_max)) {
|
||||
bu_log("rt_bound_internal: rt_bound_tree() failed\n");
|
||||
if (rt_traverse_tree(rtip, tp, tree_min, tree_max)) {
|
||||
bu_log("rt_bound_internal: tree traversal failed\n");
|
||||
rt_db_free_internal(&intern);
|
||||
rt_i_destroy(rtip);
|
||||
return -1;
|
||||
|
||||
@@ -72,10 +72,15 @@ brlcad_add_test(NAME rt_tree_prune COMMAND rt_tree_prune)
|
||||
|
||||
brlcad_addexec(rt_reprep_prune reprep_prune.c "librt;libwdb;libbu;${M_LIBRARY}" TEST)
|
||||
|
||||
brlcad_addexec(rt_rtcmp_capture rtcmp_capture.c "librt;libwdb;libbu;${M_LIBRARY}" TEST)
|
||||
brlcad_add_test(NAME rt_rtcmp_capture COMMAND rt_rtcmp_capture)
|
||||
brlcad_add_test(NAME rt_rtcmp_capture_primitives COMMAND rt_rtcmp_capture primitives)
|
||||
brlcad_add_test(NAME rt_reprep_prune COMMAND rt_reprep_prune)
|
||||
# Note - this feature is not available in a BRLCAD_ENABLE_RUNTIME_DEBUG=OFF
|
||||
# build, since it has an unavoidable performance overhead in the hot loop to
|
||||
# check if the setting is enabled.
|
||||
if (BRLCAD_ENABLE_RUNTIME_DEBUG)
|
||||
brlcad_addexec(rt_rtcmp_capture rtcmp_capture.c "librt;libwdb;libbu;${M_LIBRARY}" TEST)
|
||||
brlcad_add_test(NAME rt_rtcmp_capture COMMAND rt_rtcmp_capture)
|
||||
brlcad_add_test(NAME rt_rtcmp_capture_primitives COMMAND rt_rtcmp_capture primitives)
|
||||
brlcad_add_test(NAME rt_reprep_prune COMMAND rt_reprep_prune)
|
||||
endif()
|
||||
|
||||
brlcad_addexec(rt_submodel_xform submodel_xform.c "librt;libwdb;libbu;${M_LIBRARY}" TEST)
|
||||
brlcad_add_test(NAME rt_submodel_xform COMMAND rt_submodel_xform)
|
||||
@@ -212,36 +217,37 @@ brlcad_add_test(NAME rt_metaball_adjust COMMAND rt_metaball_adjust)
|
||||
set(
|
||||
distcheck_files
|
||||
CMakeLists.txt
|
||||
ars_inside.c
|
||||
arb_intersect.g
|
||||
ars_inside.c
|
||||
binary_attribute.c
|
||||
binunif.c
|
||||
brep_io.cpp
|
||||
bound_internal.c
|
||||
brep_boolean_tests.g
|
||||
brep_io.cpp
|
||||
crofton.c
|
||||
cyclic_tests.g
|
||||
datum_annot_semantics.c
|
||||
db_name.c
|
||||
default_object.c
|
||||
datum_annot_semantics.c
|
||||
dsp_raytrace_check.c
|
||||
dsp_sa_vol_check.c
|
||||
primitive_brep.cpp
|
||||
reprep_prune.c
|
||||
brep_boolean_tests.g
|
||||
cyclic_tests.g
|
||||
extreme_ssi_test.g
|
||||
invalid_inmem.c
|
||||
lcomb_large.c
|
||||
matrix_tests.g
|
||||
metaball_adjust.c
|
||||
nurbs_surfaces.g
|
||||
pnts_bounds.c
|
||||
prim_tess.c
|
||||
primitive_brep.cpp
|
||||
reprep_prune.c
|
||||
rt_datum.c
|
||||
rt_perturb.c
|
||||
rtcmp_capture.c
|
||||
search_stress.c
|
||||
static_init.cpp
|
||||
sketch.g
|
||||
static_init.cpp
|
||||
submodel_xform.c
|
||||
prim_tess.c
|
||||
pnts_bounds.c
|
||||
tess_timing.c
|
||||
tree_prune.c
|
||||
vds_tree.c
|
||||
|
||||
@@ -37,6 +37,7 @@ main(int UNUSED(argc), const char **argv)
|
||||
point_t bmin, bmax;
|
||||
point_t expected_min = {-1.0, -1.0, -1.0};
|
||||
point_t expected_max = { 1.0, 1.0, 1.0};
|
||||
mat_t translated;
|
||||
int ret = 1;
|
||||
|
||||
bu_setprogname(argv[0]);
|
||||
@@ -75,6 +76,68 @@ main(int UNUSED(argc), const char **argv)
|
||||
if (!VNEAR_EQUAL(bmax, expected_max, BN_TOL_DIST))
|
||||
goto done;
|
||||
|
||||
dp = db_lookup(dbip, "left.s", LOOKUP_QUIET);
|
||||
if (dp == RT_DIR_NULL || rt_bound_internal(dbip, dp, bmin, bmax))
|
||||
goto done;
|
||||
if (!VNEAR_EQUAL(bmin, expected_min, BN_TOL_DIST) ||
|
||||
!VNEAR_EQUAL(bmax, expected_max, BN_TOL_DIST))
|
||||
goto done;
|
||||
|
||||
BU_LIST_INIT(&wm.l);
|
||||
if (mk_comb(wdbp, "empty.c", &wm.l, 0, NULL, NULL, NULL,
|
||||
0, 0, 0, 0, 0, 0, 0))
|
||||
goto done;
|
||||
dp = db_lookup(dbip, "empty.c", LOOKUP_QUIET);
|
||||
if (dp == RT_DIR_NULL ||
|
||||
rt_bound_internal(dbip, dp, bmin, bmax) == 0)
|
||||
goto done;
|
||||
|
||||
BU_LIST_INIT(&wm.l);
|
||||
if (!mk_addmember("empty.c", &wm.l, NULL, WMOP_UNION))
|
||||
goto done;
|
||||
if (mk_lcomb(wdbp, "nested.c", &wm, 0, NULL, NULL, NULL, 0))
|
||||
goto done;
|
||||
dp = db_lookup(dbip, "nested.c", LOOKUP_QUIET);
|
||||
if (dp == RT_DIR_NULL ||
|
||||
rt_bound_internal(dbip, dp, bmin, bmax) == 0)
|
||||
goto done;
|
||||
|
||||
MAT_IDN(translated);
|
||||
MAT_DELTAS(translated, 20.0, 0.0, 0.0);
|
||||
BU_LIST_INIT(&wm.l);
|
||||
if (!mk_addmember("left.s", &wm.l, NULL, WMOP_UNION) ||
|
||||
!mk_addmember("left.s", &wm.l, translated, WMOP_UNION))
|
||||
goto done;
|
||||
if (mk_lcomb(wdbp, "instanced.r", &wm, 1, NULL, NULL, NULL, 0))
|
||||
goto done;
|
||||
dp = db_lookup(dbip, "instanced.r", LOOKUP_QUIET);
|
||||
if (dp == RT_DIR_NULL || rt_bound_internal(dbip, dp, bmin, bmax))
|
||||
goto done;
|
||||
VSET(expected_max, 21.0, 1.0, 1.0);
|
||||
if (!VNEAR_EQUAL(bmin, expected_min, BN_TOL_DIST) ||
|
||||
!VNEAR_EQUAL(bmax, expected_max, BN_TOL_DIST))
|
||||
goto done;
|
||||
|
||||
BU_LIST_INIT(&wm.l);
|
||||
if (!mk_addmember("left.s", &wm.l, translated, WMOP_UNION))
|
||||
goto done;
|
||||
if (mk_lcomb(wdbp, "child.c", &wm, 0, NULL, NULL, NULL, 0))
|
||||
goto done;
|
||||
MAT_DELTAS(translated, 10.0, 0.0, 0.0);
|
||||
BU_LIST_INIT(&wm.l);
|
||||
if (!mk_addmember("child.c", &wm.l, translated, WMOP_UNION))
|
||||
goto done;
|
||||
if (mk_lcomb(wdbp, "parent.r", &wm, 1, NULL, NULL, NULL, 0))
|
||||
goto done;
|
||||
dp = db_lookup(dbip, "parent.r", LOOKUP_QUIET);
|
||||
if (dp == RT_DIR_NULL || rt_bound_internal(dbip, dp, bmin, bmax))
|
||||
goto done;
|
||||
VSET(expected_min, 29.0, -1.0, -1.0);
|
||||
VSET(expected_max, 31.0, 1.0, 1.0);
|
||||
if (!VNEAR_EQUAL(bmin, expected_min, BN_TOL_DIST) ||
|
||||
!VNEAR_EQUAL(bmax, expected_max, BN_TOL_DIST))
|
||||
goto done;
|
||||
|
||||
ret = 0;
|
||||
|
||||
done:
|
||||
|
||||
@@ -85,6 +85,69 @@ proc exercise_object_lifecycle {class object args} {
|
||||
}
|
||||
}
|
||||
|
||||
proc exercise_panedwindow_bindings {} {
|
||||
set pane_size 200
|
||||
set drag_distance 20
|
||||
set native_motion_binding [bind Panedwindow <Motion>]
|
||||
|
||||
toplevel .panes
|
||||
foreach orientation {horizontal vertical} {
|
||||
set pane .panes.$orientation
|
||||
iwidgets::panedwindow $pane -orient $orientation \
|
||||
-width $pane_size -height $pane_size -showhandle 0
|
||||
$pane add first -minimum 0 -margin 0
|
||||
$pane add second -minimum 0 -margin 0
|
||||
pack $pane -side left -fill both -expand yes
|
||||
}
|
||||
|
||||
panedwindow .panes.native -width $pane_size -height $pane_size
|
||||
foreach name {first second} {
|
||||
frame .panes.native.$name
|
||||
.panes.native add .panes.native.$name
|
||||
}
|
||||
pack .panes.native -side left -fill both -expand yes
|
||||
update
|
||||
|
||||
# Hull events must not invoke native Tk handlers on Iwidgets objects.
|
||||
foreach pane {.panes.horizontal .panes.vertical .panes.native} {
|
||||
foreach event {
|
||||
<Motion> <Leave>
|
||||
<ButtonPress-1> <B1-Motion> <ButtonRelease-1>
|
||||
<ButtonPress-2> <B2-Motion> <ButtonRelease-2>
|
||||
} {
|
||||
event generate $pane $event -x 1 -y 1
|
||||
}
|
||||
update
|
||||
assert_equal "$pane pointer events" $::background_errors {}
|
||||
}
|
||||
assert_equal "native panedwindow motion binding" \
|
||||
[bind Panedwindow <Motion>] $native_motion_binding
|
||||
|
||||
# Removing the hull's class tag must retain Iwidgets' sash dragging.
|
||||
foreach orientation {horizontal vertical} {
|
||||
set pane .panes.$orientation
|
||||
set before [$pane fraction]
|
||||
set sash [$pane component sash1]
|
||||
set x 0
|
||||
set y 0
|
||||
if {$orientation eq "horizontal"} {
|
||||
set y $drag_distance
|
||||
} else {
|
||||
set x $drag_distance
|
||||
}
|
||||
event generate $sash <ButtonPress-1> -x 0 -y 0
|
||||
event generate $sash <B1-Motion> -x $x -y $y
|
||||
event generate $sash <B1-ButtonRelease-1> -x $x -y $y
|
||||
update
|
||||
if {[lindex [$pane fraction] 0] <= [lindex $before 0]} {
|
||||
fail "$orientation panedwindow sash did not move"
|
||||
}
|
||||
assert_equal "$orientation sash events" $::background_errors {}
|
||||
}
|
||||
destroy .panes
|
||||
update
|
||||
}
|
||||
|
||||
proc require_at_least {package minimum} {
|
||||
set version [package require $package $minimum]
|
||||
if {[package vcompare $version $minimum] < 0} {
|
||||
@@ -102,6 +165,7 @@ set tk_version [require_at_least Tk 8.6]
|
||||
set itcl_version [require_at_least Itcl 4.3.0]
|
||||
set itk_version [require_at_least Itk 4.2.3]
|
||||
set iwidgets_version [require_at_least Iwidgets 4.1.1]
|
||||
exercise_panedwindow_bindings
|
||||
interp alias {} Hierarchy {} ::iwidgets::Hierarchy
|
||||
interp alias {} scrolledlistbox {} ::iwidgets::scrolledlistbox
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ if(BRLCAD_ENABLE_TCL)
|
||||
if(TK_LIBRARY)
|
||||
target_compile_definitions(mged PRIVATE HAVE_TK=1)
|
||||
endif(TK_LIBRARY)
|
||||
target_include_directories(mged BEFORE PRIVATE ${MGED_INCLUDE_DIRS})
|
||||
brlcad_include_dirs(mged MGED_INCLUDE_DIRS PRIVATE)
|
||||
add_target_deps(mged Tkhtml Tktable itcl_pkgIndex itk_pkgIndex TclIndexBld dm_plugins)
|
||||
|
||||
# MGED needs the tclIndex and pkgIndex files set up correctly
|
||||
|
||||
@@ -425,6 +425,8 @@ mged_attach(struct mged_state *s, const char *wp_name, int argc, const char *arg
|
||||
{
|
||||
int opt_argc;
|
||||
char **opt_argv;
|
||||
const char *dm_name;
|
||||
const char *dm_lname;
|
||||
struct mged_dm *o_dm;
|
||||
|
||||
if (!wp_name) {
|
||||
@@ -495,8 +497,8 @@ mged_attach(struct mged_state *s, const char *wp_name, int argc, const char *arg
|
||||
mged_link_vars(s->mged_curr_dm);
|
||||
|
||||
Tcl_ResetResult(s->interp);
|
||||
const char *dm_name = dm_get_dm_name(DMP);
|
||||
const char *dm_lname = dm_get_dm_lname(DMP);
|
||||
dm_name = dm_get_dm_name(DMP);
|
||||
dm_lname = dm_get_dm_lname(DMP);
|
||||
if (dm_name && dm_lname) {
|
||||
Tcl_AppendResult(s->interp, "ATTACHING ", dm_name, " (", dm_lname, ")\n", (char *)NULL);
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ f_facedef(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[
|
||||
struct rt_arb_internal *arb;
|
||||
struct rt_arb_internal *arbo;
|
||||
plane_t planes[6];
|
||||
int arb_type;
|
||||
int status;
|
||||
struct bu_vls error_msg;
|
||||
|
||||
@@ -125,7 +126,7 @@ f_facedef(ClientData clientData, Tcl_Interp *interp, int argc, const char *argv[
|
||||
RT_ARB_CK_MAGIC(arb);
|
||||
|
||||
/* find new planes to account for any editing */
|
||||
int arb_type = rt_arb_std_type(&MEDIT(s)->es_int, MEDIT(s)->tol);
|
||||
arb_type = rt_arb_std_type(&MEDIT(s)->es_int, MEDIT(s)->tol);
|
||||
if (rt_arb_calc_planes(&error_msg, arb, arb_type, planes, &s->tol.tol)) {
|
||||
Tcl_AppendResult(interp, bu_vls_addr(&error_msg),
|
||||
"Unable to determine plane equations\n", (char *)NULL);
|
||||
|
||||
@@ -113,9 +113,6 @@ extern struct _mged_variables default_mged_variables;
|
||||
/* defined in color_scheme.c */
|
||||
extern struct _color_scheme default_color_scheme;
|
||||
|
||||
/* defined in grid.c */
|
||||
extern struct bv_grid_state default_grid_state;
|
||||
|
||||
/* defined in axes.c */
|
||||
extern struct _axes_state default_axes_state;
|
||||
|
||||
|
||||
@@ -575,6 +575,7 @@ void pr_beep(void);
|
||||
void pr_prompt(struct mged_state *s);
|
||||
|
||||
/* grid.c */
|
||||
extern struct bv_grid_state default_grid_state;
|
||||
extern void round_to_grid(struct mged_state *s, fastf_t *view_dx, fastf_t *view_dy);
|
||||
extern void snap_keypoint_to_grid(struct mged_state *s);
|
||||
extern void snap_view_center_to_grid(struct mged_state *s);
|
||||
|
||||
@@ -226,7 +226,7 @@ package provide Archer 1.0
|
||||
method buildViewAxesPreferences {}
|
||||
method doAboutArcher {}
|
||||
method doarcherHelp {}
|
||||
method handleMap {}
|
||||
method handleMap {_window}
|
||||
method handleBindingModeChange {_name1 _name2 _op}
|
||||
method overrideBindingMode {_mode}
|
||||
method updateOverrideBindingMode {_keysym}
|
||||
@@ -427,6 +427,7 @@ package provide Archer 1.0
|
||||
|
||||
private {
|
||||
variable mInstanceInit 1
|
||||
variable mWindowMapped 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,7 +529,7 @@ package provide Archer 1.0
|
||||
}
|
||||
|
||||
# resize and position window after it's drawn
|
||||
bind [namespace tail $this] <Map> [::itcl::code $this handleMap]
|
||||
bind [namespace tail $this] <Map> [::itcl::code $this handleMap %W]
|
||||
}
|
||||
|
||||
|
||||
@@ -4263,18 +4264,26 @@ proc title_node_handler {node} {
|
||||
|
||||
}
|
||||
|
||||
::itcl::body Archer::handleMap {} {
|
||||
if {$mWindowGeometry != ""} {
|
||||
after idle "wm geometry [namespace tail $this] $mWindowGeometry"
|
||||
} else {
|
||||
after idle "wm geometry [namespace tail $this] $itk_option(-geometry)"
|
||||
::itcl::body Archer::handleMap {_window} {
|
||||
# Child windows also dispatch Map events through the toplevel's tag.
|
||||
if {$_window ne [namespace tail $this]} {
|
||||
return
|
||||
}
|
||||
set mWindowMapped 1
|
||||
|
||||
set geometry $mWindowGeometry
|
||||
if {$geometry eq ""} {
|
||||
set geometry $itk_option(-geometry)
|
||||
}
|
||||
if {$geometry ne ""} {
|
||||
after idle [list wm geometry $_window $geometry]
|
||||
}
|
||||
|
||||
if {$mSeparateCommandWindow && $mCmdWindowGeometry != ""} {
|
||||
after idle [::itcl::code wm geometry $itk_component(sepcmdT) $mCmdWindowGeometry]
|
||||
after idle [list wm geometry $itk_component(sepcmdT) $mCmdWindowGeometry]
|
||||
}
|
||||
|
||||
bind [namespace tail $this] <Map> {}
|
||||
bind $_window <Map> {}
|
||||
}
|
||||
|
||||
::itcl::body Archer::handleDisplayEscape {_dm} {
|
||||
@@ -9351,7 +9360,17 @@ proc title_node_handler {node} {
|
||||
puts $_pfile "set mVPaneToggle3 $mVPaneToggle3"
|
||||
puts $_pfile "set mVPaneToggle5 $mVPaneToggle5"
|
||||
|
||||
puts $_pfile "set mWindowGeometry [winfo geometry [namespace tail $this]]"
|
||||
# Before the first map, the hull's size only reflects unfinished layout.
|
||||
if {$mWindowMapped} {
|
||||
if {$ArcherCore::inheritFromToplevel} {
|
||||
set mWindowGeometry [wm geometry [namespace tail $this]]
|
||||
} else {
|
||||
set mWindowGeometry [winfo geometry [namespace tail $this]]
|
||||
}
|
||||
}
|
||||
if {$mWindowGeometry ne ""} {
|
||||
puts $_pfile [list set mWindowGeometry $mWindowGeometry]
|
||||
}
|
||||
|
||||
if {$mSeparateCommandWindow} {
|
||||
puts $_pfile "set mCmdWindowGeometry [winfo geometry $itk_component(sepcmdT)]"
|
||||
|
||||
@@ -165,8 +165,7 @@ proc secErrorDialog {root title text default args} {
|
||||
update idletasks
|
||||
|
||||
# First frame consists of error icon and message
|
||||
frame $base.frame\#1 \
|
||||
-class Panedwindow
|
||||
frame $base.frame\#1
|
||||
pack $base.frame\#1 -fill x -anchor w
|
||||
|
||||
canvas $base.frame\#1.bitmap \
|
||||
|
||||
@@ -47,10 +47,11 @@ if { [info exists tk_strictMotif] == 0 } {
|
||||
|
||||
# MGED html manual directory search order precedence should be:
|
||||
# MGED_HTML_DIR
|
||||
# [bu_dir data]/html/manuals/mged
|
||||
# [bu_dir doc]/html/manuals/mged
|
||||
|
||||
if ![info exists mged_default(html_dir)] {
|
||||
set mged_default(html_dir) [file normalize [file join [bu_dir doc] html manuals mged]]
|
||||
set mged_default(html_dir) [file normalize [file join [bu_dir data] html manuals mged]]
|
||||
if {![file exists $mged_default(html_dir)]} {
|
||||
set mged_default(html_dir) [file normalize [file join [bu_dir doc] html manuals mged]]
|
||||
}
|
||||
|
||||