[PYTHON] I tried to summarize the operations that are likely to be used with numpy-stl

Introduction

I thought it would be easy if the things to be modeled with a 3D printer became a pattern and I could create a model without permission by entering numbers, but I found out what is called numpy-stl, so I summarized it as a memo.

What is numpy-stl?

A rough translation of the official document looks like this.

A simple library for working with STL files (as well as common 3D models) quickly and easily. All operations rely heavily on numpy and are one of the fastest STL libraries for Python.

In short, it's a library where you can create 3D models like numpy and play with existing STL files.

Official website and reference materials

--numpy-stl project page https://pypi.org/project/numpy-stl/ --numpy-stl documentation https://numpy-stl.readthedocs.io/en/latest/ --3D printing x Python ~ 3D printing approaching from code ~ https://www.slideshare.net/TakuroWada/3dpython3d

Installation

Basically, pip is OK. This time, I ran it on macOS Catalina 10.15.6, python 3.7.7.

install


pip3 install numpy-stl

If you want to check the generated 3D model, also install the following libraries.

install


pip3 install mpl_toolkits
pip3 install matplotlib

Various operations

I will add it when I feel like rotating. (However, if you google with numpy-stl, you will see quite a few articles like that.)

I want to make a cube (regular hexahedron)

I made it a function because it was a big deal. Enter the size in the arguments scale_x, scale_y, scale_z. Depending on the unit system, you should be able to create a cube with a height and width of 1 in the default state with no arguments.

cube_model.py


import numpy as np
from stl import mesh

def cube_model(scaleX=1, scaleY=1, scaleZ=1):
    scaleX = scaleX / 2
    scaleY = scaleY / 2
    scaleZ = scaleZ / 2

    vertices = np.array([\
        [-1*scaleX, -1*scaleY, -1*scaleZ],
        [+1*scaleX, -1*scaleY, -1*scaleZ],
        [+1*scaleX, +1*scaleY, -1*scaleZ],
        [-1*scaleX, +1*scaleY, -1*scaleZ],
        [-1*scaleX, -1*scaleY, +1*scaleZ],
        [+1*scaleX, -1*scaleY, +1*scaleZ],
        [+1*scaleX, +1*scaleY, +1*scaleZ],
        [-1*scaleX, +1*scaleY, +1*scaleZ]])

    faces = np.array([\
        [0,3,1],
        [1,3,2],
        [0,4,7],
        [0,7,3],
        [4,5,6],
        [4,6,7],
        [5,1,2],
        [5,2,6],
        [2,3,6],
        [3,7,6],
        [0,1,5],
        [0,5,4]])

    cube = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype))
    cube.remove_duplicate_polygons=True
    for i, f in enumerate(faces):
        for j in range(3):
            cube.vectors[i][j] = vertices[f[j],:]

    return cube

Click here for the program to load

test_plot.py


import numpy as np
from stl import mesh
from mpl_toolkits import mplot3d
from matplotlib import pyplot
from cube_model import cube_model

figure = pyplot.figure()
axes = mplot3d.Axes3D(figure)

your_mesh = cube_model(10,10,10)
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors))

scale = your_mesh.points.flatten()
print(scale)
axes.auto_scale_xyz(scale, scale, scale)

pyplot.show()

I want to load my STL

Specify your own STL file in your_stl_model.stl.

read_stl_file.py


import numpy as np
from stl import mesh
from mpl_toolkits import mplot3d
from matplotlib import pyplot

figure = pyplot.figure()
axes = mplot3d.Axes3D(figure)

your_mesh = mesh.Mesh.from_file('your_stl_model.stl')
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors))

scale = cube_comb.points.flatten()
axes.auto_scale_xyz(scale, scale, scale)

pyplot.show()

I want to align the 3D model with the origin

It is used to align the center of the model with (0,0,0) when the read STL is flying in a strange direction. In the argument my_mesh, put the mesh object when the STL file etc. is read.

mesh_location_zero.py


import numpy as np
from stl import mesh

def mesh_location_zero(my_mesh):
    midPosRel = (my_mesh.max_ - my_mesh.min_)/2
    my_mesh.x = my_mesh.x - (midPosRel[0] + my_mesh.min_[0])
    my_mesh.y = my_mesh.y - (midPosRel[1] + my_mesh.min_[1])
    my_mesh.z = my_mesh.z - (midPosRel[2] + my_mesh.min_[2])
    return my_mesh

Update mesh information

In order to update the members in the mesh object, this is also executed when moving, including adjusting the coordinate system, or expanding, rotating, or changing the model. The arguments are the same.

mesh_update.py


import numpy as np
from stl import mesh

def mesh_update(my_mesh):
    my_mesh.update_areas()
    my_mesh.update_max()
    my_mesh.update_min()
    my_mesh.update_units()
    return my_mesh

I want to scale the 3D model

Enlargement / reduction has also been made into a function. Put your own 3D model in my_mesh, and put 1.0 as 100% in scale_x, scale_y, and scale_z.

mesh_scale.py


import numpy as np
from stl import mesh

def mesh_scale(my_mesh, scale_x, scale_y, scale_z):
    my_mesh.x = my_mesh.x * scale_x
    my_mesh.y = my_mesh.y * scale_y
    my_mesh.z = my_mesh.z * scale_z 
    return my_mesh

I want to move a 3D model

You can move it with mesh.translate. Arguments are specified in numpy.array. (This time, I also use cube_model.py.)

move_model.py


import numpy as np
from stl import mesh
from mpl_toolkits import mplot3d
from matplotlib import pyplot
from cube_model import cube_model

figure = pyplot.figure()
axes = mplot3d.Axes3D(figure)

your_mesh = cube_model(5,20,5)
your_mesh.translate(np.array([1,3,1]))

axes.add_collection3d(mplot3d.art3d.Poly3DCollection(your_mesh.vectors))

scale = cube_comb.points.flatten()
print(scale)
axes.auto_scale_xyz(scale, scale, scale)

pyplot.show()

I want to combine 3D models

You can combine models with numpy.concatenate. I'm just selling that I can make a model with numpy. (This time, I also use cube_model.py.)

mesh_scale.py


import numpy as np
from stl import mesh
from mpl_toolkits import mplot3d
from matplotlib import pyplot
from cube_model import cube_model

figure = pyplot.figure()
axes = mplot3d.Axes3D(figure)

your_mesh = cube_model(10,10,10)
your_mesh2 = cube_model(5,20,5)
your_mesh2.translate(np.array([1,1,1]))

cube_comb = mesh.Mesh(np.concatenate([
    your_mesh.data.copy(),
    your_mesh2.data.copy(),
]))

axes.add_collection3d(mplot3d.art3d.Poly3DCollection(cube_comb.vectors))

scale = cube_comb.points.flatten()
print(scale)
axes.auto_scale_xyz(scale, scale, scale)

pyplot.show()

I want to save a 3D model

Can be saved with mesh.save. The arguments are the save destination path and file name.

save_model.py


import numpy as np
from stl import mesh
from cube_model import cube_model

your_mesh = cube_model(10,10,10)
your_mesh2 = cube_model(5,20,5)
your_mesh2.translate(np.array([1,1,1]))

cube_comb = mesh.Mesh(np.concatenate([
    your_mesh.data.copy(),
    your_mesh2.data.copy(),
]))

cube_comb.save('your_model.stl')

bonus

I tried to stream the STL data created in the software "XYZprint" used to stream the modeling data with a 3D printer made by XYZprinting. I'm glad that the stacked data can be created properly.

XYZprintで読み込んで見たときのスクショその1 XYZprintで読み込んで見たときのスクショその2

in conclusion

This time I tried to operate numpy-stl. If there are other operations that you might use in general, add them when you feel like it.

Recommended Posts

I tried to summarize the operations that are likely to be used with numpy-stl
I tried to expand the database so that it can be used with PES analysis software
I tried to summarize the string operations of Python
I tried to predict the horses that will be in the top 3 with LightGBM
I tried to summarize the methods that are often used when implementing basic algo in Quantx Factory
I tried to summarize the code often used in Pandas
I tried to summarize the commands often used in business
[LPIC 101] I tried to summarize the command options that are easy to make a mistake
I tried to summarize the umask command
I tried to summarize the graphical modeling.
I tried to summarize the commands used by beginner engineers today
I tried to summarize the frequently used implementation method of pytest-mock
[New employee studying] Let's summarize the Linux commands that are likely to be used for network construction from now on
[Flask] I tried to summarize the "docker-compose configuration" that can be created quickly for web applications
I tried to build an estimation model of article titles that are likely to buzz with Qiita
I tried to summarize the Linux commands used by beginner engineers today-Part 1-
I tried to save the data with discord
LeetCode I tried to summarize the simple ones
I tried to learn the sin function with chainer
I tried to summarize the basic form of GPLVM
I tried to touch the CSV file with Python
I tried to solve the soma cube with python
I tried to solve the problem with Python Vol.1
plotly trace and layout templates that are likely to be used in scatter plots
I tried to summarize SparseMatrix
I tried to analyze the whole novel "Weathering with You" ☔️
[First COTOHA API] I tried to summarize the old story
I tried to find the average of the sequence with TensorFlow
I tried to notify the train delay information with LINE Notify
[Machine learning] I tried to summarize the theory of Adaboost
I tried to divide the file into folders with Python
I investigated the pretreatment that can be done with PyCaret
I tried to summarize how to use the EPEL repository again
I tried to summarize what python strong people are doing in the competition professional neighborhood
I tried to summarize the languages that beginners should learn from now on by purpose
I tried to move the ball
I tried to estimate the interval.
I tried to describe the traffic in real time with WebSocket
I tried to solve the ant book beginner's edition with python
[Linux] I tried to summarize the command of resource confirmation system
I tried to automate the watering of the planter with Raspberry Pi
[Python] A memo that I tried to get started with asyncio
I tried to process the image in "sketch style" with OpenCV
I tried to summarize what was output with Qiita with Word cloud
I tried to get started with Bitcoin Systre on the weekend
I tried to process the image in "pencil style" with OpenCV
I tried to expand the size of the logical volume with LVM
I tried to summarize everyone's remarks on slack with wordcloud (Python)
I tried to improve the efficiency of daily work with Python
When I tried to use pip with python, I was told that XML_SetHashSalt could not be found.
A story that didn't work when I tried to log in with the Python requests module
I tried to summarize Python exception handling
[Python] I tried to visualize the night on the Galactic Railroad with WordCloud!
I tried to refer to the fun rock-paper-scissors poi for beginners with Python
I tried to summarize until I quit the bank and became an engineer
I tried to implement deep learning that is not deep with only NumPy
I tried to implement Autoencoder with TensorFlow
I tried to implement a blockchain that actually works with about 170 lines
I tried to visualize AutoEncoder with TensorFlow
I tried to recognize the wake word
I tried to get started with Hy