安装Blender并使用

news2024/11/6 7:02:56

前言

该系列记录了如何用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"
#endif
 
PyDoc_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;
  }
 
#endif
 
  PyObject *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"
#endif
 
PyMODINIT_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);
#endif
 
  mathutils_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.coloradmin.cn/o/2230571.html

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

相关文章

ApsaraMQ Serverless 能力再升级,事件驱动架构赋能 AI 应用

本文整理于 2024 年云栖大会阿里云智能集团高级技术专家金吉祥&#xff08;牟羽&#xff09;带来的主题演讲《ApsaraMQ Serverless 能力再升级&#xff0c;事件驱动架构赋能 AI 应用》 云消息队列 ApsaraMQ 全系列产品 Serverless 化&#xff0c;支持按量付费、自适应弹性、跨可…

栈虚拟机和寄存器虚拟机,有什么不同?

本来这节内容是打算直接讲字节码指令的&#xff0c;但讲之前又必须得先讲指令集架构&#xff0c;而指令集架构又分为两种&#xff0c;一种是基于栈的&#xff0c;一种是基于寄存器的。 那不妨我们这节就单独来讲讲栈虚拟机和寄存器虚拟机&#xff0c;它们有什么不同&#xff0…

Rust整合Elasticsearch

Elasticsearch是什么 Lucene&#xff1a;Java实现的搜索引擎类库 易扩展高性能仅限Java开发不支持水平扩展 Elasticsearch&#xff1a;基于Lucene开发的分布式搜索和分析引擎 支持分布式、水平扩展提高RestfulAPI&#xff0c;可被任何语言调用 Elastic Stack是什么 ELK&a…

【Apache Zookeeper】

一、简介 1、场景 如何让⼀个应⽤中多个独⽴的程序协同⼯作是⼀件⾮常困难的事情。开发这样的应⽤&#xff0c;很容易让很多开发⼈员陷⼊如何使多个程序协同⼯作的逻辑中&#xff0c;最后导致没有时间更好地思考和实现他们⾃⼰的应⽤程序逻辑&#xff1b;又或者开发⼈员对协同…

手把手写Linux第一个小程序 - 进度条(5种版本)

本专栏内容为&#xff1a;Linux学习专栏&#xff0c;分为系统和网络两部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握Linux。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;linux &#x1f69a;代码仓库&#xff1a;小小unicorn的代…

TikTok如何用邮箱注册?用哪种邮箱比较好?

要在TikTok上创建一个账号&#xff0c;首先需要进行注册&#xff0c;这是一个简单但至关重要的步骤。在本篇文章中&#xff0c;我们将详细介绍如何用邮箱注册TikTok的整个过程&#xff0c;包括每个步骤的细节和注意事项。此外&#xff0c;我们还将讨论选择哪种邮箱比较好&#…

LabVIEW在Windows和Linux开发的差异

LabVIEW广泛应用于工程和科研领域的自动化和测量控制系统开发&#xff0c;其在Windows和Linux平台上的开发环境有所不同。这些差异主要体现在操作系统兼容性、硬件支持、软件库和驱动程序、实时系统开发以及部署选择上。以下从各个方面详细对比分析LabVIEW在Windows与Linux系统…

哪个牌子的宠物空气净化器好?口碑好的宠物空气净化器推荐!

哪个牌子的宠物空气净化器好&#xff1f;作为一名家电测评博主&#xff0c;我发现市面上宠物空气净化器的牌子越来越多了&#xff0c;很多厂家都看中了宠物行业的红利&#xff0c;想来分一杯羹&#xff0c;这就导致很多技术不成熟的产品流入了市场。今年我测试了50多台宠物空气…

ios 快捷指令扩展(Intents Extension)简单使用 swift语言

本文介绍使用Xcode15 建立快捷指令的Extension&#xff0c;并描述如何修改快捷指令的IntentHandler&#xff0c;带参数跳转主应用&#xff1b;以及展示多个选项的快捷指令弹框(配置intentdefinition文件)&#xff0c;点击选项带参数跳到主应用的方法 创建快捷指令 快捷指令是…

计算机的错误计算(一百四十一)

摘要 探讨 MATLAB中正弦、余弦的计算精度问题。当自变量为大数时&#xff0c;输出可能出错。 从 IEEE-754-2019 知&#xff0c;三角函数的定义域是实数域。 例1. 计算 直接贴图吧&#xff1a; 这样&#xff0c;MATLAB的输出均为错误结果&#xff0c;即没有正确有效数字。…

医院绩效考核管理系统源码,医院如何构建绩效考核体系?

医院绩效考核管理系统作为现代医院管理的重要组成部分&#xff0c;其核心功能旨在提高医院运营效率、优化资源配置、确保医疗服务质量&#xff0c;以及增强医院竞争力。 业务科室绩效考核体系的构建 临床医疗与医技科室绩效考核的设置 临床医疗的绩效考核采用百分制&#xff…

「C/C++」C/C++标准库之#include<cstdlib>通用工具库

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

Resnet代码实现

图2 18-layer、34-layer的残差结构 图3 50-layer、101-layer、102-layer的残差结构 import torch import torch.nn as nn#这个18或者34层网络的残差模块&#xff0c;根据ResNet的具体实现可以自动匹配 class BasicBlock(nn.Module):conv1 stride1对应的实线残差&#xff0c;因…

为什么大家都在学数字孪生呢?

随着物联网&#xff0c;大数据、人工智能等技术的发展&#xff0c;新一代信息技术与制造业正在深度融合&#xff0c;人们与物理世界的交互方式正在发生转折性的变化。数字化转型正在成为企业的重要战略&#xff0c;而数字孪生则成为全新的焦点。 当下&#xff0c;在数字技术和…

IDEA使用Maven Helper查看整个项目的jar冲突

在插件市场安装Maven Helper&#xff0c;安装好后&#xff0c;重启IDEA&#xff1b;双击打开可能存在jar冲突的pom文件&#xff1b;在右侧面板查看冲突,text是引入的依赖明细&#xff0c;点击Dependecy Analyzer选项卡即可查看冲突的jar。

「Pytorch」如何理解深度学习中的算子(operator)

在深度学习中&#xff0c;“算子”&#xff08;operator&#xff09;通常指的是在神经网络中进行的各种数学运算或函数。这些算子可以是基本的数学操作&#xff0c;如加法、乘法、卷积&#xff0c;也可以是更复杂的变换&#xff0c;如激活函数和池化操作。 主要类型的算子 线性…

Hbuilder html5+沉浸式状态栏

manifest.json源码视图添加 {"statusbar": {"immersed": true }如图&#xff1a; 2、plusready准备&#xff0c;将状态栏字体变黑&#xff0c;不然背景白色、状态栏白色看不到 //2.1 如果你用了mui&#xff0c; mui.plusReady(function(){plus.navigat…

windows/linux注册服务与阿里镜像仓库使用

这里写目录标题 启动Windows将jar注册服务Linux将jar设置开机启动 外网环境编译打包 启动 Windows将jar注册服务 将jar包导入到服务器上&#xff0c;将WinSW工具也放到服务器上。 winSw下载地址&#xff1a;https://github.com/winsw/winsw/releases 依据下图修改xml内容即可…

建筑行业知识库搭建:好处、方法与注意事项

在建筑行业&#xff0c;知识管理对于提升项目效率、降低成本、增强创新能力以及构建竞争优势具有至关重要的作用。搭建一个高效、系统的建筑行业知识库&#xff0c;不仅有助于实现知识的有效沉淀与便捷共享&#xff0c;还能促进知识在项目实践中的灵活应用&#xff0c;从而加速…

Oracle与SQL Server的语法区别

1&#xff09;日期和日期转换函数。 SQL: SELECT A.*, CASE WHEN NVL(PAA009,) OR PAA009 >Convert(Varchar(10), SYSDATE,120) THEN Y ELSE N END AS ActiveUser FROM POWPAA A WHERE PAA001admin or PAA002admin Oracle: SELECT A.*, CASE WHEN NVL(PAA009,) or PAA009&…