-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdemo-mesh-native-toolkit.sh
More file actions
executable file
·355 lines (307 loc) · 10.5 KB
/
Copy pathdemo-mesh-native-toolkit.sh
File metadata and controls
executable file
·355 lines (307 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
#!/bin/bash
set -e
echo "=== Terrain Intelligence Generator - Native Toolkit Mesh Demo ==="
echo ""
echo "This demo shows how to use the vicar-native-toolkit for native-looking"
echo "VICAR commands that transparently execute inside Docker."
echo ""
# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TOOLKIT_DIR="$SCRIPT_DIR/vicar-native-toolkit"
WORKSPACE="$TOOLKIT_DIR/workspace"
IMAGE="ghcr.io/nasa-ammos/tig/terrain-intelligence-generator:opensource"
# Parse arguments
STEREO_LEFT=""
STEREO_RIGHT=""
TEXTURE_FILE=""
print_usage() {
echo "Usage: $0 --stereo-left FILE --stereo-right FILE [--texture FILE]"
echo ""
echo "Options:"
echo " --stereo-left FILE Left stereo image (required)"
echo " --stereo-right FILE Right stereo image (required)"
echo " --texture FILE Texture image (optional, defaults to right stereo)"
echo ""
echo "Example:"
echo " $0 --stereo-left left.VIC --stereo-right right.VIC"
echo ""
echo "Requirements:"
echo " - direnv installed and configured"
echo " - MARS calibration files available"
echo " - Stereo images must be from same acquisition (matching SCLK)"
exit 1
}
while [[ $# -gt 0 ]]; do
case $1 in
--stereo-left)
[ -z "$2" ] && { echo "ERROR: --stereo-left requires a FILE argument"; print_usage; }
STEREO_LEFT="$2"
shift 2
;;
--stereo-right)
[ -z "$2" ] && { echo "ERROR: --stereo-right requires a FILE argument"; print_usage; }
STEREO_RIGHT="$2"
shift 2
;;
--texture)
[ -z "$2" ] && { echo "ERROR: --texture requires a FILE argument"; print_usage; }
TEXTURE_FILE="$2"
shift 2
;;
--help|-h)
print_usage
;;
*)
echo "ERROR: Unknown option: $1"
print_usage
;;
esac
done
# Validate inputs
if [ -z "$STEREO_LEFT" ]; then
echo "ERROR: --stereo-left is required"
print_usage
fi
if [ -z "$STEREO_RIGHT" ]; then
echo "ERROR: --stereo-right is required"
print_usage
fi
# Check prerequisites
echo "Checking prerequisites..."
echo ""
# Check direnv
if ! command -v direnv &> /dev/null; then
echo "ERROR: direnv not installed"
echo ""
echo "Install direnv:"
echo " Ubuntu/Debian: sudo apt install direnv"
echo " macOS: brew install direnv"
echo " Fedora: sudo dnf install direnv"
echo ""
echo "Then add to shell profile:"
echo " bash: echo 'eval \"\$(direnv hook bash)\"' >> ~/.bashrc"
echo " zsh: echo 'eval \"\$(direnv hook zsh)\"' >> ~/.zshrc"
exit 1
fi
# Check Docker
if ! command -v docker &> /dev/null; then
echo "ERROR: docker not installed"
exit 1
fi
# Check toolkit directory
if [ ! -d "$TOOLKIT_DIR" ]; then
echo "ERROR: vicar-native-toolkit not found at: $TOOLKIT_DIR"
exit 1
fi
echo "✓ Prerequisites met"
echo ""
# Configure MARS calibration if available
if [ -f "$SCRIPT_DIR/find-calibration.sh" ]; then
source "$SCRIPT_DIR/find-calibration.sh"
CALIB_DIR=$(find_calibration)
if [ $? -eq 0 ] && verify_calibration "$CALIB_DIR"; then
# Create config for toolkit with java-vicario image
cat > "$TOOLKIT_DIR/.envrc.local" << EOF
# Auto-generated by demo-mesh-native-toolkit.sh
export MARS_CONFIG_PATH="$CALIB_DIR"
export CONTAINER_IMAGE="$IMAGE"
EOF
echo "✓ MARS calibration configured: $CALIB_DIR"
else
echo "⚠ WARNING: MARS calibration not found (required for stereo processing)"
if [ -n "$STEREO_LEFT" ]; then
echo "ERROR: Cannot process stereo pair without calibration"
print_calibration_help
exit 1
fi
fi
else
echo "⚠ WARNING: find-calibration.sh not found"
fi
# Ensure workspace exists
mkdir -p "$WORKSPACE"
# Resolve input file paths to absolute paths before changing directory
if [ -n "$TEXTURE_FILE" ]; then
TEXTURE_FILE="$(cd "$(dirname "$TEXTURE_FILE")" && pwd)/$(basename "$TEXTURE_FILE")"
fi
if [ -n "$STEREO_LEFT" ]; then
STEREO_LEFT="$(cd "$(dirname "$STEREO_LEFT")" && pwd)/$(basename "$STEREO_LEFT")"
fi
if [ -n "$STEREO_RIGHT" ]; then
STEREO_RIGHT="$(cd "$(dirname "$STEREO_RIGHT")" && pwd)/$(basename "$STEREO_RIGHT")"
fi
# Step 0: Activate toolkit
echo ""
echo "Step 0: Activating VICAR Native Toolkit..."
echo " This starts the vicar-sidecar container and generates command wrappers"
echo ""
cd "$TOOLKIT_DIR"
# Trust the toolkit directory. Writing .envrc.local above invalidates any prior
# `direnv allow`, so re-allow here to guarantee a reliable first run.
direnv allow . 2>/dev/null || true
# Load direnv environment
# Note: If direnv is blocked, the stderr will contain "is blocked" message
DIRENV_STDERR=$(mktemp)
DIRENV_OUTPUT=$(direnv export bash 2>"$DIRENV_STDERR")
if grep -q "is blocked" "$DIRENV_STDERR"; then
echo "⚠ direnv not allowed for this directory"
echo ""
echo "Run this command to trust the toolkit directory:"
echo " cd $TOOLKIT_DIR && direnv allow"
echo ""
echo "Then re-run this demo script."
rm -f "$DIRENV_STDERR"
exit 1
fi
# Show direnv messages to user
cat "$DIRENV_STDERR"
rm -f "$DIRENV_STDERR"
# Apply direnv environment
eval "$DIRENV_OUTPUT"
echo "✓ Toolkit activated"
echo ""
# Verify toolkit commands available
if ! command -v marsmesh &> /dev/null; then
echo "ERROR: VICAR commands not found in PATH"
echo "This usually means the toolkit activation failed"
exit 1
fi
echo "Available VICAR commands:"
echo " marsmesh, marsxyz, marscorr, marscor3, marsrfilt, vicario, gen, label, ..."
echo ""
# Copy input files to workspace
cd workspace
# Process stereo pair to generate XYZ
echo "Step 1: Processing stereo pair to generate XYZ..."
echo " WARNING: This takes 10+ minutes for full-resolution images"
echo ""
# Validate files exist
if [ ! -f "$STEREO_LEFT" ]; then
echo "ERROR: Left stereo file not found: $STEREO_LEFT"
exit 1
fi
if [ ! -f "$STEREO_RIGHT" ]; then
echo "ERROR: Right stereo file not found: $STEREO_RIGHT"
exit 1
fi
# Copy stereo pair to workspace
cp "$STEREO_LEFT" left.vic
cp "$STEREO_RIGHT" right.vic
echo " ✓ Stereo pair copied"
# Step 1a: Stereo correlation (disparity map)
echo ""
echo " Step 1a: Running stereo correlation..."
echo " Note: Commands look native but execute in Docker container!"
echo ""
echo " Running initial correlation (marscorr)..."
marscorr \( left.vic right.vic \) disparity_init.img template=15 search=51 quality=0.2 2>&1 | \
grep -E "tiepoints gathered|Seed point" | tail -3 || true
if [ ! -f disparity_init.img ]; then
echo " ❌ ERROR: marscorr failed to generate disparity_init.img"
exit 1
fi
echo " ✓ Initial disparity generated"
echo " Running refinement (marscor3)..."
marscor3 \( left.vic right.vic \) disparity.img in_disp=disparity_init.img template=11 search=31 quality=0.4 -omp_on 2>&1 | \
grep -E "tiepoints|Pyramid|Zooming" | tail -3 || true
if [ ! -f disparity.img ]; then
echo " ❌ ERROR: marscor3 failed to generate disparity.img"
exit 1
fi
echo " ✓ Disparity map generated"
# Step 1b: Generate XYZ from disparity
echo ""
echo " Step 1b: Generating XYZ point cloud (marsxyz)..."
marsxyz \( left.vic right.vic \) pointcloud.xyz disp=disparity.img \
error=10.0 abserr=0.15 lined=100 avgline=50 zlimit=\(-300,300\) spike_range=0.04 outlier=0.5 2>&1 | \
grep -E "Successfully|valid|rejected|XYZ" | tail -10 || true
if [ ! -f pointcloud.xyz ]; then
echo " ❌ ERROR: marsxyz failed to generate pointcloud.xyz"
exit 1
fi
echo " ✓ XYZ point cloud generated"
# Step 1c: Filter rover hardware from XYZ
echo ""
echo " Step 1c: Filtering rover hardware (marsrfilt)..."
marsrfilt inp=pointcloud.xyz out=pointcloud_filtered.xyz 2>&1 | \
grep -E "MARSRFILT|Version|Filtering|points|removed" || true
if [ ! -f pointcloud_filtered.xyz ]; then
echo " ⚠ WARNING: marsrfilt failed, using unfiltered XYZ"
cp pointcloud.xyz pointcloud_filtered.xyz
else
echo " ✓ Rover hardware filtered"
fi
# Use right image as texture (or custom texture if provided)
if [ -n "$TEXTURE_FILE" ]; then
cp "$TEXTURE_FILE" texture.img
else
cp "$STEREO_RIGHT" texture.img
fi
echo ""
echo "Step 2: Generating 3D mesh (marsmesh)..."
echo " Command executes in Docker but looks like a native binary!"
echo ""
marsmesh inp=pointcloud_filtered.xyz out=terrain.obj in_skin=texture.img \
x_subsample=1 y_subsample=1 \
range_min=0.2 range_mid=100 range_max=100 \
lod_levels=10 max_angle=87.5 \
res_min=3000 res_max=500000 density=1 -adaptive \
maxgap=5 2>&1 | \
grep -E "MARSMESH|Version|mesh|triangles|vertices|Writing|LOD|decimat" || true
if [ ! -f terrain.obj ]; then
echo "❌ ERROR: marsmesh failed to generate terrain.obj"
exit 1
fi
echo "✓ Mesh generated: terrain.obj"
echo ""
# Convert texture using vicario wrapper
echo "Step 3: Converting texture to PNG (vicario)..."
# Note: vicario may show Java warnings but successfully produces output
vicario texture.img texture.png 2>&1 | grep -E "Image write Done|JConvertIIO|inp =|out =|format =|oform =|rescale ="
if [ -f texture.png ]; then
echo "✓ Texture converted: texture.png"
else
echo "⚠ Texture conversion failed"
echo " Using original texture.img instead"
fi
echo ""
# List results
echo "Step 4: Results summary"
if [ -f texture.png ]; then
ls -lh pointcloud_filtered.xyz terrain.obj terrain.mtl texture.png 2>/dev/null
else
ls -lh pointcloud_filtered.xyz terrain.obj terrain.mtl texture.img 2>/dev/null
fi
echo ""
echo "=== Demo Complete ==="
echo ""
echo "Generated files in: $WORKSPACE"
echo " - pointcloud_filtered.xyz: Filtered point cloud"
echo " - terrain.obj : 3D mesh (Wavefront OBJ)"
echo " - terrain.mtl : Material file"
if [ -f texture.png ]; then
echo " - texture.png : Texture image"
else
echo " - texture.img : Texture image (VICAR format)"
fi
echo ""
echo "Key advantages of vicar-native-toolkit:"
echo " ✓ Commands look native: 'marsmesh ...' instead of 'docker exec ...'"
echo " ✓ Persistent container: No startup/cleanup overhead"
echo " ✓ Auto-discovery: All 200+ VICAR commands available"
echo " ✓ Transparent paths: Works from current directory"
echo ""
echo "To view the mesh:"
echo " - Blender: File → Import → Wavefront (.obj)"
echo " - MeshLab: File → Import Mesh → terrain.obj"
echo " - CloudCompare: File → Open → terrain.obj"
echo " - Online: Upload to https://3dviewer.net/"
echo ""
echo "Toolkit commands:"
echo " toolkit-status : Show container status"
echo " toolkit-shell : Open bash shell in container"
echo " toolkit-verify-calib: Check MARS calibration"
echo " toolkit-stop : Stop and remove container"
echo ""
echo "The vicar-sidecar container remains running for future use."
echo "To stop it: cd $TOOLKIT_DIR && toolkit-stop"