使用Python从3D频谱图中导出.stl或.obj

发布于 2025-01-30 14:16:11 字数 475 浏览 1 评论 0原文

我是Python和编程的新手。但是,对于一个艺术项目,我花了上周学习使用Python进行编程,并找到了情节图书馆。太神奇了!它如此改进了我的代码! 我编写了一个代码,该代码使我可以加载.wav文件,创建3D频谱图并将3D图像导出到.png或HTML文件。 但是,我实际上想拥有的是3D频谱图的.stl或.obj文件(请参见图像)。 我已经尝试了一些事情,例如。我找到了一个在.stl中转动.png的页面。这是一个很好的选择,但不是我想要的。我有了另一个想法,我将在哪里制作3D频谱图的x .png切片,然后从切片中构建.stl。

我想知道,也许您中的某人有另一个想法或建议将3D图导出到.stl/.obj文件中,甚至绘制了3D频谱图,并立即将其导出到.stl或.obj。

非常感谢您的帮助=) 最好的 甜心90 3D光谱图

I am very new to python and programming in general. However, for an art project, I have spent the last week learning to program using python and found the plotly library. So amazing! It improved my code so much!
I have written a code which lets me load in .wav files, creating a 3D spectrogram and exporting the 3D image to either a .png or html file.
However, what I actually wanted to have is an .stl or .obj file of the 3D spectrogram (see image attached).
I have already tried a few things, eg. I found a page which turns .png in .stl. It is a good alternative but it’s not what I was looking for. I had another idea where I would make x .png slices of the 3D spectrogram and then build a .stl from the slices.

I was wondering, maybe someone of you has another idea or advice to export the 3D plot into a .stl/.obj file or even plot a 3D spectrogram and immediately export it to .stl or .obj.

Thank you very much in advance for your help =)
Bests,
Sweetheart90
3D spectrogram plot

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花开浅夏 2025-02-06 14:16:11

不那么容易。您需要将顶点连接到三角网格(形状n,3,3)
然后,您可以使用MK_STL_MESH生成和Export_stl_mesh来保存:

def export_stl_mesh(*args, fileName:str, **kwargs):
    """
        exports geoms mesh as stl file
        call like:  im_ex_port.export_stl_mesh( np.flip(d.vtx[0][d.geoms[0].mesh], -1 ), 
                                    fileName=f"{g.name}_{str(g.gId)}")
    """
    content = mk_stl_mesh(*args, **kwargs)
    exportPath = os.path.join(sts.mediaPath, 'stls', f"{fileName}.stl")
    with open(exportPath, 'wb') as f:
        f.write(content.encode('ascii'))
    print(f"stl saved to exportPath: \n{exportPath}")

def mk_stl_mesh(mesh, *args, **kwargs):
    bounds = f"solid Exported from geometries.py" + '\n'
    content = bounds
    for triangle in mesh.reshape(-1, 3, 3):
        content += ('facet normal 0.000000 0.000000 1.000000' + '\n')
        content += ('outer loop' + '\n')
        for point in triangle:
            content += (f"vertex {' '.join([f'{t:6f}' for t in point])}" + '\n')
        content += ('endloop' + '\n')
        content += ('endfacet' + '\n')
    content += ('end' + bounds)
    return content

我忘了提及几个要点来完成答案:

  1. 函数中有一些变量,例如MediaPath,您必须将其更改为您想要的任何变量。
  2. 最关键的部分不是显然要创建网格。从“编码火车”中有一个编码挑战25,可以帮助您在那里。这是JavaScript,但这个想法是相同的。
  3. 您应该使用Numpy来做到这一点。还有一个numpy.stl库,它可能具有您需要的内容。

玩得开心

Not that easy. You need to connect your vertices to a triangle mesh (shape n, 3, 3)
Then you can use mk_stl_mesh to generate and export_stl_mesh to save:

def export_stl_mesh(*args, fileName:str, **kwargs):
    """
        exports geoms mesh as stl file
        call like:  im_ex_port.export_stl_mesh( np.flip(d.vtx[0][d.geoms[0].mesh], -1 ), 
                                    fileName=f"{g.name}_{str(g.gId)}")
    """
    content = mk_stl_mesh(*args, **kwargs)
    exportPath = os.path.join(sts.mediaPath, 'stls', f"{fileName}.stl")
    with open(exportPath, 'wb') as f:
        f.write(content.encode('ascii'))
    print(f"stl saved to exportPath: \n{exportPath}")

def mk_stl_mesh(mesh, *args, **kwargs):
    bounds = f"solid Exported from geometries.py" + '\n'
    content = bounds
    for triangle in mesh.reshape(-1, 3, 3):
        content += ('facet normal 0.000000 0.000000 1.000000' + '\n')
        content += ('outer loop' + '\n')
        for point in triangle:
            content += (f"vertex {' '.join([f'{t:6f}' for t in point])}" + '\n')
        content += ('endloop' + '\n')
        content += ('endfacet' + '\n')
    content += ('end' + bounds)
    return content

I forgot to mention a couple of important points to complete the answer:

  1. There are some variables in the functions like mediaPath which you must change to whatever you want.
  2. The most critical part is not obviously to create the mesh. There is a coding challenge 25 from "the coding train" that can help you there. It's JavaScript but the idea is the same.
  3. You should use numpy to do this. There is also a numpy.stl library which might have what you need.

Have fun

如何视而不见 2025-02-06 14:16:11

我进一步尝试了一些事情。我在matplob lib中发现了MTRI函数,该功能应绘制带有三角形的3D表面。到目前为止,一切都很好。这是我的代码

import matplotlib.pyplot as plt
from scipy.io import wavfile
import numpy as np
from scipy import signal # spectrogram function
from matplotlib import cm # colour map
import matplotlib.tri as mtri


filename="/Users/sebastiankuhz/Desktop/kunst/Assemblypart1.wav"
samplingFrequency, signalData = wavfile.read(filename)

# basic config
sample_rate = samplingFrequency
sig_len_secs = signalData.shape[0]/samplingFrequency

# generate the signal
timestamps_secs = np.arange(sample_rate*sig_len_secs) / sample_rate
mysignal = signalData

# extract the spectrum
freq_bins, timestamps, spec = signal.spectrogram(mysignal,sample_rate)

z=10.0*np.log10(spec)

tri = mtri.Triangulation(freq_bins,timestamps)


# 3d plot
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.plot_surface(freq_bins[:, None], timestamps[None, :], z, cmap=cm.coolwarm)

plt.show()

,我收到错误:“ valueError:x和y必须是相等的1D数组”。

问题:
从编程的角度来看,我理解错误,因为freq_bins和时间戳的数组的长度不相同。但是,在图中,我看到每个时间戳值都具有“专用” freq_bins值和z值。因此,为什么我会收到此错误?

I have further tried things. I found the mtri function in matplob lib which should plot a 3D surface with triangles. so far so good. this is my code

import matplotlib.pyplot as plt
from scipy.io import wavfile
import numpy as np
from scipy import signal # spectrogram function
from matplotlib import cm # colour map
import matplotlib.tri as mtri


filename="/Users/sebastiankuhz/Desktop/kunst/Assemblypart1.wav"
samplingFrequency, signalData = wavfile.read(filename)

# basic config
sample_rate = samplingFrequency
sig_len_secs = signalData.shape[0]/samplingFrequency

# generate the signal
timestamps_secs = np.arange(sample_rate*sig_len_secs) / sample_rate
mysignal = signalData

# extract the spectrum
freq_bins, timestamps, spec = signal.spectrogram(mysignal,sample_rate)

z=10.0*np.log10(spec)

tri = mtri.Triangulation(freq_bins,timestamps)


# 3d plot
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.plot_surface(freq_bins[:, None], timestamps[None, :], z, cmap=cm.coolwarm)

plt.show()

Now, I receive the error: "ValueError: x and y must be equal-length 1D arrays".

Question:
From a programming point of view, I understand the error, as the length of the arrays of the freq_bins and the timestamps are not the same. However in the plot I see that every timestamps value has "dedicated" freq_bins values and also z values. Thus, why do I then receive this error?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文