Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 27 additions & 16 deletions .github/workflows/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
# Based on old ubuntu to create more compatible binaries
# Based on manylinux_2_28 (AlmaLinux 8, GLIBC 2.28) for maximum HPC compatibility
# Binaries built here will run on RHEL/Rocky/Alma 8+, Ubuntu 20.04+, and most HPC clusters

# To build (e.g. for ShapeWorks 6.7):
# docker build --progress=plain -t akenmorris/ubuntu-build-box-jammy-sw67 .
# docker build --progress=plain -t akenmorris/manylinux-build-box-sw67 .
# To publish:
# docker push akenmorris/ubuntu-build-box-jammy-sw67
# docker push akenmorris/manylinux-build-box-sw67

FROM ubuntu:jammy-20250819 AS env
MAINTAINER akenmorris@gmail.com
FROM quay.io/pypa/manylinux_2_28_x86_64 AS env
LABEL maintainer="akenmorris@gmail.com"

# Set environment variables
ENV PATH=/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV PATH=/opt/rh/gcc-toolset-13/root/usr/bin:/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

ARG DEBIAN_FRONTEND=noninteractive
ENV TZ=Etc/UTC
# Enable PowerTools repo for additional development packages
RUN dnf install -y dnf-plugins-core && dnf config-manager --set-enabled powertools

# Update
RUN apt-get update -y && apt-get upgrade -y && apt-get dist-upgrade -y && apt-get install build-essential software-properties-common -y && add-apt-repository ppa:ubuntu-toolchain-r/test -y && apt-get update -y
# Update and install build tools
# gcc-toolset-13 provides GCC 13 with GLIBCXX_3.4.31, required by conda Qt5/ICU packages.
# This keeps GLIBC 2.28 for binary compatibility while providing modern C++ library symbols.
RUN dnf update -y && dnf groupinstall -y "Development Tools" \
&& dnf install -y gcc-toolset-13-gcc gcc-toolset-13-gcc-c++ gcc-toolset-13-binutils gcc-toolset-13-libstdc++-devel

# Install git and git-lfs
RUN add-apt-repository ppa:git-core/ppa
RUN apt-get update
RUN apt-get install git curl -y
RUN curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash
RUN apt-get install git-lfs -y
RUN dnf install -y git curl
RUN curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.rpm.sh | bash
RUN dnf install -y git-lfs

# Install other dependencies
RUN apt-get install rsync freeglut3-dev libgl1-mesa-dev libegl1-mesa zip libcups2 pigz wget ccache -y
RUN dnf install -y rsync freeglut-devel mesa-libGL-devel mesa-libEGL-devel zip cups-libs pigz wget ccache

# Install conda
RUN curl https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -o /tmp/Miniconda3-latest-Linux-x86_64.sh \
Expand All @@ -38,6 +40,15 @@ RUN curl https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -
&& echo ". /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc \
&& echo "conda activate base" >> ~/.bashrc

# Install modern libstdc++ with GLIBCXX_3.4.30+ required by conda Qt5/ICU packages
# gcc-toolset-13 only provides static libstdc++, so we use conda-forge's libstdcxx-ng
RUN /opt/conda/bin/conda install -y -c conda-forge libstdcxx-ng=13 \
&& LIBSTDCXX=$(ls /opt/conda/lib/libstdc++.so.6.0.* | head -1) \
&& cp -f "$LIBSTDCXX" /usr/lib64/ \
&& rm -f /usr/lib64/libstdc++.so.6 \
&& ln -s $(basename "$LIBSTDCXX") /usr/lib64/libstdc++.so.6 \
&& ldconfig

# Get and decompress linuxdeployqt, it's complicated to use fuse with docker due to the kernel module
RUN curl -L -o $HOME/linuxdeployqt.AppImage https://github.com/probonopd/linuxdeployqt/releases/download/5/linuxdeployqt-5-x86_64.AppImage && chmod +x $HOME/linuxdeployqt.AppImage ; cd $HOME ; ./linuxdeployqt.AppImage --appimage-extract
RUN ln -s /root/squashfs-root/usr/bin/linuxdeployqt /usr/bin
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/build-linux-debug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
build:

runs-on: ubuntu-latest
container: akenmorris/ubuntu-build-box-jammy-sw67
container: akenmorris/manylinux-build-box-sw67

steps:

Expand Down Expand Up @@ -66,7 +66,7 @@ jobs:
uses: actions/cache/restore@v3
with:
path: /github/home/install
key: ${{ runner.os }}-deps-debug-${{ hashFiles('.github/workflows/gha_deps.sh', 'install_shapeworks.sh', 'python_requirements.txt', 'build_dependencies.sh') }}
key: ${{ runner.os }}-deps-debug-${{ hashFiles('.github/workflows/Dockerfile', '.github/workflows/gha_deps.sh', 'install_shapeworks.sh', 'python_requirements.txt', 'build_dependencies.sh') }}

- name: Check space3.5
run: df -h
Expand Down Expand Up @@ -107,7 +107,7 @@ jobs:
uses: actions/cache/save@v3
with:
path: /github/home/install
key: ${{ runner.os }}-deps-debug-${{ hashFiles('.github/workflows/gha_deps.sh', 'install_shapeworks.sh', 'python_requirements.txt', 'build_dependencies.sh') }}
key: ${{ runner.os }}-deps-debug-${{ hashFiles('.github/workflows/Dockerfile', '.github/workflows/gha_deps.sh', 'install_shapeworks.sh', 'python_requirements.txt', 'build_dependencies.sh') }}

- name: Check space5
run: df -h
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
build:

runs-on: ubuntu-latest
container: akenmorris/ubuntu-build-box-jammy-sw67
container: akenmorris/manylinux-build-box-sw67

steps:

Expand Down Expand Up @@ -64,7 +64,7 @@ jobs:
uses: actions/cache/restore@v3
with:
path: /github/home/install
key: ${{ runner.os }}-deps-${{ hashFiles('.github/workflows/gha_deps.sh', 'install_shapeworks.sh', 'python_requirements.txt', 'build_dependencies.sh') }}
key: ${{ runner.os }}-deps-${{ hashFiles('.github/workflows/Dockerfile', '.github/workflows/gha_deps.sh', 'install_shapeworks.sh', 'python_requirements.txt', 'build_dependencies.sh') }}

- name: try import vtk
shell: bash -l {0}
Expand All @@ -81,7 +81,7 @@ jobs:
uses: actions/cache/save@v3
with:
path: /github/home/install
key: ${{ runner.os }}-deps-${{ hashFiles('.github/workflows/gha_deps.sh', 'install_shapeworks.sh', 'python_requirements.txt', 'build_dependencies.sh') }}
key: ${{ runner.os }}-deps-${{ hashFiles('.github/workflows/Dockerfile', '.github/workflows/gha_deps.sh', 'install_shapeworks.sh', 'python_requirements.txt', 'build_dependencies.sh') }}

- name: Check space4
run: df -h
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/gha_conda.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ else
cd ${GITHUB_WORKSPACE}

# run install
source ./install_shapeworks.sh --developer
source ./install_shapeworks.sh --developer || exit 1
conda clean -p -t -y
pip cache info
pip cache purge
Expand Down
3 changes: 2 additions & 1 deletion Libs/Python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pybind11_add_module(shapeworks_py
# NO_EXTRAS disables LTO which can cause GCC internal compiler errors
pybind11_add_module(shapeworks_py NO_EXTRAS
ShapeworksPython.cpp
PythonAnalyze.cpp
PythonGroom.cpp
Expand Down
13 changes: 12 additions & 1 deletion Python/shapeworks/shapeworks/network_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import trimesh
import itertools
import open3d as o3d
import scipy
import spm1d
import vtk
Expand All @@ -19,6 +18,8 @@
import shapeworks as sw
np.random.seed(0)

# open3d is imported lazily when needed (not available on all platforms)


class NetworkAnalysis:
def __init__(self, project):
Expand Down Expand Up @@ -85,6 +86,16 @@ def compute_mean_shape(self):
return mesh_points, mesh_normals, mean_shape, surface

def run(self):
# Import open3d here (lazy import - not available on all platforms)
try:
import open3d as o3d
except ImportError:
raise ImportError(
"open3d is required for network analysis but is not installed. "
"This feature may not be available on your platform/Python version. "
"Try: pip install open3d-cpu (Linux) or pip install open3d (macOS/Windows)"
)

project = self.project
analyze = self.analyze
num_pts = analyze.get_num_particles()
Expand Down
13 changes: 12 additions & 1 deletion Python/shapeworks/shapeworks/network_analysis_figures.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import trimesh
# import itertools
# import operator
import open3d as o3d
import scipy
# import spm1d
import vtk
Expand All @@ -24,11 +23,23 @@
import vedo
import cv2

# open3d is imported lazily when needed (not available on all platforms)

class NetworkAnalysisFigures:
def __init__(self, network_analysis):
self.network_analysis = network_analysis

def run(self):
# Import open3d here (lazy import - not available on all platforms)
try:
import open3d as o3d
except ImportError:
raise ImportError(
"open3d is required for network analysis figures but is not installed. "
"This feature may not be available on your platform/Python version. "
"Try: pip install open3d-cpu (Linux) or pip install open3d (macOS/Windows)"
)

# In[4]:

analyze = self.network_analysis.analyze
Expand Down
3 changes: 2 additions & 1 deletion Support/package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ else
linuxdeployqt ShapeWorksStudio -verbose=2
cd ..

rm lib/libxcb* lib/libX* lib/libfont* lib/libfreetype*
# Keep libfreetype as harfbuzz depends on it (FT_Get_Transform requires freetype 2.11+)
rm lib/libxcb* lib/libX* lib/libfont*
rm -rf geometry-central doc
fi

Expand Down
34 changes: 23 additions & 11 deletions install_shapeworks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -179,22 +179,34 @@ function install_conda() {
if ! python -m light_the_torch install torch==2.8.0 torchaudio==2.8.0 torchvision==0.23.0; then return 1; fi
fi

# for network analysis
# for network analysis (optional - not available on all platforms/Python versions)
# open3d needs to be installed differently on each platform so it's not part of python_requirements.txt
OPEN3D_INSTALLED=NO
if [[ "$(uname)" == "Linux" ]]; then
if ! pip install open3d-cpu==0.19.0; then return 1; fi
if pip install open3d-cpu==0.19.0; then
OPEN3D_INSTALLED=YES
else
echo "WARNING: open3d-cpu could not be installed. Network analysis features will not be available."
fi
elif [[ "$(uname)" == "Darwin" ]]; then
if ! pip install open3d==0.19.0; then return 1; fi

if [[ "$(uname -m)" == "arm64" ]]; then
pushd $CONDA_PREFIX/lib/python3.12/site-packages/open3d/cpu
install_name_tool -change /opt/homebrew/opt/libomp/lib/libomp.dylib @rpath/libomp.dylib pybind.cpython-312-darwin.so
install_name_tool -add_rpath @loader_path/../../../ pybind.cpython-312-darwin.so
popd
ln -sf "$CONDA_PREFIX/lib/libomp.dylib" "$CONDA_PREFIX/lib/python3.12/site-packages/open3d/cpu/../../../libomp.dylib"
if pip install open3d==0.19.0; then
OPEN3D_INSTALLED=YES
if [[ "$(uname -m)" == "arm64" ]]; then
pushd $CONDA_PREFIX/lib/python3.12/site-packages/open3d/cpu
install_name_tool -change /opt/homebrew/opt/libomp/lib/libomp.dylib @rpath/libomp.dylib pybind.cpython-312-darwin.so
install_name_tool -add_rpath @loader_path/../../../ pybind.cpython-312-darwin.so
popd
ln -sf "$CONDA_PREFIX/lib/libomp.dylib" "$CONDA_PREFIX/lib/python3.12/site-packages/open3d/cpu/../../../libomp.dylib"
fi
else
echo "WARNING: open3d could not be installed. Network analysis features will not be available."
fi
else
if ! pip install open3d==0.19.0; then return 1; fi
if pip install open3d==0.19.0; then
OPEN3D_INSTALLED=YES
else
echo "WARNING: open3d could not be installed. Network analysis features will not be available."
fi
fi

for package in DataAugmentationUtilsPackage DatasetUtilsPackage MONAILabelPackage DeepSSMUtilsPackage DocumentationUtilsPackage ShapeCohortGenPackage shapeworks ; do
Expand Down
Loading