Skip to content
Closed
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
12 changes: 12 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 12 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@

sudo: true
dist: trusty

language: python

service: docker

matrix:
include:
- os: linux
Expand Down Expand Up @@ -43,7 +47,7 @@ install:
conda create --yes -n test python="2.7";
fi
- source activate test
- conda install --yes numpy scipy matplotlib pip nose vtk
- conda install --yes numpy scipy matplotlib pip nose vtk sip=4.18
- conda install --yes -c https://conda.anaconda.org/dlr-sc pythonocc-core
- pip install setuptools
- pip install enum34
Expand All @@ -52,8 +56,12 @@ install:
- pip install coverage
- python setup.py install

script: coverage run test.py

script:
- coverage run test.py
# Docker in travis works only with linux.
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
docker run -u root docker.io/pygemdocker/pygem:latest /bin/sh -c "cd /home/PyGeM/build/PyGeM; coverage run test.py";
fi
after_success:
- coveralls

Expand Down
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,34 @@ To uninstall the package you have to rerun the installation and record the insta
> python setup.py install --record installed_files.txt
> cat installed_files.txt | xargs rm -rf
```
Alternatively, a way to run the PyGeM library is to use our prebuilt and high-performance Docker images.
Docker containers are extremely lightweight, secure, and are based on open standards that run on all major Linux distributions, macOS and Microsoft Windows platforms.

Install Docker for your platform by following [these instructions](https://docs.docker.com/engine/getstarted/step_one/).
If using the Docker Toolbox (macOS versions < 10.10 or Windows versions < 10), make sure you run all commands inside the Docker Quickstart Terminal.

Now we will pull the docker.io/pygemdocker/pygem image from our cloud infrastructure:
```bash
> docker pull docker.io/pygemdocker/pygem:latest
```
Docker will pull the latest tag of the image pygemdocker/pygem from docker.io. The download is around 3.246 GB. The image is a great place to start experimenting with PyGeM and includes all dependencies already compiled for you.
Once the download is complete you can start PyGeM for the first time. Just run:
```bash
> docker run -ti pygemdocker/pygem:latest
```
To facilitate the devoloping, using the text editor,version control and other tools already installed on your computers,
it is possible to share files from the host into the container:

```bash
> docker run -ti -v $(pwd):/home/PyGeM/shared pygemdocker/pygem:latest
```
To allow the X11 forwarding in the container, on Linux system just run:

```bash
> docker run -ti --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v $(pwd):/home/PyGeM/shared pygemdocker/pygem:latest
```

For Windows system, you need to install Cygwin/X version and running the command in Cygwin terminal. While for mac system, you need to install xquartz.

## Documentation
**PyGeM** uses [Sphinx](http://www.sphinx-doc.org/en/stable/) for code documentation. To build the html versions of the docs simply:
Expand Down
86 changes: 86 additions & 0 deletions dockerfiles/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
FROM phusion/baseimage:0.9.19

# Get Ubuntu updates
USER root
RUN apt-get update -q && \
apt-get upgrade -y -o Dpkg::Options::="--force-confold" && \
apt-get -y install sudo && \
apt-get -y install locales && \
echo "C.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Set locale environment
ENV LC_ALL=C.UTF-8 \
LANG=C.UTF-8 \
LANGUAGE=C.UTF-8

# OpenBLAS threads should be 1 to ensure performance
RUN echo 1 > /etc/container_environment/OPENBLAS_NUM_THREADS && \
echo 0 > /etc/container_environment/OPENBLAS_VERBOSE


# Set up user so that we do not run as root
RUN useradd -m -s /bin/bash -G sudo,docker_env PyGeM && \
echo "PyGeM:docker" | chpasswd && \
echo "PyGeM ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

RUN touch /etc/service/syslog-forwarder/down
COPY set-home-permissions.sh /etc/my_init.d/set-home-permissions.sh
RUN chmod +x /etc/my_init.d/set-home-permissions.sh

USER PyGeM
ENV HOME /home/PyGeM
RUN touch $HOME/.sudo_as_admin_successful && \
mkdir $HOME/shared && \
mkdir $HOME/build
VOLUME /home/PyGeM/shared

WORKDIR /home/PyGeM
ENTRYPOINT ["sudo","/sbin/my_init","--quiet","--","sudo","-u","PyGeM","/bin/bash","-l","-c"]
CMD ["/bin/bash","-i"]

# utilities and libraries
USER root
RUN apt-get update -y; apt-get install -y --force-yes --fix-missing --no-install-recommends curl git unzip tree subversion vim cmake bison g++ gfortran openmpi-bin pkg-config wget libpcre3-dev bison flex swig libglu1-mesa pyqt4-dev-tools
RUN apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

RUN id PyGeM
RUN chown -R PyGeM:PyGeM $HOME

RUN cd /tmp && \
wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh && \
chmod +x miniconda.sh && \
bash miniconda.sh -b -p /usr/local/miniconda && \
rm /tmp/*
ENV PATH=/usr/local/miniconda/bin:$PATH

RUN echo "PATH=/usr/local/miniconda/bin:$PATH" >> ~/.profile
RUN /bin/bash -c 'source ~/.profile'

RUN hash -r && \
conda config --set always_yes yes --set changeps1 no && \
conda update -q conda
RUN conda info -a && \
conda create --yes -n test python="2.7";

RUN /bin/bash -c 'source activate test'
# The default sip version has api that is not compatible with qt4.
RUN conda install --yes numpy scipy matplotlib pip nose vtk sip=4.18
RUN conda install --yes -c https://conda.anaconda.org/dlr-sc pythonocc-core &&\
pip install setuptools && \
pip install enum34 && \
pip install numpy-stl && \
pip install coveralls && \
pip install coverage

RUN cd $HOME && \
cd build && \
git clone https://github.com/mathLab/PyGeM.git && \
cd PyGeM && \
python setup.py install

USER PyGeM


17 changes: 17 additions & 0 deletions dockerfiles/set-home-permissions.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
# User can pass e.g. --env HOST_UID=1003 so that UID in the container matches
# with the UID on the host. This is useful for Linux users, Mac and Windows
# already do transparent mapping of shared volumes.
if [ "$HOST_UID" ]; then
usermod -u $HOST_UID PyGeM
fi
if [ "$HOST_GID" ]; then
groupmod -g $HOST_GID PyGeM
fi
# This makes sure that all files in /home/fenics are accessible by the user
# fenics. We exclude the folder ~/shared to reduce IO out to the host. Docker
# for Mac, Docker for Windows and the UID/GID trick above should mean that file
# permissions work seamlessly now.
cd /home/PyGeM
find . -maxdepth 1 | grep -v "./shared" | xargs chown -R PyGeM:PyGeM

80 changes: 79 additions & 1 deletion pygem/params.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
"""
Utilities for reading and writing parameters files to perform the desired geometrical morphing.
"""
import os
import ConfigParser
import os

import numpy as np
from OCC.BRepBndLib import brepbndlib_Add
from OCC.BRepMesh import BRepMesh_IncrementalMesh
from OCC.Bnd import Bnd_Box

import pygem.affine as at


Expand Down Expand Up @@ -294,6 +299,79 @@ def print_info(self):
print '\nposition_vertex_3 ='
print self.position_vertex_3

def build_bounding_box(self, shape, tol=1e-6, triangualte=False, triangulate_tol=1e-1):
min_xyz, max_xyz = self._calculate_bb_dimension(shape, tol, triangualte, triangulate_tol)
self.origin_box = min_xyz
self._set_box_dimensions(min_xyz, max_xyz)
self._set_position_of_vertices()
self._set_mapping()
self._set_transformation_params_to_zero()

def _set_box_origin(self, xyz):
self.origin_box = xyz

def _set_box_dimensions(self, min_xyz, max_xyz):
"""
Dimensions of the cage are set as distance from the origin (minimum) of the cage to
the maximal point in each dimension.
:return:
"""
dims = [max_xyz[i] - min_xyz[i] for i in range(3)]
self.lenght_box_x = dims[0]
self.lenght_box_y = dims[1]
self.lenght_box_z = dims[2]

def _set_position_of_vertices(self):
"""
Vertices of the control box around the object are set in this method.
Four vertex (non coplanar) are sufficient to uniquely identify a parallelepiped -- the
second half of the box is created as a mirror reflection of the first four vertices.
:return:
"""
origin_array = np.array(self.origin_box)
dim = [self.lenght_box_x, self.lenght_box_y, self.lenght_box_z]
self.position_vertex_0 = origin_array
self.position_vertex_1 = origin_array + np.array([dim[0], .0, .0])
self.position_vertex_2 = origin_array + np.array([.0, dim[1], .0])
self.position_vertex_3 = origin_array + np.array([.0, .0, dim[2]])

def _set_mapping(self):
dim = [self.lenght_box_x, self.lenght_box_y, self.lenght_box_z]
self.psi_mapping = np.diag([1. / dim[i] for i in range(3)])
self.inv_psi_mapping = np.diag(dim)

def _set_transformation_params_to_zero(self):
ctrl_pnts = self.n_control_points
self.array_mu_x = np.zeros(ctrl_pnts)
self.array_mu_y = np.zeros(ctrl_pnts)
self.array_mu_z = np.zeros(ctrl_pnts)

def _calculate_bb_dimension(self, shape, tol=1e-6, triangualte=False, triangulate_tol=1e-1):
""" return the bounding box of the TopoDS_Shape `shape`
Parameters
----------
shape : TopoDS_Shape or a subclass such as TopoDS_Face
the shape to compute the bounding box from
tol: float
tolerance of the computed boundingbox
triangualte : bool
if True only the dimensions of the bb will take into account every part of the shape (also not 'visible')
if False only the 'visible' part is taken into account
*** Explanation: every UV-Surface has to be rectangular. When a solid is created surfaces are trimmed.
*** the trimmed part, however, is still saved inside a file. It is just 'invisible' when drawn in a program
Returns
-------
tuple: consisting of two tuples: first one has coords of minimum, the second one coords of maximum
"""
bbox = Bnd_Box()
bbox.SetGap(tol)
if triangualte:
BRepMesh_IncrementalMesh(shape, triangulate_tol)
brepbndlib_Add(shape, bbox, triangualte)
xmin, ymin, zmin, xmax, ymax, zmax = bbox.Get()
xyz_min = np.array([xmin, ymin, zmin])
xyz_max = np.array([xmax, ymax, zmax])
return xyz_min, xyz_max


class RBFParameters(object):
Expand Down
Loading