Skip to content

Commit 38c8cf4

Browse files
andyclaude
andcommitted
Merge wip/166-coin-port: ECCE_USE_COIN build option, off by default (#166 stage 1)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R9WkbXZ96rqCJxYuumcrgF
2 parents 8b5b877 + b2560c0 commit 38c8cf4

8 files changed

Lines changed: 128 additions & 17 deletions

File tree

‎CMakeLists.txt‎

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,27 @@ include_directories(
9292
${FREETYPE_UNQUALIFIED_INCLUDE_DIR}
9393
)
9494

95+
# #166: build against the system Coin3D instead of the
96+
# vendored Inventor core in src/inv. <inv/X/Y.H> includes are forwarded to
97+
# <Inventor/X/Y.h> by a generated overlay that is searched before include/.
98+
option(ECCE_USE_COIN "Build against Coin3D instead of the vendored Inventor core (#166; coexists with the vendored core until stage 4)" OFF)
99+
if(ECCE_USE_COIN)
100+
file(GLOB _coin_scan LIST_DIRECTORIES true ${CMAKE_SOURCE_DIR}/src/*)
101+
list(FILTER _coin_scan EXCLUDE REGEX "/src/inv$")
102+
file(GLOB _coin_scan_inc LIST_DIRECTORIES true ${CMAKE_SOURCE_DIR}/include/*)
103+
list(FILTER _coin_scan_inc EXCLUDE REGEX "/include/inv$")
104+
list(APPEND _coin_scan ${_coin_scan_inc})
105+
execute_process(COMMAND python3 ${CMAKE_SOURCE_DIR}/tools/coin/gen_shim.py
106+
${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}/coin-shim ${_coin_scan}
107+
RESULT_VARIABLE _shim_rc)
108+
if(NOT _shim_rc EQUAL 0)
109+
message(FATAL_ERROR "gen_shim.py failed")
110+
endif()
111+
include_directories(BEFORE ${CMAKE_BINARY_DIR}/coin-shim)
112+
add_compile_definitions(OIV_COIN)
113+
find_library(COIN_LIBRARY Coin REQUIRED)
114+
endif()
115+
95116
if(APPLE)
96117
# ~90 files across the tree spell OpenGL headers the Linux/X11 way
97118
# ("GL/gl.h", "GL/glu.h") -- Apple's own OpenGL framework headers live
@@ -222,21 +243,6 @@ else()
222243
set_property(TARGET eccercmd PROPERTY SOURCES ${_rcmd_srcs})
223244
endif()
224245
# --- src/inv -> libecceinv.a + libeccemoiv.a (libeccewxinv.a needs wx, TODO) ---
225-
ecce_library(ecceinv
226-
src/inv/dbelements
227-
src/inv/dbengines
228-
src/inv/dbfields
229-
src/inv/dbnodes
230-
src/inv/dbsb
231-
src/inv/dbso
232-
src/inv/dbupgraders
233-
src/inv/flclient
234-
src/inv/image
235-
src/inv/interaction
236-
src/inv/nodekits
237-
)
238-
target_compile_definitions(ecceinv PRIVATE NDEBUG)
239-
target_link_libraries(ecceinv PRIVATE OpenGL::GL OpenGL::GLU)
240246
# Old build's src/inv/flclient/Makefile adds `pkg-config --cflags-only-I freetype2`
241247
# on top of the baseline include dir: some FreeType headers (ft2build.h) live at
242248
# the top of the freetype2 include tree, others (ftoutln.h etc, used elsewhere in
@@ -249,8 +255,30 @@ find_path(FREETYPE_ROOT_INCLUDE_DIR ft2build.h
249255
if(NOT FREETYPE_ROOT_INCLUDE_DIR)
250256
message(FATAL_ERROR "FreeType's ft2build.h not found -- searched the usual Linux and Homebrew locations")
251257
endif()
252-
target_include_directories(ecceinv PRIVATE ${FREETYPE_ROOT_INCLUDE_DIR})
253-
258+
if(ECCE_USE_COIN)
259+
# Only the FreeType font layer (flclient) is kept from the vendored core.
260+
ecce_library(ecceinv src/inv/flclient)
261+
target_compile_definitions(ecceinv PRIVATE NDEBUG)
262+
target_include_directories(ecceinv PRIVATE ${FREETYPE_ROOT_INCLUDE_DIR})
263+
target_link_libraries(ecceinv PUBLIC ${COIN_LIBRARY} OpenGL::GL OpenGL::GLU)
264+
else()
265+
ecce_library(ecceinv
266+
src/inv/dbelements
267+
src/inv/dbengines
268+
src/inv/dbfields
269+
src/inv/dbnodes
270+
src/inv/dbsb
271+
src/inv/dbso
272+
src/inv/dbupgraders
273+
src/inv/flclient
274+
src/inv/image
275+
src/inv/interaction
276+
src/inv/nodekits
277+
)
278+
target_compile_definitions(ecceinv PRIVATE NDEBUG)
279+
target_link_libraries(ecceinv PRIVATE OpenGL::GL OpenGL::GLU)
280+
target_include_directories(ecceinv PRIVATE ${FREETYPE_ROOT_INCLUDE_DIR})
281+
endif()
254282
ecce_library(eccemoiv src/inv/moiv)
255283
target_compile_definitions(eccemoiv PRIVATE NDEBUG)
256284
target_link_libraries(eccemoiv PRIVATE OpenGL::GL OpenGL::GLU)

‎GETTING_STARTED.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ generator (Unix Makefiles on Debian) instead of Ninja, which still builds
3333
but via `make`, not the `ninja` command used everywhere else in this
3434
document.
3535

36+
Optional (#166, experimental): `cmake -G Ninja -DECCE_USE_COIN=ON ..` builds
37+
the 3D viewer stack against the system Coin3D (`libcoin-dev` 4.0.x on Debian)
38+
instead of the vendored Open Inventor core; the default (OFF) is unchanged.
39+
Use a separate build directory (e.g. `build-coin`) so both configurations can
40+
be built from one tree, and have CI build both while the two coexist.
41+
3642
This produces the 19 GUI apps (`gateway`, `organizer`, `builder`,
3743
`pertable`, ...) plus the CLI apps, all statically linked against the
3844
in-tree libraries.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
type: map
3+
title: "ECCE_USE_COIN builds the viewer stack against Coin3D; both builds coexist until stage 4"
4+
area: wx-viewer
5+
paths: [CMakeLists.txt, tools/coin/gen_shim.py, include/inv/ChemKit/ChemDisplay.H, include/inv/SoWx/SoWxViewer.H, src/inv/wxinv/SoWxRenderArea.C]
6+
issues: [166]
7+
---
8+
`cmake -DECCE_USE_COIN=ON` (default OFF) does not compile the vendored
9+
Inventor core in `src/inv` (`db*`, `image`, `interaction`, `nodekits`).
10+
`ecceinv` shrinks to `src/inv/flclient` (our FreeType font layer) plus
11+
`libCoin`; `moiv`, `wxinv`, `src/viz`, `src/wxviz` and the apps build
12+
unchanged otherwise. `<inv/X/Y.H>` includes are forwarded to
13+
`<Inventor/X/Y.h>` by an overlay that `tools/coin/gen_shim.py` writes into
14+
`<build>/coin-shim` at configure time and that is searched before
15+
`include/`; `OIV_COIN` is defined. `inv/ChemKit`, `inv/SoWx` and
16+
`inv/flclient.h` stay ours.
17+
18+
Header fixes are portable and work in both builds: `ChemDisplay.H`
19+
includes Coin's `SoTextureCoordinateElement.h` (a typedef in Coin, so it
20+
cannot be forward-declared) and `SoWxViewer.H`/`SoWxRenderArea.C` include
21+
`SbLinear.h`/`SbColor.h`, which Coin's headers do not pull in transitively.
22+
23+
Why both exist: the vendored core is still the shipped, tested viewer; the
24+
Coin build is validated side by side (stage 2 onwards) and the vendored
25+
core is removed only at stage 4. Use separate build directories
26+
(`build-cmake`, `build-coin`): switching the option in one tree rebuilds
27+
everything. After a change under `src/inv/moiv`, `src/inv/wxinv` or
28+
`include/inv/{ChemKit,SoWx}`, build both.

‎docs/claude/wx-viewer/index.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Read this before changing any dialog, panel, sizer, grid, ewx control or the Ope
1212
### wxWidgets 3.2/GTK3, the 3D viewer, and C++ pitfalls
1313

1414
- [Open Inventor's redraw sensor is a ONE-SHOT that re-arms on render, and with a render callback installed nothing re-arms it](open-inventors-redraw-sensor-is-a-one.md)
15+
- [`ECCE_USE_COIN` builds the viewer stack against Coin3D; both builds coexist until stage 4](ecce-use-coin-builds-the-viewer-against-coin3d.md)
1516
- [wx3.2/GTK3 layout reentrancy](wx3-2-gtk3-layout-reentrancy.md)
1617
- [`wxGrid::CreateGrid()`/`SetTable()` synchronously fires `wxEVT_GRID_SELECT_CELL`](wxgrid-creategrid-settable-synchronously-fires-wxevt-grid.md)
1718
- [The `.pjd` (DialogBlocks) files are reference only; never regenerate code from them](the-pjd-dialogblocks-files-are-reference-only.md)

‎include/inv/ChemKit/ChemDisplay.H‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ class ChemBondStuff;
106106
class ChemUnitCylinder;
107107
class ChemUnitSphere;
108108
class SoClipPlaneElement;
109+
#ifdef OIV_COIN
110+
#include <Inventor/elements/SoTextureCoordinateElement.h> // a typedef in Coin
111+
#else
109112
class SoTextureCoordinateElement;
113+
#endif
110114
// --> CAstick
111115
class ChemResidueStuff;
112116
class ChemData;

‎include/inv/SoWx/SoWxViewer.H‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
#include <X11/Intrinsic.h>
1111

1212
#include "inv/SoType.H"
13+
#ifdef OIV_COIN
14+
#include <Inventor/SbLinear.h> // Coin headers do not pull this in transitively
15+
#endif
1316
#include "inv/SbTime.H"
1417

1518
#define ID_VIEWER 1000000

‎src/inv/wxinv/SoWxRenderArea.C‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
#include "inv/actions/SoGLRenderAction.H"
33
#include "inv/elements/SoWindowElement.H"
44

5+
#ifdef OIV_COIN
6+
#include <Inventor/SbColor.h>
7+
#endif
58
#include "inv/SoWx/SoWx.H"
69
#include "inv/SoWx/SoWxRenderArea.H"
710
#include "inv/SoWx/SoWxViewer.H"

‎tools/coin/gen_shim.py‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env python3
2+
"""Build an include overlay that maps SGI-style <inv/X/Y.H> includes onto
3+
Coin's <Inventor/X/Y.h>. Headers Coin lacks become empty stubs and are
4+
listed in missing.txt. inv/ChemKit comes from the tree (moiv's own)."""
5+
import os, re, sys
6+
root, out = sys.argv[1], sys.argv[2]
7+
coin = "/usr/include/Inventor"
8+
scan = [os.path.join(root, d) for d in ("src/inv/moiv", "src/inv/wxinv", "include/inv/ChemKit", "include/inv/SoWx")]
9+
# extra roots to scan (headers outside src/inv that include inv/)
10+
scan += sys.argv[3:]
11+
pat = re.compile(r'^\s*#\s*include\s+[<"](inv/[^>"]+)[>"]', re.M)
12+
seen = set()
13+
for d in scan:
14+
for dp, _, fs in os.walk(d):
15+
for f in fs:
16+
if f.endswith(('.C', '.H', '.h', '.c', '.cpp', '.inc')):
17+
try: txt = open(os.path.join(dp, f), errors='replace').read()
18+
except OSError: continue
19+
for m in pat.finditer(txt): seen.add(m.group(1))
20+
missing = []
21+
for inc in sorted(seen):
22+
if inc.startswith(("inv/ChemKit/", "inv/SoWx/")) or inc == "inv/flclient.h": continue
23+
rel = inc[len("inv/"):]
24+
base = re.sub(r'\.[Hh]$', '', rel)
25+
target = os.path.join(out, "inv", rel)
26+
os.makedirs(os.path.dirname(target), exist_ok=True)
27+
c = "Inventor/" + base + ".h"
28+
if os.path.exists(os.path.join("/usr/include", c)):
29+
open(target, "w").write('#include <%s>\n' % c)
30+
else:
31+
open(target, "w").write('/* not in Coin: %s */\n' % inc)
32+
missing.append(inc)
33+
os.makedirs(os.path.join(out, "inv"), exist_ok=True)
34+
for n in ("ChemKit", "SoWx", "flclient.h"): # ours, taken from the tree
35+
ck = os.path.join(out, "inv", n)
36+
if not os.path.exists(ck): os.symlink(os.path.join(root, "include/inv", n), ck)
37+
open(os.path.join(out, "missing.txt"), "w").write("\n".join(missing) + "\n")
38+
print(len(seen), "inv/ includes,", len(missing), "not in Coin")

0 commit comments

Comments
 (0)