安装Blender并使用

前言

该系列记录了如何用Blenderpro来构建自己的场景数据集,从环境搭建到后期构建数据集的整个流程

本文章是第一部分,BlenderPrc2的安装以及环境配置

部分参考https://blog.csdn.net/weixin_49521551/article/details/121573334
官方文档https://dlr-rm.github.io/BlenderProc/

一、Blenderpro是什么?

一个用于真实感渲染的程序性 Blender pipeline。

二、使用步骤

1.创建虚拟环境

为了方便日后的环境管理,我们在anaconda新建一个虚拟环境进行Blenderproc的安装,anaconda安装过程略,新环境命令如下:

conda create -n blender python=3.7  # blender处为你的虚拟环境名称
conda activate blender

2.安装Blenderproc(这一步直接按github官方教程走)

blenderproc的安装有两种方式,第一种是通过github安装,第二种是使用使用更简便的pip方式

via pip

在虚拟环境下直接执行
代码如下:

pip install Blenderproc

via github

但是不建议这样安装,还是使用作者在github上的Readme.md安装步骤更为合适

具体步骤为

git clone https://github.com/DLR-RM/BlenderProc
cd BlenderProc
pip install -e .

之后终端执行命令:

blenderproc run quickstart.py

如果环境没有问题,则会直接生成output文件夹,里面会生成输出的0.hdf5

但是一般环境都是不全的,所以下面介绍环境安装细节

三.配置环境

1.bug1

当运行代码时,发现会出现问题,如:

第一次运行blenderproc run quickstart.py时,会自动在blender官网下载blender软件的安装包,这个过程报错:urllib.error.HTTPError:HTTP Error 403:Forbidden

意味着需要在官网下载blender并安装,但是由于网路问题没有下载成功,给出解决办法:

手动下载安装包,并安装在路径/home/usename/下即可

2.bug2

当运行代码时,发现会出现问题,如:

[BUG]: Error: ModuleNotFoundError: No module named 'skimage' 

意味着当前环境代码找不到scikit-image包,当然也能是找不到其他的包,比如imageio、opencv等都有可能。那么就需要安装这个包,最直接的方法当然是

pip install scikit-image

但是这个是错误的,因为blenderproc是一个单独的环境,自己是看不到的,实在想找其实是在blener的安装路径下的python/site-package下,那么解决方法就是使用指令

blenderproc pip install scikit-image

如果没有解决,可以尝试先卸载,再安装,并加上参数

blenderproc pip uninstall scikit-image
blenderproc pip install scikit-image --not-use-custom-package-path

这会将 scikit-image安装到 blenders 站点包文件夹中,而不是我们的自定义文件夹。
现在,脚本应该可以正常运行。

参考链接:https://github.com/DLR-RM/BlenderProc/issues/855

3.bug3

当运行代码时,发现会出现问题,如:

【错误记录/Blender】python中使用bpy模块

那还不简单,直接

pip install bpy

但是不行,会出现不知名问题,解决办法是下载离线包,再手动安装

地址如下:Releases · TylerGubala/blenderpy

然后再运行指令,即可安装成功

pip install bpy-2.91a0-cp37-cp37m-manylinux2014_x86_64.whl && bpy_post_install

这样在pip list里就可以找到bpy了

参考链接:https://blog.csdn.net/qq_33446100/article/details/117591371

4.bug4

当运行代码时,发现会出现问题,如:

【错误记录/mathutils】python中使用mathutils模块

使用blenderproc的时候,需要安装mathutils,但是直接pip会出现问题

官方安装方法

这里是mathutils的库,里面写了安装方式:

mathutils 3.3.0 on PyPI - Libraries.io

git clone https://gitlab.com/ideasman42/blender-mathutils.git
cd blender-mathutils# To build you can choose between pythons distutils or CMake.
# distutils:
python setup.py build
sudo python setup.py install# CMake:
cmake .
make
sudo make install# 非root模式可以去掉sudo

但是如果python版本在3.8及其以下,会在install时报错,原因在于PyModule_AddType无法解析,这里参考了其他帖子中评论的方法已解决该问题。

解决方式:

①把src/mathutils/mathutils.c中的PyModule_AddType改成PyModule_AddObject,

②把参数改成三个,中间设置一个参数接收moudle名称,要记得在前面先初始化

  char *mod_name;#### 略/* each type has its own new() function */PyModule_AddObject(mod, mod_name, &vector_Type);PyModule_AddObject(mod, mod_name, &matrix_Type);PyModule_AddObject(mod, mod_name, &euler_Type);PyModule_AddObject(mod, mod_name, &quaternion_Type);PyModule_AddObject(mod, mod_name, &color_Type);

③把 y = _Py_HashDouble(NULL, (double)(array[i++]))中的NULL删掉

以上步骤执行完成后,按照官方安装方法继续执行即可。

src/mathutils/mathutils.c修改后的完整代码:

/* SPDX-License-Identifier: GPL-2.0-or-later *//** \file* \ingroup pymathutils*/#include <Python.h>#include "mathutils.h"#include "BLI_math.h"
#include "BLI_utildefines.h"#include "../generic/py_capi_utils.h"
#include "../generic/python_utildefines.h"#ifndef MATH_STANDALONE
#  include "BLI_dynstr.h"
#endifPyDoc_STRVAR(M_Mathutils_doc,"This module provides access to math operations.\n""\n"".. note::\n""\n""   Classes, methods and attributes that accept vectors also accept other numeric sequences,\n""   such as tuples, lists.\n""\n""The :mod:`mathutils` module provides the following classes:\n""\n""- :class:`Color`,\n""- :class:`Euler`,\n""- :class:`Matrix`,\n""- :class:`Quaternion`,\n""- :class:`Vector`,\n");
static int mathutils_array_parse_fast(float *array,int size,PyObject *value_fast,const char *error_prefix)
{PyObject *item;PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);int i;i = size;do {i--;if (((array[i] = PyFloat_AsDouble((item = value_fast_items[i]))) == -1.0f) &&PyErr_Occurred()) {PyErr_Format(PyExc_TypeError,"%.200s: sequence index %d expected a number, ""found '%.200s' type, ",error_prefix,i,Py_TYPE(item)->tp_name);size = -1;break;}} while (i);return size;
}Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
{int i;Py_uhash_t x; /* Unsigned for defined overflow behavior. */Py_hash_t y;Py_uhash_t mult;Py_ssize_t len;mult = _PyHASH_MULTIPLIER;len = array_len;x = 0x345678UL;i = 0;while (--len >= 0) {y = _Py_HashDouble((double)(array[i++]));if (y == -1) {return -1;}x = (x ^ y) * mult;/* the cast might truncate len; that doesn't change hash stability */mult += (Py_hash_t)(82520UL + len + len);}x += 97531UL;if (x == (Py_uhash_t)-1) {x = -2;}return x;
}int mathutils_array_parse(float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
{const uint flag = array_num_max;int num;array_num_max &= ~MU_ARRAY_FLAGS;#if 1 /* approx 6x speedup for mathutils types */if ((num = VectorObject_Check(value) ? ((VectorObject *)value)->vec_num : 0) ||(num = EulerObject_Check(value) ? 3 : 0) || (num = QuaternionObject_Check(value) ? 4 : 0) ||(num = ColorObject_Check(value) ? 3 : 0)) {if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {return -1;}if (flag & MU_ARRAY_SPILL) {CLAMP_MAX(num, array_num_max);}if (num > array_num_max || num < array_num_min) {if (array_num_max == array_num_min) {PyErr_Format(PyExc_ValueError,"%.200s: sequence length is %d, expected %d",error_prefix,num,array_num_max);}else {PyErr_Format(PyExc_ValueError,"%.200s: sequence length is %d, expected [%d - %d]",error_prefix,num,array_num_min,array_num_max);}return -1;}memcpy(array, ((const BaseMathObject *)value)->data, num * sizeof(float));}else
#endif{PyObject *value_fast = NULL;/* non list/tuple cases */if (!(value_fast = PySequence_Fast(value, error_prefix))) {/* PySequence_Fast sets the error */return -1;}num = PySequence_Fast_GET_SIZE(value_fast);if (flag & MU_ARRAY_SPILL) {CLAMP_MAX(num, array_num_max);}if (num > array_num_max || num < array_num_min) {if (array_num_max == array_num_min) {PyErr_Format(PyExc_ValueError,"%.200s: sequence length is %d, expected %d",error_prefix,num,array_num_max);}else {PyErr_Format(PyExc_ValueError,"%.200s: sequence length is %d, expected [%d - %d]",error_prefix,num,array_num_min,array_num_max);}Py_DECREF(value_fast);return -1;}num = mathutils_array_parse_fast(array, num, value_fast, error_prefix);Py_DECREF(value_fast);}if (num != -1) {if (flag & MU_ARRAY_ZERO) {const int array_num_left = array_num_max - num;if (array_num_left) {memset(&array[num], 0, sizeof(float) * array_num_left);}}}return num;
}int mathutils_array_parse_alloc(float **array,int array_num,PyObject *value,const char *error_prefix)
{int num;#if 1 /* approx 6x speedup for mathutils types */if ((num = VectorObject_Check(value) ? ((VectorObject *)value)->vec_num : 0) ||(num = EulerObject_Check(value) ? 3 : 0) || (num = QuaternionObject_Check(value) ? 4 : 0) ||(num = ColorObject_Check(value) ? 3 : 0)) {if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {return -1;}if (num < array_num) {PyErr_Format(PyExc_ValueError,"%.200s: sequence size is %d, expected > %d",error_prefix,num,array_num);return -1;}*array = PyMem_Malloc(num * sizeof(float));memcpy(*array, ((const BaseMathObject *)value)->data, num * sizeof(float));return num;}#endifPyObject *value_fast = NULL;// *array = NULL;int ret;/* non list/tuple cases */if (!(value_fast = PySequence_Fast(value, error_prefix))) {/* PySequence_Fast sets the error */return -1;}num = PySequence_Fast_GET_SIZE(value_fast);if (num < array_num) {Py_DECREF(value_fast);PyErr_Format(PyExc_ValueError,"%.200s: sequence size is %d, expected > %d",error_prefix,num,array_num);return -1;}*array = PyMem_Malloc(num * sizeof(float));ret = mathutils_array_parse_fast(*array, num, value_fast, error_prefix);Py_DECREF(value_fast);if (ret == -1) {PyMem_Free(*array);}return ret;
}int mathutils_array_parse_alloc_v(float **array,int array_dim,PyObject *value,const char *error_prefix)
{PyObject *value_fast;const int array_dim_flag = array_dim;int i, num;/* non list/tuple cases */if (!(value_fast = PySequence_Fast(value, error_prefix))) {/* PySequence_Fast sets the error */return -1;}num = PySequence_Fast_GET_SIZE(value_fast);if (num != 0) {PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);float *fp;array_dim &= ~MU_ARRAY_FLAGS;fp = *array = PyMem_Malloc(num * array_dim * sizeof(float));for (i = 0; i < num; i++, fp += array_dim) {PyObject *item = value_fast_items[i];if (mathutils_array_parse(fp, array_dim, array_dim_flag, item, error_prefix) == -1) {PyMem_Free(*array);*array = NULL;num = -1;break;}}}Py_DECREF(value_fast);return num;
}int mathutils_int_array_parse(int *array, int array_dim, PyObject *value, const char *error_prefix)
{int size, i;PyObject *value_fast, **value_fast_items, *item;if (!(value_fast = PySequence_Fast(value, error_prefix))) {/* PySequence_Fast sets the error */return -1;}if ((size = PySequence_Fast_GET_SIZE(value_fast)) != array_dim) {PyErr_Format(PyExc_ValueError,"%.200s: sequence size is %d, expected %d",error_prefix,size,array_dim);Py_DECREF(value_fast);return -1;}value_fast_items = PySequence_Fast_ITEMS(value_fast);i = size;while (i > 0) {i--;if (((array[i] = PyC_Long_AsI32((item = value_fast_items[i]))) == -1) && PyErr_Occurred()) {PyErr_Format(PyExc_TypeError, "%.200s: sequence index %d expected an int", error_prefix, i);size = -1;break;}}Py_DECREF(value_fast);return size;
}int mathutils_array_parse_alloc_vi(int **array,int array_dim,PyObject *value,const char *error_prefix)
{PyObject *value_fast;int i, size;if (!(value_fast = PySequence_Fast(value, error_prefix))) {/* PySequence_Fast sets the error */return -1;}size = PySequence_Fast_GET_SIZE(value_fast);if (size != 0) {PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);int *ip;ip = *array = PyMem_Malloc(size * array_dim * sizeof(int));for (i = 0; i < size; i++, ip += array_dim) {PyObject *item = value_fast_items[i];if (mathutils_int_array_parse(ip, array_dim, item, error_prefix) == -1) {PyMem_Free(*array);*array = NULL;size = -1;break;}}}Py_DECREF(value_fast);return size;
}int mathutils_array_parse_alloc_viseq(int **array, int **start_table, int **len_table, PyObject *value, const char *error_prefix)
{PyObject *value_fast, *subseq;int i, size, start, subseq_len;int *ip;*array = NULL;*start_table = NULL;*len_table = NULL;if (!(value_fast = PySequence_Fast(value, error_prefix))) {/* PySequence_Fast sets the error */return -1;}size = PySequence_Fast_GET_SIZE(value_fast);if (size != 0) {PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);*start_table = PyMem_Malloc(size * sizeof(int));*len_table = PyMem_Malloc(size * sizeof(int));/* First pass to set starts and len, and calculate size of array needed */start = 0;for (i = 0; i < size; i++) {subseq = value_fast_items[i];if ((subseq_len = (int)PySequence_Size(subseq)) == -1) {PyErr_Format(PyExc_ValueError, "%.200s: sequence expected to have subsequences", error_prefix);PyMem_Free(*start_table);PyMem_Free(*len_table);Py_DECREF(value_fast);*start_table = NULL;*len_table = NULL;return -1;}(*start_table)[i] = start;(*len_table)[i] = subseq_len;start += subseq_len;}ip = *array = PyMem_Malloc(start * sizeof(int));/* Second pass to parse the subsequences into array */for (i = 0; i < size; i++) {subseq = value_fast_items[i];subseq_len = (*len_table)[i];if (mathutils_int_array_parse(ip, subseq_len, subseq, error_prefix) == -1) {PyMem_Free(*array);PyMem_Free(*start_table);PyMem_Free(*len_table);*array = NULL;*len_table = NULL;*start_table = NULL;size = -1;break;}ip += subseq_len;}}Py_DECREF(value_fast);return size;
}int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix)
{if (EulerObject_Check(value)) {if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {return -1;}eulO_to_mat3(rmat, ((const EulerObject *)value)->eul, ((const EulerObject *)value)->order);return 0;}if (QuaternionObject_Check(value)) {if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {return -1;}float tquat[4];normalize_qt_qt(tquat, ((const QuaternionObject *)value)->quat);quat_to_mat3(rmat, tquat);return 0;}if (MatrixObject_Check(value)) {if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {return -1;}if (((MatrixObject *)value)->row_num < 3 || ((MatrixObject *)value)->col_num < 3) {PyErr_Format(PyExc_ValueError, "%.200s: matrix must have minimum 3x3 dimensions", error_prefix);return -1;}matrix_as_3x3(rmat, (MatrixObject *)value);normalize_m3(rmat);return 0;}PyErr_Format(PyExc_TypeError,"%.200s: expected a Euler, Quaternion or Matrix type, ""found %.200s",error_prefix,Py_TYPE(value)->tp_name);return -1;
}/* ----------------------------------MATRIX FUNCTIONS-------------------- *//* Utility functions *//* LomontRRDCompare4, Ever Faster Float Comparisons by Randy Dillon */
/* XXX We may want to use 'safer' BLI's compare_ff_relative ultimately?* LomontRRDCompare4() is an optimized version of Dawson's AlmostEqual2sComplement()* (see [1] and [2]).* Dawson himself now claims this is not a 'safe' thing to do* (pushing ULP method beyond its limits),* an recommends using work from [3] instead, which is done in BLI func...** [1] http://www.randydillon.org/Papers/2007/everfast.htm* [2] http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm* [3] https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/* instead.*/
#define SIGNMASK(i) (-(int)(((uint)(i)) >> 31))int EXPP_FloatsAreEqual(float af, float bf, int maxDiff)
{/* solid, fast routine across all platforms* with constant time behavior */const int ai = *(const int *)(&af);const int bi = *(const int *)(&bf);const int test = SIGNMASK(ai ^ bi);int diff, v1, v2;BLI_assert((0 == test) || (0xFFFFFFFF == test));diff = (ai ^ (test & 0x7fffffff)) - bi;v1 = maxDiff + diff;v2 = maxDiff - diff;return (v1 | v2) >= 0;
}/*---------------------- EXPP_VectorsAreEqual -------------------------* Builds on EXPP_FloatsAreEqual to test vectors */
int EXPP_VectorsAreEqual(const float *vecA, const float *vecB, int size, int floatSteps)
{int x;for (x = 0; x < size; x++) {if (EXPP_FloatsAreEqual(vecA[x], vecB[x], floatSteps) == 0) {return 0;}}return 1;
}#ifndef MATH_STANDALONE
PyObject *mathutils_dynstr_to_py(struct DynStr *ds)
{const int ds_len = BLI_dynstr_get_len(ds); /* space for \0 */char *ds_buf = PyMem_Malloc(ds_len + 1);PyObject *ret;BLI_dynstr_get_cstring_ex(ds, ds_buf);BLI_dynstr_free(ds);ret = PyUnicode_FromStringAndSize(ds_buf, ds_len);PyMem_Free(ds_buf);return ret;
}
#endif/* Mathutils Callbacks *//* For mathutils internal use only,* eventually should re-alloc but to start with we only have a few users. */
#define MATHUTILS_TOT_CB 17
static Mathutils_Callback *mathutils_callbacks[MATHUTILS_TOT_CB] = {NULL};uchar Mathutils_RegisterCallback(Mathutils_Callback *cb)
{uchar i;/* find the first free slot */for (i = 0; mathutils_callbacks[i]; i++) {if (mathutils_callbacks[i] == cb) {/* already registered? */return i;}}BLI_assert(i + 1 < MATHUTILS_TOT_CB);mathutils_callbacks[i] = cb;return i;
}int _BaseMathObject_CheckCallback(BaseMathObject *self)
{Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];if (LIKELY(cb->check(self) != -1)) {return 0;}return -1;
}/* use macros to check for NULL */
int _BaseMathObject_ReadCallback(BaseMathObject *self)
{Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];if (LIKELY(cb->get(self, self->cb_subtype) != -1)) {return 0;}if (!PyErr_Occurred()) {PyErr_Format(PyExc_RuntimeError, "%s read, user has become invalid", Py_TYPE(self)->tp_name);}return -1;
}int _BaseMathObject_WriteCallback(BaseMathObject *self)
{Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];if (LIKELY(cb->set(self, self->cb_subtype) != -1)) {return 0;}if (!PyErr_Occurred()) {PyErr_Format(PyExc_RuntimeError, "%s write, user has become invalid", Py_TYPE(self)->tp_name);}return -1;
}int _BaseMathObject_ReadIndexCallback(BaseMathObject *self, int index)
{Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];if (LIKELY(cb->get_index(self, self->cb_subtype, index) != -1)) {return 0;}if (!PyErr_Occurred()) {PyErr_Format(PyExc_RuntimeError, "%s read index, user has become invalid", Py_TYPE(self)->tp_name);}return -1;
}int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index)
{Mathutils_Callback *cb = mathutils_callbacks[self->cb_type];if (LIKELY(cb->set_index(self, self->cb_subtype, index) != -1)) {return 0;}if (!PyErr_Occurred()) {PyErr_Format(PyExc_RuntimeError, "%s write index, user has become invalid", Py_TYPE(self)->tp_name);}return -1;
}void _BaseMathObject_RaiseFrozenExc(const BaseMathObject *self)
{PyErr_Format(PyExc_TypeError, "%s is frozen (immutable)", Py_TYPE(self)->tp_name);
}void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self)
{PyErr_Format(PyExc_TypeError, "%s is not frozen (mutable), call freeze first", Py_TYPE(self)->tp_name);
}/* BaseMathObject generic functions for all mathutils types */
char BaseMathObject_owner_doc[] = "The item this is wrapping or None  (read-only).";
PyObject *BaseMathObject_owner_get(BaseMathObject *self, void *UNUSED(closure))
{PyObject *ret = self->cb_user ? self->cb_user : Py_None;return Py_INCREF_RET(ret);
}char BaseMathObject_is_wrapped_doc[] ="True when this object wraps external data (read-only).\n\n:type: boolean";
PyObject *BaseMathObject_is_wrapped_get(BaseMathObject *self, void *UNUSED(closure))
{return PyBool_FromLong((self->flag & BASE_MATH_FLAG_IS_WRAP) != 0);
}char BaseMathObject_is_frozen_doc[] ="True when this object has been frozen (read-only).\n\n:type: boolean";
PyObject *BaseMathObject_is_frozen_get(BaseMathObject *self, void *UNUSED(closure))
{return PyBool_FromLong((self->flag & BASE_MATH_FLAG_IS_FROZEN) != 0);
}char BaseMathObject_is_valid_doc[] ="True when the owner of this data is valid.\n\n:type: boolean";
PyObject *BaseMathObject_is_valid_get(BaseMathObject *self, void *UNUSED(closure))
{return PyBool_FromLong(BaseMath_CheckCallback(self) == 0);
}char BaseMathObject_freeze_doc[] =".. function:: freeze()\n""\n""   Make this object immutable.\n""\n""   After this the object can be hashed, used in dictionaries & sets.\n""\n""   :return: An instance of this object.\n";
PyObject *BaseMathObject_freeze(BaseMathObject *self)
{if ((self->flag & BASE_MATH_FLAG_IS_WRAP) || (self->cb_user != NULL)) {PyErr_SetString(PyExc_TypeError, "Cannot freeze wrapped/owned data");return NULL;}self->flag |= BASE_MATH_FLAG_IS_FROZEN;return Py_INCREF_RET((PyObject *)self);
}int BaseMathObject_traverse(BaseMathObject *self, visitproc visit, void *arg)
{Py_VISIT(self->cb_user);return 0;
}int BaseMathObject_clear(BaseMathObject *self)
{Py_CLEAR(self->cb_user);return 0;
}void BaseMathObject_dealloc(BaseMathObject *self)
{/* only free non wrapped */if ((self->flag & BASE_MATH_FLAG_IS_WRAP) == 0) {PyMem_Free(self->data);}if (self->cb_user) {PyObject_GC_UnTrack(self);BaseMathObject_clear(self);}Py_TYPE(self)->tp_free(self);  // PyObject_DEL(self); /* breaks sub-types. */
}/*----------------------------MODULE INIT-------------------------*/
static struct PyMethodDef M_Mathutils_methods[] = {{NULL, NULL, 0, NULL},
};static struct PyModuleDef M_Mathutils_module_def = {PyModuleDef_HEAD_INIT,"mathutils",         /* m_name */M_Mathutils_doc,     /* m_doc */0,                   /* m_size */M_Mathutils_methods, /* m_methods */NULL,                /* m_slots */NULL,                /* m_traverse */NULL,                /* m_clear */NULL,                /* m_free */
};/* submodules only */
#include "mathutils_geometry.h"
#include "mathutils_interpolate.h"
#ifndef MATH_STANDALONE
#  include "mathutils_bvhtree.h"
#  include "mathutils_kdtree.h"
#  include "mathutils_noise.h"
#endifPyMODINIT_FUNC PyInit_mathutils(void)
{PyObject *mod;PyObject *submodule;PyObject *sys_modules = PyImport_GetModuleDict();char *mod_name;if (PyType_Ready(&vector_Type) < 0) {return NULL;}if (PyType_Ready(&matrix_Type) < 0) {return NULL;}if (PyType_Ready(&matrix_access_Type) < 0) {return NULL;}if (PyType_Ready(&euler_Type) < 0) {return NULL;}if (PyType_Ready(&quaternion_Type) < 0) {return NULL;}if (PyType_Ready(&color_Type) < 0) {return NULL;}mod = PyModule_Create(&M_Mathutils_module_def);/* each type has its own new() function */PyModule_AddObject(mod, mod_name, &vector_Type);PyModule_AddObject(mod, mod_name, &matrix_Type);PyModule_AddObject(mod, mod_name, &euler_Type);PyModule_AddObject(mod, mod_name, &quaternion_Type);PyModule_AddObject(mod, mod_name, &color_Type);/* submodule */PyModule_AddObject(mod, "geometry", (submodule = PyInit_mathutils_geometry()));/* XXX, python doesn't do imports with this usefully yet* 'from mathutils.geometry import PolyFill'* ...fails without this. */PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);PyModule_AddObject(mod, "interpolate", (submodule = PyInit_mathutils_interpolate()));/* XXX, python doesn't do imports with this usefully yet* 'from mathutils.geometry import PolyFill'* ...fails without this. */PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);#ifndef MATH_STANDALONE/* Noise submodule */PyModule_AddObject(mod, "noise", (submodule = PyInit_mathutils_noise()));PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);/* BVHTree submodule */PyModule_AddObject(mod, "bvhtree", (submodule = PyInit_mathutils_bvhtree()));PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);/* KDTree_3d submodule */PyModule_AddObject(mod, "kdtree", (submodule = PyInit_mathutils_kdtree()));PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
#endifmathutils_matrix_row_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_row_cb);mathutils_matrix_col_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_col_cb);mathutils_matrix_translation_cb_index = Mathutils_RegisterCallback(&mathutils_matrix_translation_cb);return mod;
}

到这里,mathutils也安装完成

参考链接:https://blog.csdn.net/Q_pril/article/details/137771478

5.bug5

当运行代码时,发现会出现问题,如:

No module named 'bop_toolkit_lib'

意味着找不到模块bop_toolkit_lib,需要安装,首先想到的是使用指令

blenderproc pip install bop_toolkit_lib

但是在pip里是没有这个包的,因此不会安装成功,所以这里直接先在github上下载,即运行指令

git clone https://github.com/thodan/bop_toolkit
cd bop_toolkit
pip install -r requirements.txt -e .

安装完之后,还是不会找到模块,因此,解决办法是

blenderproc pip install "git+https://github.com/thodan/bop_toolkit"

参考链接:https://github.com/DLR-RM/BlenderProc/issues/559

四.运行

终端执行命令

blenderproc run quickstart.py

运行之后在目录下会有0.dhf5的文件生成,此时运行

blenderproc vis hdf5 output/0.hdf5

即可将结果进行可视化,结果如图:

到这一步,blenderproc的环境安装配置也就完成了,更多的基础示例可以下载github项目工程并参照示例进行。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/6505.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

json-server的使用(根据json数据一键生成接口)

一.使用目的 在前端开发初期&#xff0c;后端 API 可能还未完成&#xff0c;json-server 可以快速创建模拟的 RESTful API&#xff0c;帮助前端开发者进行开发和测试。 二.安装 npm install json-server //局部安装npm i json-server -g //全局安装 三.使用教程 1.准备一…

MySQL详细安装教程

一、从MySQL官网安装 可以翻译成中文看起来就舒服多了 下载并打开安装包&#xff0c;能看到版本是8.0.36&#xff0c;双击运行或者右键选择打开&#xff0c;打开后是一个安装向导&#xff0c;这个安装向导会先帮我们安装一个 mysql-installer 的程序&#xff0c;再通过该程序安…

qt QErrorMessage详解

1、概述 QErrorMessage是Qt框架中用于显示错误消息的一个对话框类。它提供了一个简单的模态对话框&#xff0c;用于向用户显示错误或警告消息。QErrorMessage通常用于应用程序中&#xff0c;当需要向用户报告错误但不希望中断当前操作时。它提供了一个标准的错误消息界面&…

Vue3安装、创建到使用

vue安装 npm install vuenext # 全局安装 vue-cli npm install -g vue/cli #更新插件 项目中运行 vue upgrade --nextvue create 命令 vue create [options] <app-name> options 选项可以是&#xff1a; -p, --preset <presetName>&#xff1a; 忽略提示符并使用已…

Linux 下执行定时任务之 Systemd Timers

不知道 ECS 因为什么缘故&#xff0c;上面安装的 MySQL 服务老是不定期挂掉&#xff0c;本来想通过 Linux 得 Cron 配置个半小时的定时检测任务&#xff0c;结果一直没有执行&#xff0c;因此又尝试使用了 Systemd Timers 进行了重新配置&#xff0c;简要做个记录。 Systemd Ti…

计算机网络:网络层 —— IP 多播技术

文章目录 基本概念IP多播地址和多播组 IP多播的类型硬件多播将IPv4多播地址映射为多播MAC地址 基本概念 多播&#xff08;Multicast&#xff0c;也称为组播&#xff09;是一种实现“一对多”通信的技术&#xff0c;允许一台或多台主机&#xff08;多播源&#xff09;发送单一数…

OuteTTS:基于纯语言建模的开源文本到语音合成项目,支持语音克隆等多种语音合成任务

❤️ 如果你也关注大模型与 AI 的发展现状&#xff0c;且对大模型应用开发非常感兴趣&#xff0c;我会快速跟你分享最新的感兴趣的 AI 应用和热点信息&#xff0c;也会不定期分享自己的想法和开源实例&#xff0c;欢迎关注我哦&#xff01; &#x1f966; 微信公众号&#xff…

C语言 | Leetcode C语言题解之第540题有序数组中的单一元素

题目&#xff1a; 题解&#xff1a; int singleNonDuplicate(int* nums, int numsSize) {int low 0, high numsSize - 1;while (low < high) {int mid (high - low) / 2 low;mid - mid & 1;if (nums[mid] nums[mid 1]) {low mid 2;} else {high mid;}}return …

【学习笔记】SAP ABAP——数据类型

SAP ABAP——数据类型 SAP模块介绍数据类型内涵数据类型分类预定义数据类型数据字典数据类型用户自定义数据类型 SAP模块介绍 模块模块名称FI财务会计CO管理会计SD销售分销MM物料管理PM工厂维护HR人力资源PS项目管理BW数据仓库BC系统相关PP生产制造 数据类型内涵 ​ 数据类型…

国产服务器平台离线部署k8s和kubesphere(含离线部署新方式)

"信创&#xff1a;鲲鹏麒麟&#xff0c;ARM64架构&#xff0c;实现K8s和Kubesphere的离线部署&#xff0c;全新方式助力企业高效运维。" 本文将深入探讨如何借助鲲鹏CPU(arm64)和操作系统Kylin V10 SP2/SP3,通过KubeKey制作KubeSphere与Kubernetes的离线安装包&#…

SpringBoot在线教育系统:技术与实践

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

初始JavaEE篇——多线程(7):定时器、CAS

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 定时器的使用 定时器的原理 模拟实现定时器 CAS 介绍 CAS的应用场景 解析 AtomicInteger 类 实现自旋锁 CAS的缺陷…

【金融风控】相关业务介绍及代码详解

金融风控相关业务介绍 【了解】项目整体介绍 1.风控业务和风控报表</span> 零售金融产品 相关的指标 风控建模流程 ​ #2.特征工程 特征构造 特征筛选 ​ 3.评分卡模型构建 逻辑回归 集成学习 XGBoost LightGBM 模型评估 ​ #4.样本不均衡问题/异常点检测 【了解】今日…

Spring Bean的作用域和生命周期

在 Spring 框架中&#xff0c;Bean 是用于管理对象的核心组成部分。Spring 的 IoC 容器通过 Bean 的作用域来控制它们的生命周期。理解 Spring Bean 的作用域和生命周期对于开发灵活、高效的 Spring 应用至关重要。 Spring Bean 的五种作用域 Spring 提供了五种 Bean 作用域&a…

Linux 配置JDK

文章目录 一、下载Oracle-JDK1.1、如何正确的下载JDK二、配置JDK环境变量2.1 环境变量配置2.1.1、修改vim /etc/profile 添加jdk的路径一、下载Oracle-JDK 1.1、如何正确的下载JDK 首先我要安装的是oracle-jdk,这个时候什么地方都不要去,就去oracle的官网,然后找到,jdk的下…

adb 常用命令汇总

目录 adb 常用命令 1、显示已连接的设备列表 2、进入设备 3、安装 APK 文件到设备 4、卸载指定包名的应用 5、从设备中复制文件到本地 6、将本地文件复制到设备 7、查看设备日志信息 8、重启设备 9、截取设备屏幕截图 10、屏幕分辨率 11、屏幕密度 12、显示设备的…

人工智能技术:未来生活的“魔法师”

想象一下&#xff0c;未来的某一天&#xff0c;你醒来时&#xff0c;智能助手已经为你准备好了早餐&#xff0c;你的智能家居系统根据你的心情和日程安排调整了室内的光线和音乐&#xff0c;而你的自动驾驶汽车已经在门口等你。这不是科幻小说&#xff0c;这是人工智能技术为我…

JavaWeb

一,JavaWeb JavaWeb就是用Java技术来解决相关web互联网领域的技术。 软件架构模式&#xff1a; 1.BS模式&#xff1a;browser server 浏览器服务器 优点&#xff1a;只需要开发服务器代码&#xff0c;用户下载浏览器&#xff0c;维护方便&#xff1b;减少用户的磁盘空间 缺…

【C++笔记】模版的特化及其编译分离

【C笔记】模版的特化及其编译分离 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】模版的特化及其编译分离前言一.模版1.1非类型模板参数 二.模板的特化2.1特化的定义2.2 函数模板特化2.3底层const2.4 类模板特化 三…

解决:无法在此设备上激活Windows因为无法连接到你的组织的激活服务器

问题&#xff1a; 桌面右下角会出现这个东西&#x1f447; 在设置里查看激活状态就会看到&#x1f447; 解决方法 &#xff1a; 1.打开CMD 搜索CMD&#xff0c;然后以管理员身份运行 2.设置 KMS服务器 1&#xff09;命令行输入&#xff1a; slmgr /skms kms.03k.org 然后…