Skip to main content

A fast geometry manipulation and creation library written in Rust, wrapped in python

Project description

GMAC

Build & Test

A fast geometry manipulation and creation library made in rust, with a convenient python interface, and very few dependencies. Primary features include:

  • Create primitives
  • Transform geometries (or selection just a selection of nodes)
  • Large range of selection and transformation tools
  • Deform geometries using RBF and FFD
  • Convenient python interface (gmac_py)
  • Fast and memory efficient

Here's a demonstration of a plane tail deformed using the Free Form deformer (FFD):

Variation 1 Variation 2

Both plane tail variations were created using the Gmac Free Form deformer (FFD).

Contributing

Build python from source

These instructions assume that Python3 and Cargo are installed on your system. To set up this project, follow these steps:

  1. Clone the repository:
    git clone https://github.com/alexlovric/gmac.git
    cd gmac/gmac_py
    
  2. Create a virtual environment and install build system:
    python3 -m venv .venv
    source .venv/bin/activate # In windows /Scripts/activate
    python3 -m pip install -r requirements.txt
    
  3. Build the release binary:
    maturin develop --release
    
  4. Build the python wheel:
    maturin build --release
    

Examples in Python

Using GMAC to deform a box

Heres a simple demonstration where we deform a box mesh using RbfDeformer from the gmac_morph library. Firstly lets import the required modules and create a box mesh that we intend to deform using the generate_box function:

import gmac
import gmac.morph as morph
import gmac.io as io
import numpy as np

box = gmac.generate_box(
    length=[1.0, 1.0, 1.0], centre=[0.0, 0.0, 0.0], resolution=[5, 5, 5]
)

io.write_stl(nodes=box.nodes, cells=box.cells, filename="original_box.stl")

Now lets define some control points to use in the training of our RBF deformer. We use generate_block_cluster to create a grid of 3D points:

original_control_points = np.array(
    gmac.generate_block_cluster(
        length=[1.2, 1.2, 1.2], centre=[0.0, 0.0, 0.0], resolution=[2, 2, 2]
    )
)

io.write_vtp(original_control_points, "original_control_points.vtp")

Now before we define the deformed control points we want to use as the output training data for our RBF deformer, lets select nodes that we want to change from the original control points. GMAC has various selection tools to allow you to select nodes of the mesh, in this case we utilise select_nodes_in_plane_direction to select the nodes in the direction of a plane:

target_control_point_ids = gmac.select_nodes_in_plane_direction(
    nodes=original_control_points, origin=[0.3, 0.0, 0.0], normal=[1.0, 0.0, 0.0]
)

io.write_vtp(nodes=original_control_points[target_control_point_ids], filename="target_points.vtp")

We will define our deformed control points by transforming the target points of the original control points. To do this we will utilise one of GMACs various transformation tools, in this case transform_points. We define our transformation using a transformation matrix, in this case we will translate, rotate and scale the target points:

deformed_control_points = original_control_points.copy()

deformed_control_points[target_control_point_ids] = gmac.transform_nodes(
    nodes=deformed_control_points[target_control_point_ids],
    transformation_matrix=gmac.build_transformation_matrix(
        translation=[1.0, 0.0, 0.0],
        rotation=[45.0, 0.0, 0.0],
        scaling=[1.0, 0.75, 0.75],
    ),
    origin=[0.0, 0.0, 0.0],
)

io.write_vtp(nodes=deformed_control_points, filename="deformed_control_points.vtp")

Now we can set up the RbfDeformer using these original and deformed control points as well as some other parameters specific to the the RBF interpolator. Using this deformer we can deform the original box:

rbf = morph.RbfDeformer(
    original_control_points=original_control_points,
    deformed_control_points=deformed_control_points,
    kernel="gaussian",
    epsilon=1.0,
)

box.nodes = rbf.deform(points=box.nodes)

io.write_stl(nodes=box.nodes, cells=box.cells, filename="deformed_box.stl")

Here you can see the original control points and mesh, as well as the deformed control points and mesh:

Original control points Deformed control points

Similarly the Free Form Deformer can be used. This gives more control over the deformation process and can be used for deforming specific parts of the mesh without affecting the rest of the mesh. Starting from the same geometry as before, we can define a design block (the specific region we want to deform) and deform the geometry as follows:

design_block = morph.DesignBlock([0.8, 1.2, 1.2], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [2, 2, 2])

free_design_ids = design_block.select_free_design_nodes(geometry, 2)

transformation_matrix = gmac.build_transformation_matrix([0.25, 0.0, 0.0], [45.0, 0.0, 0.0], [1.0, 1.5, 1.5])

deformed_design_nodes = np.array(design_block.nodes)
deformed_design_nodes[free_design_ids] = gmac.transform_nodes(
    deformed_design_nodes[free_design_ids],
    transformation_matrix,
    [0.2, 0., 0.],
)

ffd = morph.FreeFormDeformer(design_block)

geometry.nodes = ffd.deform(geometry.nodes, deformed_design_nodes)

io.write_stl(geometry.nodes, geometry.cells, "deformed_geometry.stl")
Original control points Deformed control points

Examples in Rust

Using GMAC to deform a box

Using the gmac_morph library a box can be deformed using both RBF and FFD tools. In this case we will demonstrate the FFD process. Firstly lets import the modules required and create a box:

use gmac_core::primitives::generate_box;
use gmac_morph::{ffd::FreeFormDeformer, design_block::DesignBlock};
use gmac_core::transformation::{build_transformation_matrix, transform_node};
use gmac_io::vtk::{write_vtu, write_vtp};

fn main() {
    let mut geometry =
        generate_box([1.0, 1.0, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [5, 5, 5]);
    ...
}

Now lets specify the design block that we want to use to map our deformation:

    ...
    let design_block =
        DesignBlock::new([0.8, 1.2, 1.2], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [2, 2, 2]);

We will now deform the design block nodes so that the deformation can be mapped to the box. First we will clone the nodes. Then select the last layer of the nodes and transform it:

...
    let free_design_ids = design_block.select_free_design_nodes(&geometry, Some(2)).unwrap();

    let mut deformed_design_nodes = design_block.nodes.clone();

    let transformation_matrix =
        build_transformation_matrix([0.25, 0.0, 0.0], [45.0, 0.0, 0.0], [1.0, 1.5, 1.5]);

    free_design_ids.iter().for_each(|&id| {
        transform_node(&mut deformed_design_nodes[id], &transformation_matrix, &[0.2, 0., 0.])
    });
...

Lets create the free form deformer and deform the target nodes:

...
    let ffd = FreeFormDeformer::new(design_block);

    geometry.nodes = ffd.deform(&target_nodes, &deformed_design_nodes).unwrap();

    write_vtu(&geometry.nodes, &geometry.cells, Some("target/deformed.vtu")).unwrap();
    write_stl(&geometry.nodes, &geometry.cells, Some("target/deformed.stl")).unwrap();
...

References

The gmac_morph is heavily influenced by PyGEM (https://github.com/mathLab/PyGeM), and the following

Sieger, Menzel, Botsch. On Shape Deformation Techniques for Simulation-based Design Optimization. SEMA SIMAI Springer Series, 2015.

Lombardi, Parolini, Quarteroni, Rozza. Numerical Simulation of Sailing Boats: Dynamics, FSI, and Shape Optimization. Springer Optimization and Its Applications, 2012.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gmac-0.1.5.tar.gz (57.6 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

gmac-0.1.5-cp38-abi3-win_amd64.whl (249.2 kB view details)

Uploaded CPython 3.8+Windows x86-64

gmac-0.1.5-cp38-abi3-manylinux_2_34_x86_64.whl (2.3 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.34+ x86-64

gmac-0.1.5-cp38-abi3-macosx_11_0_arm64.whl (304.5 kB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

File details

Details for the file gmac-0.1.5.tar.gz.

File metadata

  • Download URL: gmac-0.1.5.tar.gz
  • Upload date:
  • Size: 57.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.9.0

File hashes

Hashes for gmac-0.1.5.tar.gz
Algorithm Hash digest
SHA256 aeb77796224d442968deb8f31ca019ee1db676efd14ae82a38f3bb41955c5669
MD5 3cc18a437a89b681124338453f8c73cb
BLAKE2b-256 bb558d4846a7d08f09e2b9720317d9d9dbcc755d45712ff93b1df1bb2df7c963

See more details on using hashes here.

File details

Details for the file gmac-0.1.5-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: gmac-0.1.5-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 249.2 kB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.9.0

File hashes

Hashes for gmac-0.1.5-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 2f221dedc55bf7ce12b73a403359b2b8d78b089d4d48b29d57676c2ccf51dedf
MD5 5f339ed34c41a2eeab0502b83d1806ea
BLAKE2b-256 30625f5facbdc66d0244f4018ed3df8d356503acbd89693e560f7a6a00899a90

See more details on using hashes here.

File details

Details for the file gmac-0.1.5-cp38-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for gmac-0.1.5-cp38-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 c0e5088a7157f77a3d308950a447fbd317af8aa2e4b2b81a6b6dfa706b0c3e0b
MD5 e1d96c31603f4203207495b25e2fccd2
BLAKE2b-256 ab7d4e3ebb85df2a89a62a4b1415e3b4195014d0357282bdb677508b35d1dbcb

See more details on using hashes here.

File details

Details for the file gmac-0.1.5-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for gmac-0.1.5-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ec989a167628f8dd113cb8c482a28d1722bb0520a8b2a0d000e627cfcdd885d0
MD5 c49b54ed30b1880a1eab108e1000416e
BLAKE2b-256 119a4f0a46f3e720fdabb9796559f5a31ab414773c4cbcfe4924fcb44b9ea226

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page