Alternate Python bindings for the Open Asset Import Library (ASSIMP)

Overview

Impasse

Python Test Status codecov

A simple Python wrapper for assimp using cffi to access the library. Requires Python >= 3.7.

It's a fork of PyAssimp, Assimp's official Python port. In contrast to PyAssimp, it strictly targets modern Python 3 and provides type hints. It also aims to allow mutating scenes before exporting by having all wrapper classes operate directly on the underlying C data structures.

Usage

Complete example: 3D viewer

impasse comes with a simple 3D viewer that shows how to load and display a 3D model using a shader-based OpenGL pipeline.

Screenshot

To use it:

python ./scripts/3d_viewer.py <path to your model>

You can use this code as starting point in your applications.

Writing your own code

To get started with impasse, examine the simpler sample.py script in scripts/, which illustrates the basic usage. All Assimp data structures are wrapped using ctypes. All the data+length fields in Assimp's data structures (such as aiMesh::mNumVertices, aiMesh::mVertices) are replaced by list-like wrapper classes, so you can call len() on them to get their respective size and access members using [].

For example, to load a file named hello.3ds and print the first vertex of the first mesh, you would do (proper error handling substituted by assertions ...):

from impasse import load

scene = load('hello.3ds')

assert len(scene.meshes)
mesh = scene.meshes[0]

assert len(mesh.vertices)
print(mesh.vertices[0])

Another example to list the 'top nodes' in a scene:

from impasse import load

scene = load('hello.3ds')
for c in scene.root_node.children:
    print(str(c))

All of assimp's coordinate classes are returned as NumPy arrays, so you can work with them using library for 3d math that handles NumPy arrays. Using transforms.py to modify the scene:

import math

import numpy
import transformations
import impasse

# assimp returns an immutable scene, we have to copy it if we want to change it
scene = impasse.load('hello.3ds').copy_mutable()
transform = scene.root_node.transformation
# Rotate the root node's transform by 180 deg on X
transform = numpy.dot(transformations.rotation_matrix(math.pi, (1, 0, 0)), transform)
scene.root_node.transformation = transform
impasse.export(scene, 'whatever.obj', 'obj')

Installing

Install impasse by running:

pip install impasse

or, if you want to install from the source directory:

pip install -e .

Impasse requires an assimp dynamic library (DLL on Windows, .so on linux, .dynlib on macOS) in order to work. The default search directories are:

  • the current directory
  • on linux additionally: /usr/lib, /usr/local/lib, /usr/lib/ -linux-gnu

To build that library, refer to the Assimp master INSTALL instructions. To look in more places, edit ./impasse/helper.py. There's an additional_dirs list waiting for your entries.

Progress

All features present in PyAssimp are now present in Assimp (plus a few more!) Since the API largely mirrors PyAssimp's, most existing code should work in Impasse with minor changes.

Note that Impasse is not complete. Many assimp features are still missing, mostly around mutating scenes. Notably, anything that would require a new or delete in assimp's C++ API is not supported.

Performance

Impasse tries to avoid unnecessary copies or conversions of data owned by C, and most classes are just thin layers around the underlying CFFI structs. NumPy arrays that directly map to the underlying structs' memory are used for the coordinate structs like Matrix4x4 and Vector3D.

Testing with a similar quicktest.py script against assimp's test model directory:

Impasse

** Loaded 169 models, got controlled errors for 28 files, 0 uncontrolled

real	0m1.460s
user	0m1.676s
sys	0m0.571s

PyAssimp

** Loaded 165 models, got controlled errors for 28 files, 4 uncontrolled

real	0m7.607s
user	0m7.746s
sys	0m0.579s
Comments
  • Nicer way of referring to material property keys

    Nicer way of referring to material property keys

        ('$mat.twosided', 0): [0]
        ('$mat.refracti', 0): [1.]
        ('$mat.bumpscaling', 0): [1.]
        ('$clr.specular', 0): [1. 1. 1.]
    

    Those keys are in the data returned by assimp, but I'm not sure if the prefix is that meaningful. PyAssimp strips off everything before the first .. If they're meaningful or there are collisions without those prefixes, we should keep a string enum of common ones that's easier to refer to.

    enhancement 
    opened by SaladDais 3
  • Rebase on top of original assimp sources to keep PyAssimp's commit history intact

    Rebase on top of original assimp sources to keep PyAssimp's commit history intact

    Now that I think of it, it's preferable to keep the commit history for assimp even if most of it's unrelated to PyAssimp. Make a commit deleting all assimp sources and moving PyAssimp to the repo root, then rebase impasse on top of that.

    Rewriting history isn't nice since I've already based my sources on top of a squashed commit, but impact should be mininal since nobody's using this yet.

    opened by SaladDais 1
  • Make mapping classes mix-ins

    Make mapping classes mix-ins

    Other than name collisions with keys / values, I don't think there's any reason to keep the explicit as_mapping() method rather than just putting them on a mixin for the SerializeableStructs. Can define manual renames for any of those.

    This'd give us a closer API to what PyAssimp already has

    enhancement 
    opened by SaladDais 1
  • Add accessors for mesh and texture that return instances rather than indexes

    Add accessors for mesh and texture that return instances rather than indexes

    All of the struct wrapper have a _scene member that should allow them to transparently look up the texture / material by the index in the attr they wrap.

    enhancement 
    opened by SaladDais 1
  • Get scene mutability working

    Get scene mutability working

    Per the C api you have to create a copy of the scene to get a non-const version: https://github.com/assimp/assimp/blob/master/include/assimp/cexport.h#L109-L123 . Right now all the structs we return have wrappers enforcing the const-ness of scene returned from the the aiImportFile() function. Need to expose the copying functions so people can get a scene they can modify before export.

    enhancement 
    opened by SaladDais 1
  • Package assimp shared library so assimp isn't required to be on the system

    Package assimp shared library so assimp isn't required to be on the system

    Would be nice so people don't have to do some weird conda thing if they want to install the package including assimp.

    I think it should be enough to have osx aarch64, osx x64, linux x64 and windows x64 packages. We don't need to do python version-specific builds, since we'll just be building the assimp library itself and binding against it with cffi. It should be provided in an optional, separate package with the shared library in the package data for the given platform's build.

    enhancement 
    opened by SaladDais 0
  • Add ability to alloc new structs, append to sequences

    Add ability to alloc new structs, append to sequences

    This is tricky since assimp makes liberal use of new[] and delete[] on types that have non-trivial destructors (like aiTexture.) malloc()ing and free()ing those is technically possible but inadvisable, and requires knowledge of the platform / compiler's C++ ABI.

    Likewise, assimp's C API doesn't appear to expose a wrapper around those new[] and delete[] calls. Adding functions to assimp to do those would be the least nasal demon-y approach but wouldn't be available in stable distros' libs.

    A third approach would be to have Scenes keep track of the original values of mutated ptrs, then put everything back in place when the GC happens so anything that'd been internally alloc'd with new could be deleted by assimp. Would also have to keep a list of things we'd malloc()d in our own code to manually free(). Can see a lot of nasty corner cases with this one.

    enhancement help wanted 
    opened by SaladDais 0
Releases(v5.2.0)
Owner
Salad Dais
Code as craft
Salad Dais
DP2 graph edit codes.

必要なソフト・パッケージ Python3 Numpy JSON Matplotlib 動作確認環境 MacBook Air M1 Python 3.8.2 (arm64) Numpy 1.22.0 Matplotlib 3.5.1 JSON 2.0.9 使い方 draw_time_histgram(

1 Feb 19, 2022
Tools for making image cutouts from sets of TESS full frame images

Cutout tools for astronomical images Astrocut provides tools for making cutouts from sets of astronomical images with shared footprints. It is under a

Space Telescope Science Institute 20 Dec 16, 2022
A simple Streamlit Component to compare images in Streamlit apps. It integrates Knightlab's JuxtaposeJS

streamlit-image-juxtapose A simple Streamlit Component to compare images in Streamlit apps using Knightlab's JuxtaposeJS. The images are saved to the

Robin 30 Dec 31, 2022
Random collage/montage generator with drop-shadow

Random Collage Example Usage These are the sample input files in $PWD for the below examples: 1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10

M B 1 Dec 07, 2021
A utility for quickly cropping large collections of images.

Crop Tool A utility for quickly cropping large collections of images. Inspired by Derrick Schultz's dataset-tools. Setup It's suggested that you use A

dusk (they/them) 6 Nov 14, 2021
python app to turn a photograph into a cartoon

Draw This. Draw This is a polaroid camera that draws cartoons. You point, and shoot - and out pops a cartoon; the camera's best interpretation of what

Dan Macnish 2k Dec 19, 2022
HtmlWebShot - A python3 package which Can Create Images From url, Html-CSS, Svg and from any readable file and texts with many setup features.

A python3 package which Can Create Images From url, Html-CSS, Svg and from any readable file and texts with many setup features

Danish 24 Dec 14, 2022
Program to export all new icons from the latest Fortnite patch

Assets Exporter This program allows you to generate all new icons of a patch in png! Requierements Python =3.8 (installed on your computer) If you wa

ᴅᴊʟᴏʀ3xᴢᴏ 6 Jun 24, 2022
CropImage is a simple toolkit for image cropping, detecting and cropping main body from pictures.

CropImage is a simple toolkit for image cropping, detecting and cropping main body from pictures. Support face and saliency detection.

Haofan Wang 15 Dec 22, 2022
Command line utility for converting images to seamless tiles

img2texture Command line utility for converting images to seamless tiles. The resulting tiles can be used as textures in games, compositing and 3D mod

Artёm IG 24 Dec 26, 2022
The aim is to extract timeseries water level 2D information for any designed boundaries within the EasyGSH model domain

bct_file_generator_for_EasyGSH The aim is to extract timeseries water level 2D information for any designed boundaries within the EasyGSH model domain

Clayton Soares 1 Jul 08, 2022
Computational Xmas Tree lights!

Computational Xmas Tree This repo contains the code for the computational illumination of a Christmas Tree! It is based on the work by Matt Parker fro

GSD6338 146 Dec 23, 2022
Fuzzware is a project for automated, self-configuring fuzzing of firmware images

Fuzzware Fuzzware is a project for automated, self-configuring fuzzing of firmware images. The idea of this project is to configure the memory ranges

190 Dec 21, 2022
Script For Importing Image sequences into scrap mechanic via blueprints

To use dowload and extract "video makes.zip" Python has to be installed https://www.python.org/ (may not work on version lower than 3.9) Has to be run

2 Oct 30, 2021
MikuMikuRig是一款集生成控制器,自动导入动画,自动布料为一体的blender插件

Miku_Miku_Rig MikuMikuRig是一款集生成控制器,自动导入动画,自动布料为一体的blender插件。 MikumiKurig is a Blender plugin that can generates rig, automatically imports animations

小威廉伯爵 342 Dec 29, 2022
3D Model files and source code for rotating turntable. Raspberry Pi, DC servo and PWM modulator required.

3DSimpleTurntable 3D Model files and source code for rotating turntable. Raspberry Pi, DC servo and PWM modulator required. Preview Construction Print

Thomas Boyle 1 Feb 13, 2022
hashmask reverse lookup

ImageHashMasks Lookup Hashmask NFT index from a picture Setup pip install pillow click imagehash Usage $ python imagehashmasks.py

17 Nov 29, 2021
Samila is a generative art generator written in Python

Samila is a generative art generator written in Python, Samila let's you create arts based on many thousand points. The position of every single point is calculated by a formula, which has random par

Sepand Haghighi 947 Dec 30, 2022
Python pygame project that turns your images to matrix rain

Matrix-Rain-An-Image This project implements the classic Matrix digital rain effect in python with pygame to build up an image provided with multiple

7 Dec 11, 2022
Labelme is a graphical image annotation tool, It is written in Python and uses Qt for its graphical interface

Image Polygonal Annotation with Python (polygon, rectangle, circle, line, point and image-level flag annotation).

Kentaro Wada 9.6k Jan 09, 2023