Add Chromium-only Blender WebEngine parity work
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_BBox.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
using namespace Freestyle::Geometry;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int BBox_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&BBox_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "BBox", (PyObject *)&BBox_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
BBox_doc,
|
||||
"Class for representing a bounding box.\n"
|
||||
"\n"
|
||||
".. method:: __init__()\n"
|
||||
"\n"
|
||||
" Default constructor.\n");
|
||||
static int BBox_init(BPy_BBox *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->bb = new BBox<Vec3r>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void BBox_dealloc(BPy_BBox *self)
|
||||
{
|
||||
delete self->bb;
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *BBox_repr(BPy_BBox *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("BBox - address: %p", self->bb);
|
||||
}
|
||||
|
||||
/*-----------------------BPy_BBox type definition ------------------------------*/
|
||||
|
||||
PyTypeObject BBox_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "BBox",
|
||||
/*tp_basicsize*/ sizeof(BPy_BBox),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)BBox_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)BBox_repr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ BBox_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)BBox_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,34 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../geometry/BBox.h"
|
||||
#include "../geometry/Geom.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject BBox_Type;
|
||||
|
||||
#define BPy_BBox_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&BBox_Type))
|
||||
|
||||
/*---------------------------Python BPy_BBox structure definition----------*/
|
||||
struct BPy_BBox {
|
||||
PyObject_HEAD
|
||||
Freestyle::BBox<Freestyle::Geometry::Vec3r> *bb;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_BBox visible prototypes-----------*/
|
||||
|
||||
int BBox_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,174 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_BinaryPredicate0D.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
#include "BPy_Interface0D.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int BinaryPredicate0D_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&BinaryPredicate0D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "BinaryPredicate0D", (PyObject *)&BinaryPredicate0D_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
BinaryPredicate0D___doc__,
|
||||
"Base class for binary predicates working on :class:`Interface0D`\n"
|
||||
"objects. A BinaryPredicate0D is typically an ordering relation\n"
|
||||
"between two Interface0D objects. The predicate evaluates a relation\n"
|
||||
"between the two Interface0D instances and returns a boolean value (true\n"
|
||||
"or false). It is used by invoking the __call__() method.\n"
|
||||
"\n"
|
||||
".. method:: __init__()\n"
|
||||
"\n"
|
||||
" Default constructor.\n"
|
||||
"\n"
|
||||
".. method:: __call__(inter1, inter2)\n"
|
||||
"\n"
|
||||
" Must be overload by inherited classes. It evaluates a relation\n"
|
||||
" between two Interface0D objects.\n"
|
||||
"\n"
|
||||
" :param inter1: The first Interface0D object.\n"
|
||||
" :type inter1: :class:`Interface0D`\n"
|
||||
" :param inter2: The second Interface0D object.\n"
|
||||
" :type inter2: :class:`Interface0D`\n"
|
||||
" :return: True or false.\n"
|
||||
" :rtype: bool\n");
|
||||
static int BinaryPredicate0D___init__(BPy_BinaryPredicate0D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->bp0D = new BinaryPredicate0D();
|
||||
self->bp0D->py_bp0D = (PyObject *)self;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void BinaryPredicate0D___dealloc__(BPy_BinaryPredicate0D *self)
|
||||
{
|
||||
delete self->bp0D;
|
||||
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *BinaryPredicate0D___repr__(BPy_BinaryPredicate0D *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("type: %s - address: %p", Py_TYPE(self)->tp_name, self->bp0D);
|
||||
}
|
||||
|
||||
static PyObject *BinaryPredicate0D___call__(BPy_BinaryPredicate0D *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"inter1", "inter2", nullptr};
|
||||
BPy_Interface0D *obj1, *obj2;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!O!", (char **)kwlist, &Interface0D_Type, &obj1, &Interface0D_Type, &obj2))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (typeid(*(self->bp0D)) == typeid(BinaryPredicate0D)) {
|
||||
PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden");
|
||||
return nullptr;
|
||||
}
|
||||
if (self->bp0D->operator()(*(obj1->if0D), *(obj2->if0D)) < 0) {
|
||||
if (!PyErr_Occurred()) {
|
||||
string class_name(Py_TYPE(self)->tp_name);
|
||||
PyErr_SetString(PyExc_RuntimeError, (class_name + " __call__ method failed").c_str());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return PyBool_from_bool(self->bp0D->result);
|
||||
}
|
||||
|
||||
/*----------------------BinaryPredicate0D get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
BinaryPredicate0D_name_doc,
|
||||
"The name of the binary 0D predicate.\n"
|
||||
"\n"
|
||||
":type: str\n");
|
||||
static PyObject *BinaryPredicate0D_name_get(BPy_BinaryPredicate0D *self, void * /*closure*/)
|
||||
{
|
||||
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_BinaryPredicate0D_getseters[] = {
|
||||
{"name",
|
||||
(getter)BinaryPredicate0D_name_get,
|
||||
(setter) nullptr,
|
||||
BinaryPredicate0D_name_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_BinaryPredicate0D type definition ------------------------------*/
|
||||
|
||||
PyTypeObject BinaryPredicate0D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "BinaryPredicate0D",
|
||||
/*tp_basicsize*/ sizeof(BPy_BinaryPredicate0D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)BinaryPredicate0D___dealloc__,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)BinaryPredicate0D___repr__,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ (ternaryfunc)BinaryPredicate0D___call__,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ BinaryPredicate0D___doc__,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_BinaryPredicate0D_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)BinaryPredicate0D___init__,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,34 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../stroke/Predicates0D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject BinaryPredicate0D_Type;
|
||||
|
||||
#define BPy_BinaryPredicate0D_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&BinaryPredicate0D_Type))
|
||||
|
||||
/*---------------------------Python BPy_BinaryPredicate0D structure definition----------*/
|
||||
struct BPy_BinaryPredicate0D {
|
||||
PyObject_HEAD
|
||||
Freestyle::BinaryPredicate0D *bp0D;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_BinaryPredicate0D visible prototypes-----------*/
|
||||
|
||||
int BinaryPredicate0D_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,205 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_BinaryPredicate1D.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
#include "BPy_Interface1D.h"
|
||||
|
||||
#include "BinaryPredicate1D/BPy_FalseBP1D.h"
|
||||
#include "BinaryPredicate1D/BPy_Length2DBP1D.h"
|
||||
#include "BinaryPredicate1D/BPy_SameShapeIdBP1D.h"
|
||||
#include "BinaryPredicate1D/BPy_TrueBP1D.h"
|
||||
#include "BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int BinaryPredicate1D_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&BinaryPredicate1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "BinaryPredicate1D", (PyObject *)&BinaryPredicate1D_Type);
|
||||
|
||||
if (PyType_Ready(&FalseBP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "FalseBP1D", (PyObject *)&FalseBP1D_Type);
|
||||
|
||||
if (PyType_Ready(&Length2DBP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Length2DBP1D", (PyObject *)&Length2DBP1D_Type);
|
||||
|
||||
if (PyType_Ready(&SameShapeIdBP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "SameShapeIdBP1D", (PyObject *)&SameShapeIdBP1D_Type);
|
||||
|
||||
if (PyType_Ready(&TrueBP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "TrueBP1D", (PyObject *)&TrueBP1D_Type);
|
||||
|
||||
if (PyType_Ready(&ViewMapGradientNormBP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(
|
||||
module, "ViewMapGradientNormBP1D", (PyObject *)&ViewMapGradientNormBP1D_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
BinaryPredicate1D___doc__,
|
||||
"Base class for binary predicates working on :class:`Interface1D`\n"
|
||||
"objects. A BinaryPredicate1D is typically an ordering relation\n"
|
||||
"between two Interface1D objects. The predicate evaluates a relation\n"
|
||||
"between the two Interface1D instances and returns a boolean value (true\n"
|
||||
"or false). It is used by invoking the __call__() method.\n"
|
||||
"\n"
|
||||
".. method:: __init__()\n"
|
||||
"\n"
|
||||
" Default constructor.\n"
|
||||
"\n"
|
||||
".. method:: __call__(inter1, inter2)\n"
|
||||
"\n"
|
||||
" Must be overload by inherited classes. It evaluates a relation\n"
|
||||
" between two Interface1D objects.\n"
|
||||
"\n"
|
||||
" :param inter1: The first Interface1D object.\n"
|
||||
" :type inter1: :class:`Interface1D`\n"
|
||||
" :param inter2: The second Interface1D object.\n"
|
||||
" :type inter2: :class:`Interface1D`\n"
|
||||
" :return: True or false.\n"
|
||||
" :rtype: bool\n");
|
||||
static int BinaryPredicate1D___init__(BPy_BinaryPredicate1D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->bp1D = new BinaryPredicate1D();
|
||||
self->bp1D->py_bp1D = (PyObject *)self;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void BinaryPredicate1D___dealloc__(BPy_BinaryPredicate1D *self)
|
||||
{
|
||||
delete self->bp1D;
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *BinaryPredicate1D___repr__(BPy_BinaryPredicate1D *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("type: %s - address: %p", Py_TYPE(self)->tp_name, self->bp1D);
|
||||
}
|
||||
|
||||
static PyObject *BinaryPredicate1D___call__(BPy_BinaryPredicate1D *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"inter1", "inter2", nullptr};
|
||||
BPy_Interface1D *obj1, *obj2;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!O!", (char **)kwlist, &Interface1D_Type, &obj1, &Interface1D_Type, &obj2))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (typeid(*(self->bp1D)) == typeid(BinaryPredicate1D)) {
|
||||
PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden");
|
||||
return nullptr;
|
||||
}
|
||||
if (self->bp1D->operator()(*(obj1->if1D), *(obj2->if1D)) < 0) {
|
||||
if (!PyErr_Occurred()) {
|
||||
string class_name(Py_TYPE(self)->tp_name);
|
||||
PyErr_SetString(PyExc_RuntimeError, (class_name + " __call__ method failed").c_str());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return PyBool_from_bool(self->bp1D->result);
|
||||
}
|
||||
|
||||
/*----------------------BinaryPredicate0D get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
BinaryPredicate1D_name_doc,
|
||||
"The name of the binary 1D predicate.\n"
|
||||
"\n"
|
||||
":type: str\n");
|
||||
static PyObject *BinaryPredicate1D_name_get(BPy_BinaryPredicate1D *self, void * /*closure*/)
|
||||
{
|
||||
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_BinaryPredicate1D_getseters[] = {
|
||||
{"name",
|
||||
(getter)BinaryPredicate1D_name_get,
|
||||
(setter) nullptr,
|
||||
BinaryPredicate1D_name_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_BinaryPredicate1D type definition ------------------------------*/
|
||||
|
||||
PyTypeObject BinaryPredicate1D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "BinaryPredicate1D",
|
||||
/*tp_basicsize*/ sizeof(BPy_BinaryPredicate1D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)BinaryPredicate1D___dealloc__,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)BinaryPredicate1D___repr__,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ (ternaryfunc)BinaryPredicate1D___call__,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ BinaryPredicate1D___doc__,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_BinaryPredicate1D_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)BinaryPredicate1D___init__,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,34 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../stroke/Predicates1D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject BinaryPredicate1D_Type;
|
||||
|
||||
#define BPy_BinaryPredicate1D_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&BinaryPredicate1D_Type))
|
||||
|
||||
/*---------------------------Python BPy_BinaryPredicate1D structure definition----------*/
|
||||
struct BPy_BinaryPredicate1D {
|
||||
PyObject_HEAD
|
||||
Freestyle::BinaryPredicate1D *bp1D;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_BinaryPredicate1D visible prototypes-----------*/
|
||||
|
||||
int BinaryPredicate1D_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,342 @@
|
||||
/* SPDX-FileCopyrightText: 2009-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_ContextFunctions.h"
|
||||
#include "BPy_Convert.h"
|
||||
|
||||
#include "../stroke/ContextFunctions.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------ MODULE FUNCTIONS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ContextFunctions_get_time_stamp___doc__,
|
||||
".. function:: get_time_stamp()\n"
|
||||
"\n"
|
||||
" Returns the system time stamp.\n"
|
||||
"\n"
|
||||
" :return: The system time stamp.\n"
|
||||
" :rtype: int\n");
|
||||
static PyObject *ContextFunctions_get_time_stamp(PyObject * /*self*/)
|
||||
{
|
||||
return PyLong_FromLong(ContextFunctions::GetTimeStampCF());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ContextFunctions_get_canvas_width___doc__,
|
||||
".. function:: get_canvas_width()\n"
|
||||
"\n"
|
||||
" Returns the canvas width.\n"
|
||||
"\n"
|
||||
" :return: The canvas width.\n"
|
||||
" :rtype: int\n");
|
||||
static PyObject *ContextFunctions_get_canvas_width(PyObject * /*self*/)
|
||||
{
|
||||
return PyLong_FromLong(ContextFunctions::GetCanvasWidthCF());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ContextFunctions_get_canvas_height___doc__,
|
||||
".. function:: get_canvas_height()\n"
|
||||
"\n"
|
||||
" Returns the canvas height.\n"
|
||||
"\n"
|
||||
" :return: The canvas height.\n"
|
||||
" :rtype: int\n");
|
||||
static PyObject *ContextFunctions_get_canvas_height(PyObject * /*self*/)
|
||||
{
|
||||
return PyLong_FromLong(ContextFunctions::GetCanvasHeightCF());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ContextFunctions_get_border___doc__,
|
||||
".. function:: get_border()\n"
|
||||
"\n"
|
||||
" Returns the border.\n"
|
||||
"\n"
|
||||
" :return: A tuple of 4 numbers (xmin, ymin, xmax, ymax).\n"
|
||||
" :rtype: tuple[int, int, int, int]\n");
|
||||
static PyObject *ContextFunctions_get_border(PyObject * /*self*/)
|
||||
{
|
||||
BBox<Vec2i> border(ContextFunctions::GetBorderCF());
|
||||
PyObject *v = PyTuple_New(4);
|
||||
PyTuple_SET_ITEMS(v,
|
||||
PyLong_FromLong(border.getMin().x()),
|
||||
PyLong_FromLong(border.getMin().y()),
|
||||
PyLong_FromLong(border.getMax().x()),
|
||||
PyLong_FromLong(border.getMax().y()));
|
||||
return v;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ContextFunctions_load_map___doc__,
|
||||
".. function:: load_map(file_name, map_name, num_levels=4, sigma=1.0)\n"
|
||||
"\n"
|
||||
" Loads an image map for further reading.\n"
|
||||
"\n"
|
||||
" :param file_name: The name of the image file.\n"
|
||||
" :type file_name: str\n"
|
||||
" :param map_name: The name that will be used to access this image.\n"
|
||||
" :type map_name: str\n"
|
||||
" :param num_levels: The number of levels in the map pyramid\n"
|
||||
" (default = 4). If num_levels == 0, the complete pyramid is\n"
|
||||
" built.\n"
|
||||
" :type num_levels: int\n"
|
||||
" :param sigma: The sigma value of the gaussian function.\n"
|
||||
" :type sigma: float\n");
|
||||
static PyObject *ContextFunctions_load_map(PyObject * /*self*/, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"file_name", "map_name", "num_levels", "sigma", nullptr};
|
||||
char *fileName, *mapName;
|
||||
uint nbLevels = 4;
|
||||
float sigma = 1.0;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "ss|If", (char **)kwlist, &fileName, &mapName, &nbLevels, &sigma))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
ContextFunctions::LoadMapCF(fileName, mapName, nbLevels, sigma);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ContextFunctions_read_map_pixel___doc__,
|
||||
".. function:: read_map_pixel(map_name, level, x, y)\n"
|
||||
"\n"
|
||||
" Reads a pixel in a user-defined map.\n"
|
||||
"\n"
|
||||
" :param map_name: The name of the map.\n"
|
||||
" :type map_name: str\n"
|
||||
" :param level: The level of the pyramid in which we wish to read the\n"
|
||||
" pixel.\n"
|
||||
" :type level: int\n"
|
||||
" :param x: The x coordinate of the pixel we wish to read. The origin\n"
|
||||
" is in the lower-left corner.\n"
|
||||
" :type x: int\n"
|
||||
" :param y: The y coordinate of the pixel we wish to read. The origin\n"
|
||||
" is in the lower-left corner.\n"
|
||||
" :type y: int\n"
|
||||
" :return: The floating-point value stored for that pixel.\n"
|
||||
" :rtype: float\n");
|
||||
static PyObject *ContextFunctions_read_map_pixel(PyObject * /*self*/,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"map_name", "level", "x", "y", nullptr};
|
||||
char *mapName;
|
||||
int level;
|
||||
uint x, y;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "siII", (char **)kwlist, &mapName, &level, &x, &y))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return PyFloat_FromDouble(ContextFunctions::ReadMapPixelCF(mapName, level, x, y));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ContextFunctions_read_complete_view_map_pixel___doc__,
|
||||
".. function:: read_complete_view_map_pixel(level, x, y)\n"
|
||||
"\n"
|
||||
" Reads a pixel in the complete view map.\n"
|
||||
"\n"
|
||||
" :param level: The level of the pyramid in which we wish to read the\n"
|
||||
" pixel.\n"
|
||||
" :type level: int\n"
|
||||
" :param x: The x coordinate of the pixel we wish to read. The origin\n"
|
||||
" is in the lower-left corner.\n"
|
||||
" :type x: int\n"
|
||||
" :param y: The y coordinate of the pixel we wish to read. The origin\n"
|
||||
" is in the lower-left corner.\n"
|
||||
" :type y: int\n"
|
||||
" :return: The floating-point value stored for that pixel.\n"
|
||||
" :rtype: float\n");
|
||||
static PyObject *ContextFunctions_read_complete_view_map_pixel(PyObject * /*self*/,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"level", "x", "y", nullptr};
|
||||
int level;
|
||||
uint x, y;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "iII", (char **)kwlist, &level, &x, &y)) {
|
||||
return nullptr;
|
||||
}
|
||||
return PyFloat_FromDouble(ContextFunctions::ReadCompleteViewMapPixelCF(level, x, y));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ContextFunctions_read_directional_view_map_pixel___doc__,
|
||||
".. function:: read_directional_view_map_pixel(orientation, level, x, y)\n"
|
||||
"\n"
|
||||
" Reads a pixel in one of the oriented view map images.\n"
|
||||
"\n"
|
||||
" :param orientation: The number telling which orientation we want to\n"
|
||||
" check.\n"
|
||||
" :type orientation: int\n"
|
||||
" :param level: The level of the pyramid in which we wish to read the\n"
|
||||
" pixel.\n"
|
||||
" :type level: int\n"
|
||||
" :param x: The x coordinate of the pixel we wish to read. The origin\n"
|
||||
" is in the lower-left corner.\n"
|
||||
" :type x: int\n"
|
||||
" :param y: The y coordinate of the pixel we wish to read. The origin\n"
|
||||
" is in the lower-left corner.\n"
|
||||
" :type y: int\n"
|
||||
" :return: The floating-point value stored for that pixel.\n"
|
||||
" :rtype: float\n");
|
||||
static PyObject *ContextFunctions_read_directional_view_map_pixel(PyObject * /*self*/,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"orientation", "level", "x", "y", nullptr};
|
||||
int orientation, level;
|
||||
uint x, y;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "iiII", (char **)kwlist, &orientation, &level, &x, &y))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return PyFloat_FromDouble(
|
||||
ContextFunctions::ReadDirectionalViewMapPixelCF(orientation, level, x, y));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ContextFunctions_get_selected_fedge___doc__,
|
||||
".. function:: get_selected_fedge()\n"
|
||||
"\n"
|
||||
" Returns the selected FEdge.\n"
|
||||
"\n"
|
||||
" :return: The selected FEdge.\n"
|
||||
" :rtype: :class:`FEdge`\n");
|
||||
static PyObject *ContextFunctions_get_selected_fedge(PyObject * /*self*/)
|
||||
{
|
||||
FEdge *fe = ContextFunctions::GetSelectedFEdgeCF();
|
||||
if (fe) {
|
||||
return Any_BPy_FEdge_from_FEdge(*fe);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*-----------------------ContextFunctions module docstring-------------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
module_docstring,
|
||||
"The Blender Freestyle.ContextFunctions submodule\n"
|
||||
"\n");
|
||||
/*-----------------------ContextFunctions module functions definitions-------------------*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef module_functions[] = {
|
||||
{"get_time_stamp",
|
||||
(PyCFunction)ContextFunctions_get_time_stamp,
|
||||
METH_NOARGS,
|
||||
ContextFunctions_get_time_stamp___doc__},
|
||||
{"get_canvas_width",
|
||||
(PyCFunction)ContextFunctions_get_canvas_width,
|
||||
METH_NOARGS,
|
||||
ContextFunctions_get_canvas_width___doc__},
|
||||
{"get_canvas_height",
|
||||
(PyCFunction)ContextFunctions_get_canvas_height,
|
||||
METH_NOARGS,
|
||||
ContextFunctions_get_canvas_height___doc__},
|
||||
{"get_border",
|
||||
(PyCFunction)ContextFunctions_get_border,
|
||||
METH_NOARGS,
|
||||
ContextFunctions_get_border___doc__},
|
||||
{"load_map",
|
||||
(PyCFunction)ContextFunctions_load_map,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
ContextFunctions_load_map___doc__},
|
||||
{"read_map_pixel",
|
||||
(PyCFunction)ContextFunctions_read_map_pixel,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
ContextFunctions_read_map_pixel___doc__},
|
||||
{"read_complete_view_map_pixel",
|
||||
(PyCFunction)ContextFunctions_read_complete_view_map_pixel,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
ContextFunctions_read_complete_view_map_pixel___doc__},
|
||||
{"read_directional_view_map_pixel",
|
||||
(PyCFunction)ContextFunctions_read_directional_view_map_pixel,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
ContextFunctions_read_directional_view_map_pixel___doc__},
|
||||
{"get_selected_fedge",
|
||||
(PyCFunction)ContextFunctions_get_selected_fedge,
|
||||
METH_NOARGS,
|
||||
ContextFunctions_get_selected_fedge___doc__},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*-----------------------ContextFunctions module definition--------------------------------*/
|
||||
|
||||
static PyModuleDef module_definition = {
|
||||
/*m_base*/ PyModuleDef_HEAD_INIT,
|
||||
/*m_name*/ "Freestyle.ContextFunctions",
|
||||
/*m_doc*/ module_docstring,
|
||||
/*m_size*/ -1,
|
||||
/*m_methods*/ module_functions,
|
||||
/*m_slots*/ nullptr,
|
||||
/*m_traverse*/ nullptr,
|
||||
/*m_clear*/ nullptr,
|
||||
/*m_free*/ nullptr,
|
||||
};
|
||||
|
||||
//------------------- MODULE INITIALIZATION --------------------------------
|
||||
|
||||
int ContextFunctions_Init(PyObject *module)
|
||||
{
|
||||
PyObject *m;
|
||||
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
m = PyModule_Create(&module_definition);
|
||||
if (m == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ContextFunctions", m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,17 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
/*---------------------------Python BPy_ContextFunctions visible prototypes-----------*/
|
||||
|
||||
int ContextFunctions_Init(PyObject *module);
|
||||
@@ -0,0 +1,825 @@
|
||||
/* SPDX-FileCopyrightText: 2008-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
|
||||
#include "BPy_BBox.h"
|
||||
#include "BPy_FrsMaterial.h"
|
||||
#include "BPy_Id.h"
|
||||
#include "BPy_IntegrationType.h"
|
||||
#include "BPy_Interface0D.h"
|
||||
#include "BPy_Interface1D.h"
|
||||
#include "BPy_MediumType.h"
|
||||
#include "BPy_Nature.h"
|
||||
#include "BPy_SShape.h"
|
||||
#include "BPy_StrokeAttribute.h"
|
||||
#include "BPy_ViewShape.h"
|
||||
#include "Interface0D/BPy_CurvePoint.h"
|
||||
#include "Interface0D/BPy_SVertex.h"
|
||||
#include "Interface0D/BPy_ViewVertex.h"
|
||||
#include "Interface0D/CurvePoint/BPy_StrokeVertex.h"
|
||||
#include "Interface0D/ViewVertex/BPy_NonTVertex.h"
|
||||
#include "Interface0D/ViewVertex/BPy_TVertex.h"
|
||||
#include "Interface1D/BPy_FEdge.h"
|
||||
#include "Interface1D/BPy_Stroke.h"
|
||||
#include "Interface1D/BPy_ViewEdge.h"
|
||||
#include "Interface1D/Curve/BPy_Chain.h"
|
||||
#include "Interface1D/FEdge/BPy_FEdgeSharp.h"
|
||||
#include "Interface1D/FEdge/BPy_FEdgeSmooth.h"
|
||||
|
||||
#include "Iterator/BPy_AdjacencyIterator.h"
|
||||
#include "Iterator/BPy_ChainPredicateIterator.h"
|
||||
#include "Iterator/BPy_ChainSilhouetteIterator.h"
|
||||
#include "Iterator/BPy_ChainingIterator.h"
|
||||
#include "Iterator/BPy_CurvePointIterator.h"
|
||||
#include "Iterator/BPy_Interface0DIterator.h"
|
||||
#include "Iterator/BPy_SVertexIterator.h"
|
||||
#include "Iterator/BPy_StrokeVertexIterator.h"
|
||||
#include "Iterator/BPy_ViewEdgeIterator.h"
|
||||
#include "Iterator/BPy_orientedViewEdgeIterator.h"
|
||||
|
||||
#include "../stroke/StrokeRep.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
using namespace Freestyle::Geometry;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//==============================
|
||||
// C++ => Python
|
||||
//==============================
|
||||
|
||||
PyObject *PyBool_from_bool(bool b)
|
||||
{
|
||||
return PyBool_FromLong(b ? 1 : 0);
|
||||
}
|
||||
|
||||
PyObject *PyLong_subtype_new(PyTypeObject *ty, long value)
|
||||
{
|
||||
BLI_assert(ty->tp_basicsize == sizeof(PyLongObject));
|
||||
PyLongObject *result = PyObject_NewVar(PyLongObject, ty, 1);
|
||||
PyLongObject *value_py = (PyLongObject *)PyLong_FromLong(value);
|
||||
memcpy(&result->long_value, &value_py->long_value, sizeof(result->long_value));
|
||||
Py_DECREF(value_py);
|
||||
return (PyObject *)result;
|
||||
}
|
||||
|
||||
void PyLong_subtype_add_to_dict(PyObject *dict, PyTypeObject *ty, const char *attr, long value)
|
||||
{
|
||||
PyObject *result = PyLong_subtype_new(ty, value);
|
||||
PyDict_SetItemString(dict, attr, result);
|
||||
/* Owned by the dictionary. */
|
||||
Py_DECREF(result);
|
||||
}
|
||||
|
||||
PyObject *Vector_from_Vec2f(Vec2f &vec)
|
||||
{
|
||||
float vec_data[2]; // because vec->_coord is protected
|
||||
vec_data[0] = vec.x();
|
||||
vec_data[1] = vec.y();
|
||||
return blender::Vector_CreatePyObject(vec_data, 2, nullptr);
|
||||
}
|
||||
|
||||
PyObject *Vector_from_Vec3f(Vec3f &vec)
|
||||
{
|
||||
float vec_data[3]; // because vec->_coord is protected
|
||||
vec_data[0] = vec.x();
|
||||
vec_data[1] = vec.y();
|
||||
vec_data[2] = vec.z();
|
||||
return blender::Vector_CreatePyObject(vec_data, 3, nullptr);
|
||||
}
|
||||
|
||||
PyObject *Vector_from_Vec3r(Vec3r &vec)
|
||||
{
|
||||
float vec_data[3]; // because vec->_coord is protected
|
||||
vec_data[0] = vec.x();
|
||||
vec_data[1] = vec.y();
|
||||
vec_data[2] = vec.z();
|
||||
return blender::Vector_CreatePyObject(vec_data, 3, nullptr);
|
||||
}
|
||||
|
||||
PyObject *BPy_Id_from_Id(Id &id)
|
||||
{
|
||||
PyObject *py_id = Id_Type.tp_new(&Id_Type, nullptr, nullptr);
|
||||
((BPy_Id *)py_id)->id = new Id(id.getFirst(), id.getSecond());
|
||||
return py_id;
|
||||
}
|
||||
|
||||
PyObject *Any_BPy_Interface0D_from_Interface0D(Interface0D &if0D)
|
||||
{
|
||||
if (typeid(if0D) == typeid(CurvePoint)) {
|
||||
return BPy_CurvePoint_from_CurvePoint(dynamic_cast<CurvePoint &>(if0D));
|
||||
}
|
||||
if (typeid(if0D) == typeid(StrokeVertex)) {
|
||||
return BPy_StrokeVertex_from_StrokeVertex(dynamic_cast<StrokeVertex &>(if0D));
|
||||
}
|
||||
if (typeid(if0D) == typeid(SVertex)) {
|
||||
return BPy_SVertex_from_SVertex(dynamic_cast<SVertex &>(if0D));
|
||||
}
|
||||
if (typeid(if0D) == typeid(ViewVertex)) {
|
||||
return BPy_ViewVertex_from_ViewVertex(dynamic_cast<ViewVertex &>(if0D));
|
||||
}
|
||||
if (typeid(if0D) == typeid(NonTVertex)) {
|
||||
return BPy_NonTVertex_from_NonTVertex(dynamic_cast<NonTVertex &>(if0D));
|
||||
}
|
||||
if (typeid(if0D) == typeid(TVertex)) {
|
||||
return BPy_TVertex_from_TVertex(dynamic_cast<TVertex &>(if0D));
|
||||
}
|
||||
if (typeid(if0D) == typeid(Interface0D)) {
|
||||
return BPy_Interface0D_from_Interface0D(if0D);
|
||||
}
|
||||
string msg("unexpected type: " + if0D.getExactTypeName());
|
||||
PyErr_SetString(PyExc_TypeError, msg.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject *Any_BPy_Interface1D_from_Interface1D(Interface1D &if1D)
|
||||
{
|
||||
if (typeid(if1D) == typeid(ViewEdge)) {
|
||||
return BPy_ViewEdge_from_ViewEdge(dynamic_cast<ViewEdge &>(if1D));
|
||||
}
|
||||
if (typeid(if1D) == typeid(Chain)) {
|
||||
return BPy_Chain_from_Chain(dynamic_cast<Chain &>(if1D));
|
||||
}
|
||||
if (typeid(if1D) == typeid(Stroke)) {
|
||||
return BPy_Stroke_from_Stroke(dynamic_cast<Stroke &>(if1D));
|
||||
}
|
||||
if (typeid(if1D) == typeid(FEdgeSharp)) {
|
||||
return BPy_FEdgeSharp_from_FEdgeSharp(dynamic_cast<FEdgeSharp &>(if1D));
|
||||
}
|
||||
if (typeid(if1D) == typeid(FEdgeSmooth)) {
|
||||
return BPy_FEdgeSmooth_from_FEdgeSmooth(dynamic_cast<FEdgeSmooth &>(if1D));
|
||||
}
|
||||
if (typeid(if1D) == typeid(FEdge)) {
|
||||
return BPy_FEdge_from_FEdge(dynamic_cast<FEdge &>(if1D));
|
||||
}
|
||||
if (typeid(if1D) == typeid(Interface1D)) {
|
||||
return BPy_Interface1D_from_Interface1D(if1D);
|
||||
}
|
||||
string msg("unexpected type: " + if1D.getExactTypeName());
|
||||
PyErr_SetString(PyExc_TypeError, msg.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject *Any_BPy_FEdge_from_FEdge(FEdge &fe)
|
||||
{
|
||||
if (typeid(fe) == typeid(FEdgeSharp)) {
|
||||
return BPy_FEdgeSharp_from_FEdgeSharp(dynamic_cast<FEdgeSharp &>(fe));
|
||||
}
|
||||
if (typeid(fe) == typeid(FEdgeSmooth)) {
|
||||
return BPy_FEdgeSmooth_from_FEdgeSmooth(dynamic_cast<FEdgeSmooth &>(fe));
|
||||
}
|
||||
if (typeid(fe) == typeid(FEdge)) {
|
||||
return BPy_FEdge_from_FEdge(fe);
|
||||
}
|
||||
string msg("unexpected type: " + fe.getExactTypeName());
|
||||
PyErr_SetString(PyExc_TypeError, msg.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject *Any_BPy_ViewVertex_from_ViewVertex(ViewVertex &vv)
|
||||
{
|
||||
if (typeid(vv) == typeid(NonTVertex)) {
|
||||
return BPy_NonTVertex_from_NonTVertex(dynamic_cast<NonTVertex &>(vv));
|
||||
}
|
||||
if (typeid(vv) == typeid(TVertex)) {
|
||||
return BPy_TVertex_from_TVertex(dynamic_cast<TVertex &>(vv));
|
||||
}
|
||||
if (typeid(vv) == typeid(ViewVertex)) {
|
||||
return BPy_ViewVertex_from_ViewVertex(vv);
|
||||
}
|
||||
string msg("unexpected type: " + vv.getExactTypeName());
|
||||
PyErr_SetString(PyExc_TypeError, msg.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PyObject *BPy_Interface0D_from_Interface0D(Interface0D &if0D)
|
||||
{
|
||||
PyObject *py_if0D = Interface0D_Type.tp_new(&Interface0D_Type, nullptr, nullptr);
|
||||
((BPy_Interface0D *)py_if0D)->if0D = &if0D;
|
||||
((BPy_Interface0D *)py_if0D)->borrowed = true;
|
||||
return py_if0D;
|
||||
}
|
||||
|
||||
PyObject *BPy_Interface1D_from_Interface1D(Interface1D &if1D)
|
||||
{
|
||||
PyObject *py_if1D = Interface1D_Type.tp_new(&Interface1D_Type, nullptr, nullptr);
|
||||
((BPy_Interface1D *)py_if1D)->if1D = &if1D;
|
||||
((BPy_Interface1D *)py_if1D)->borrowed = true;
|
||||
return py_if1D;
|
||||
}
|
||||
|
||||
PyObject *BPy_SVertex_from_SVertex(SVertex &sv)
|
||||
{
|
||||
PyObject *py_sv = SVertex_Type.tp_new(&SVertex_Type, nullptr, nullptr);
|
||||
((BPy_SVertex *)py_sv)->sv = &sv;
|
||||
((BPy_SVertex *)py_sv)->py_if0D.if0D = ((BPy_SVertex *)py_sv)->sv;
|
||||
((BPy_SVertex *)py_sv)->py_if0D.borrowed = true;
|
||||
return py_sv;
|
||||
}
|
||||
|
||||
PyObject *BPy_FEdgeSharp_from_FEdgeSharp(FEdgeSharp &fes)
|
||||
{
|
||||
PyObject *py_fe = FEdgeSharp_Type.tp_new(&FEdgeSharp_Type, nullptr, nullptr);
|
||||
((BPy_FEdgeSharp *)py_fe)->fes = &fes;
|
||||
((BPy_FEdgeSharp *)py_fe)->py_fe.fe = ((BPy_FEdgeSharp *)py_fe)->fes;
|
||||
((BPy_FEdgeSharp *)py_fe)->py_fe.py_if1D.if1D = ((BPy_FEdgeSharp *)py_fe)->fes;
|
||||
((BPy_FEdgeSharp *)py_fe)->py_fe.py_if1D.borrowed = true;
|
||||
return py_fe;
|
||||
}
|
||||
|
||||
PyObject *BPy_FEdgeSmooth_from_FEdgeSmooth(FEdgeSmooth &fes)
|
||||
{
|
||||
PyObject *py_fe = FEdgeSmooth_Type.tp_new(&FEdgeSmooth_Type, nullptr, nullptr);
|
||||
((BPy_FEdgeSmooth *)py_fe)->fes = &fes;
|
||||
((BPy_FEdgeSmooth *)py_fe)->py_fe.fe = ((BPy_FEdgeSmooth *)py_fe)->fes;
|
||||
((BPy_FEdgeSmooth *)py_fe)->py_fe.py_if1D.if1D = ((BPy_FEdgeSmooth *)py_fe)->fes;
|
||||
((BPy_FEdgeSmooth *)py_fe)->py_fe.py_if1D.borrowed = true;
|
||||
return py_fe;
|
||||
}
|
||||
|
||||
PyObject *BPy_FEdge_from_FEdge(FEdge &fe)
|
||||
{
|
||||
PyObject *py_fe = FEdge_Type.tp_new(&FEdge_Type, nullptr, nullptr);
|
||||
((BPy_FEdge *)py_fe)->fe = &fe;
|
||||
((BPy_FEdge *)py_fe)->py_if1D.if1D = ((BPy_FEdge *)py_fe)->fe;
|
||||
((BPy_FEdge *)py_fe)->py_if1D.borrowed = true;
|
||||
return py_fe;
|
||||
}
|
||||
|
||||
PyObject *BPy_Nature_from_Nature(ushort n)
|
||||
{
|
||||
PyObject *args = PyTuple_New(1);
|
||||
PyTuple_SET_ITEM(args, 0, PyLong_FromLong(n));
|
||||
PyObject *py_n = Nature_Type.tp_new(&Nature_Type, args, nullptr);
|
||||
Py_DECREF(args);
|
||||
return py_n;
|
||||
}
|
||||
|
||||
PyObject *BPy_Stroke_from_Stroke(Stroke &s)
|
||||
{
|
||||
PyObject *py_s = Stroke_Type.tp_new(&Stroke_Type, nullptr, nullptr);
|
||||
((BPy_Stroke *)py_s)->s = &s;
|
||||
((BPy_Stroke *)py_s)->py_if1D.if1D = ((BPy_Stroke *)py_s)->s;
|
||||
((BPy_Stroke *)py_s)->py_if1D.borrowed = true;
|
||||
return py_s;
|
||||
}
|
||||
|
||||
PyObject *BPy_StrokeAttribute_from_StrokeAttribute(StrokeAttribute &sa)
|
||||
{
|
||||
PyObject *py_sa = StrokeAttribute_Type.tp_new(&StrokeAttribute_Type, nullptr, nullptr);
|
||||
((BPy_StrokeAttribute *)py_sa)->sa = &sa;
|
||||
((BPy_StrokeAttribute *)py_sa)->borrowed = true;
|
||||
return py_sa;
|
||||
}
|
||||
|
||||
PyObject *BPy_MediumType_from_MediumType(Stroke::MediumType n)
|
||||
{
|
||||
PyObject *args = PyTuple_New(1);
|
||||
PyTuple_SET_ITEM(args, 0, PyLong_FromLong(n));
|
||||
PyObject *py_mt = MediumType_Type.tp_new(&MediumType_Type, args, nullptr);
|
||||
Py_DECREF(args);
|
||||
return py_mt;
|
||||
}
|
||||
|
||||
PyObject *BPy_StrokeVertex_from_StrokeVertex(StrokeVertex &sv)
|
||||
{
|
||||
PyObject *py_sv = StrokeVertex_Type.tp_new(&StrokeVertex_Type, nullptr, nullptr);
|
||||
((BPy_StrokeVertex *)py_sv)->sv = &sv;
|
||||
((BPy_StrokeVertex *)py_sv)->py_cp.cp = ((BPy_StrokeVertex *)py_sv)->sv;
|
||||
((BPy_StrokeVertex *)py_sv)->py_cp.py_if0D.if0D = ((BPy_StrokeVertex *)py_sv)->sv;
|
||||
((BPy_StrokeVertex *)py_sv)->py_cp.py_if0D.borrowed = true;
|
||||
return py_sv;
|
||||
}
|
||||
|
||||
PyObject *BPy_ViewVertex_from_ViewVertex(ViewVertex &vv)
|
||||
{
|
||||
PyObject *py_vv = ViewVertex_Type.tp_new(&ViewVertex_Type, nullptr, nullptr);
|
||||
((BPy_ViewVertex *)py_vv)->vv = &vv;
|
||||
((BPy_ViewVertex *)py_vv)->py_if0D.if0D = ((BPy_ViewVertex *)py_vv)->vv;
|
||||
((BPy_ViewVertex *)py_vv)->py_if0D.borrowed = true;
|
||||
return py_vv;
|
||||
}
|
||||
|
||||
PyObject *BPy_NonTVertex_from_NonTVertex(NonTVertex &ntv)
|
||||
{
|
||||
PyObject *py_ntv = NonTVertex_Type.tp_new(&NonTVertex_Type, nullptr, nullptr);
|
||||
((BPy_NonTVertex *)py_ntv)->ntv = &ntv;
|
||||
((BPy_NonTVertex *)py_ntv)->py_vv.vv = ((BPy_NonTVertex *)py_ntv)->ntv;
|
||||
((BPy_NonTVertex *)py_ntv)->py_vv.py_if0D.if0D = ((BPy_NonTVertex *)py_ntv)->ntv;
|
||||
((BPy_NonTVertex *)py_ntv)->py_vv.py_if0D.borrowed = true;
|
||||
return py_ntv;
|
||||
}
|
||||
|
||||
PyObject *BPy_TVertex_from_TVertex(TVertex &tv)
|
||||
{
|
||||
PyObject *py_tv = TVertex_Type.tp_new(&TVertex_Type, nullptr, nullptr);
|
||||
((BPy_TVertex *)py_tv)->tv = &tv;
|
||||
((BPy_TVertex *)py_tv)->py_vv.vv = ((BPy_TVertex *)py_tv)->tv;
|
||||
((BPy_TVertex *)py_tv)->py_vv.py_if0D.if0D = ((BPy_TVertex *)py_tv)->tv;
|
||||
((BPy_TVertex *)py_tv)->py_vv.py_if0D.borrowed = true;
|
||||
return py_tv;
|
||||
}
|
||||
|
||||
PyObject *BPy_BBox_from_BBox(const BBox<Vec3r> &bb)
|
||||
{
|
||||
PyObject *py_bb = BBox_Type.tp_new(&BBox_Type, nullptr, nullptr);
|
||||
((BPy_BBox *)py_bb)->bb = new BBox<Vec3r>(bb);
|
||||
return py_bb;
|
||||
}
|
||||
|
||||
PyObject *BPy_ViewEdge_from_ViewEdge(ViewEdge &ve)
|
||||
{
|
||||
PyObject *py_ve = ViewEdge_Type.tp_new(&ViewEdge_Type, nullptr, nullptr);
|
||||
((BPy_ViewEdge *)py_ve)->ve = &ve;
|
||||
((BPy_ViewEdge *)py_ve)->py_if1D.if1D = ((BPy_ViewEdge *)py_ve)->ve;
|
||||
((BPy_ViewEdge *)py_ve)->py_if1D.borrowed = true;
|
||||
return py_ve;
|
||||
}
|
||||
|
||||
PyObject *BPy_Chain_from_Chain(Chain &c)
|
||||
{
|
||||
PyObject *py_c = Chain_Type.tp_new(&Chain_Type, nullptr, nullptr);
|
||||
((BPy_Chain *)py_c)->c = &c;
|
||||
((BPy_Chain *)py_c)->py_c.c = ((BPy_Chain *)py_c)->c;
|
||||
((BPy_Chain *)py_c)->py_c.py_if1D.if1D = ((BPy_Chain *)py_c)->c;
|
||||
((BPy_Chain *)py_c)->py_c.py_if1D.borrowed = true;
|
||||
return py_c;
|
||||
}
|
||||
|
||||
PyObject *BPy_SShape_from_SShape(SShape &ss)
|
||||
{
|
||||
PyObject *py_ss = SShape_Type.tp_new(&SShape_Type, nullptr, nullptr);
|
||||
((BPy_SShape *)py_ss)->ss = &ss;
|
||||
((BPy_SShape *)py_ss)->borrowed = true;
|
||||
return py_ss;
|
||||
}
|
||||
|
||||
PyObject *BPy_ViewShape_from_ViewShape(ViewShape &vs)
|
||||
{
|
||||
PyObject *py_vs = ViewShape_Type.tp_new(&ViewShape_Type, nullptr, nullptr);
|
||||
((BPy_ViewShape *)py_vs)->vs = &vs;
|
||||
((BPy_ViewShape *)py_vs)->borrowed = true;
|
||||
((BPy_ViewShape *)py_vs)->py_ss = nullptr;
|
||||
return py_vs;
|
||||
}
|
||||
|
||||
PyObject *BPy_FrsMaterial_from_FrsMaterial(const FrsMaterial &m)
|
||||
{
|
||||
PyObject *py_m = FrsMaterial_Type.tp_new(&FrsMaterial_Type, nullptr, nullptr);
|
||||
((BPy_FrsMaterial *)py_m)->m = new FrsMaterial(m);
|
||||
return py_m;
|
||||
}
|
||||
|
||||
PyObject *BPy_IntegrationType_from_IntegrationType(IntegrationType i)
|
||||
{
|
||||
PyObject *args = PyTuple_New(1);
|
||||
PyTuple_SET_ITEM(args, 0, PyLong_FromLong(i));
|
||||
PyObject *py_it = IntegrationType_Type.tp_new(&IntegrationType_Type, args, nullptr);
|
||||
Py_DECREF(args);
|
||||
return py_it;
|
||||
}
|
||||
|
||||
PyObject *BPy_CurvePoint_from_CurvePoint(CurvePoint &cp)
|
||||
{
|
||||
PyObject *py_cp = CurvePoint_Type.tp_new(&CurvePoint_Type, nullptr, nullptr);
|
||||
// CurvePointIterator::operator*() returns a reference of a class data
|
||||
// member whose value is mutable upon iteration over different CurvePoints.
|
||||
// It is likely that such a mutable reference is passed to this function,
|
||||
// so that a new allocated CurvePoint instance is created here to avoid
|
||||
// nasty bugs (cf. #41464).
|
||||
((BPy_CurvePoint *)py_cp)->cp = new CurvePoint(cp);
|
||||
((BPy_CurvePoint *)py_cp)->py_if0D.if0D = ((BPy_CurvePoint *)py_cp)->cp;
|
||||
((BPy_CurvePoint *)py_cp)->py_if0D.borrowed = false;
|
||||
return py_cp;
|
||||
}
|
||||
|
||||
PyObject *BPy_directedViewEdge_from_directedViewEdge(ViewVertex::directedViewEdge &dve)
|
||||
{
|
||||
PyObject *py_dve = PyTuple_New(2);
|
||||
PyTuple_SET_ITEMS(
|
||||
py_dve, BPy_ViewEdge_from_ViewEdge(*(dve.first)), PyBool_from_bool(dve.second));
|
||||
return py_dve;
|
||||
}
|
||||
|
||||
//==============================
|
||||
// Iterators
|
||||
//==============================
|
||||
|
||||
PyObject *BPy_AdjacencyIterator_from_AdjacencyIterator(AdjacencyIterator &a_it)
|
||||
{
|
||||
PyObject *py_a_it = AdjacencyIterator_Type.tp_new(&AdjacencyIterator_Type, nullptr, nullptr);
|
||||
((BPy_AdjacencyIterator *)py_a_it)->a_it = new AdjacencyIterator(a_it);
|
||||
((BPy_AdjacencyIterator *)py_a_it)->py_it.it = ((BPy_AdjacencyIterator *)py_a_it)->a_it;
|
||||
((BPy_AdjacencyIterator *)py_a_it)->at_start = true;
|
||||
return py_a_it;
|
||||
}
|
||||
|
||||
PyObject *BPy_Interface0DIterator_from_Interface0DIterator(Interface0DIterator &if0D_it,
|
||||
bool reversed)
|
||||
{
|
||||
PyObject *py_if0D_it = Interface0DIterator_Type.tp_new(
|
||||
&Interface0DIterator_Type, nullptr, nullptr);
|
||||
((BPy_Interface0DIterator *)py_if0D_it)->if0D_it = new Interface0DIterator(if0D_it);
|
||||
((BPy_Interface0DIterator *)py_if0D_it)->py_it.it =
|
||||
((BPy_Interface0DIterator *)py_if0D_it)->if0D_it;
|
||||
((BPy_Interface0DIterator *)py_if0D_it)->at_start = true;
|
||||
((BPy_Interface0DIterator *)py_if0D_it)->reversed = reversed;
|
||||
return py_if0D_it;
|
||||
}
|
||||
|
||||
PyObject *BPy_CurvePointIterator_from_CurvePointIterator(CurveInternal::CurvePointIterator &cp_it)
|
||||
{
|
||||
PyObject *py_cp_it = CurvePointIterator_Type.tp_new(&CurvePointIterator_Type, nullptr, nullptr);
|
||||
((BPy_CurvePointIterator *)py_cp_it)->cp_it = new CurveInternal::CurvePointIterator(cp_it);
|
||||
((BPy_CurvePointIterator *)py_cp_it)->py_it.it = ((BPy_CurvePointIterator *)py_cp_it)->cp_it;
|
||||
return py_cp_it;
|
||||
}
|
||||
|
||||
PyObject *BPy_StrokeVertexIterator_from_StrokeVertexIterator(
|
||||
StrokeInternal::StrokeVertexIterator &sv_it, bool reversed)
|
||||
{
|
||||
PyObject *py_sv_it = StrokeVertexIterator_Type.tp_new(
|
||||
&StrokeVertexIterator_Type, nullptr, nullptr);
|
||||
((BPy_StrokeVertexIterator *)py_sv_it)->sv_it = new StrokeInternal::StrokeVertexIterator(sv_it);
|
||||
((BPy_StrokeVertexIterator *)py_sv_it)->py_it.it = ((BPy_StrokeVertexIterator *)py_sv_it)->sv_it;
|
||||
((BPy_StrokeVertexIterator *)py_sv_it)->at_start = true;
|
||||
((BPy_StrokeVertexIterator *)py_sv_it)->reversed = reversed;
|
||||
return py_sv_it;
|
||||
}
|
||||
|
||||
PyObject *BPy_SVertexIterator_from_SVertexIterator(ViewEdgeInternal::SVertexIterator &sv_it)
|
||||
{
|
||||
PyObject *py_sv_it = SVertexIterator_Type.tp_new(&SVertexIterator_Type, nullptr, nullptr);
|
||||
((BPy_SVertexIterator *)py_sv_it)->sv_it = new ViewEdgeInternal::SVertexIterator(sv_it);
|
||||
((BPy_SVertexIterator *)py_sv_it)->py_it.it = ((BPy_SVertexIterator *)py_sv_it)->sv_it;
|
||||
return py_sv_it;
|
||||
}
|
||||
|
||||
PyObject *BPy_orientedViewEdgeIterator_from_orientedViewEdgeIterator(
|
||||
ViewVertexInternal::orientedViewEdgeIterator &ove_it, bool reversed)
|
||||
{
|
||||
PyObject *py_ove_it = orientedViewEdgeIterator_Type.tp_new(
|
||||
&orientedViewEdgeIterator_Type, nullptr, nullptr);
|
||||
((BPy_orientedViewEdgeIterator *)py_ove_it)->ove_it =
|
||||
new ViewVertexInternal::orientedViewEdgeIterator(ove_it);
|
||||
((BPy_orientedViewEdgeIterator *)py_ove_it)->py_it.it =
|
||||
((BPy_orientedViewEdgeIterator *)py_ove_it)->ove_it;
|
||||
((BPy_orientedViewEdgeIterator *)py_ove_it)->at_start = true;
|
||||
((BPy_orientedViewEdgeIterator *)py_ove_it)->reversed = reversed;
|
||||
return py_ove_it;
|
||||
}
|
||||
|
||||
PyObject *BPy_ViewEdgeIterator_from_ViewEdgeIterator(ViewEdgeInternal::ViewEdgeIterator &ve_it)
|
||||
{
|
||||
PyObject *py_ve_it = ViewEdgeIterator_Type.tp_new(&ViewEdgeIterator_Type, nullptr, nullptr);
|
||||
((BPy_ViewEdgeIterator *)py_ve_it)->ve_it = new ViewEdgeInternal::ViewEdgeIterator(ve_it);
|
||||
((BPy_ViewEdgeIterator *)py_ve_it)->py_it.it = ((BPy_ViewEdgeIterator *)py_ve_it)->ve_it;
|
||||
return py_ve_it;
|
||||
}
|
||||
|
||||
PyObject *BPy_ChainingIterator_from_ChainingIterator(ChainingIterator &c_it)
|
||||
{
|
||||
PyObject *py_c_it = ChainingIterator_Type.tp_new(&ChainingIterator_Type, nullptr, nullptr);
|
||||
((BPy_ChainingIterator *)py_c_it)->c_it = new ChainingIterator(c_it);
|
||||
((BPy_ChainingIterator *)py_c_it)->py_ve_it.py_it.it = ((BPy_ChainingIterator *)py_c_it)->c_it;
|
||||
return py_c_it;
|
||||
}
|
||||
|
||||
PyObject *BPy_ChainPredicateIterator_from_ChainPredicateIterator(ChainPredicateIterator &cp_it)
|
||||
{
|
||||
PyObject *py_cp_it = ChainPredicateIterator_Type.tp_new(
|
||||
&ChainPredicateIterator_Type, nullptr, nullptr);
|
||||
((BPy_ChainPredicateIterator *)py_cp_it)->cp_it = new ChainPredicateIterator(cp_it);
|
||||
((BPy_ChainPredicateIterator *)py_cp_it)->py_c_it.py_ve_it.py_it.it =
|
||||
((BPy_ChainPredicateIterator *)py_cp_it)->cp_it;
|
||||
return py_cp_it;
|
||||
}
|
||||
|
||||
PyObject *BPy_ChainSilhouetteIterator_from_ChainSilhouetteIterator(ChainSilhouetteIterator &cs_it)
|
||||
{
|
||||
PyObject *py_cs_it = ChainSilhouetteIterator_Type.tp_new(
|
||||
&ChainSilhouetteIterator_Type, nullptr, nullptr);
|
||||
((BPy_ChainSilhouetteIterator *)py_cs_it)->cs_it = new ChainSilhouetteIterator(cs_it);
|
||||
((BPy_ChainSilhouetteIterator *)py_cs_it)->py_c_it.py_ve_it.py_it.it =
|
||||
((BPy_ChainSilhouetteIterator *)py_cs_it)->cs_it;
|
||||
return py_cs_it;
|
||||
}
|
||||
|
||||
//==============================
|
||||
// Python => C++
|
||||
//==============================
|
||||
|
||||
bool bool_from_PyBool(PyObject *b)
|
||||
{
|
||||
return PyObject_IsTrue(b) != 0;
|
||||
}
|
||||
|
||||
IntegrationType IntegrationType_from_BPy_IntegrationType(PyObject *obj)
|
||||
{
|
||||
return static_cast<IntegrationType>(PyLong_AsLong(obj));
|
||||
}
|
||||
|
||||
Stroke::MediumType MediumType_from_BPy_MediumType(PyObject *obj)
|
||||
{
|
||||
return static_cast<Stroke::MediumType>(PyLong_AsLong(obj));
|
||||
}
|
||||
|
||||
Nature::EdgeNature EdgeNature_from_BPy_Nature(PyObject *obj)
|
||||
{
|
||||
return static_cast<Nature::EdgeNature>(PyLong_AsLong(obj));
|
||||
}
|
||||
|
||||
bool Vec2f_ptr_from_PyObject(PyObject *obj, Vec2f &vec)
|
||||
{
|
||||
if (Vec2f_ptr_from_Vector(obj, vec)) {
|
||||
return true;
|
||||
}
|
||||
if (Vec2f_ptr_from_PyList(obj, vec)) {
|
||||
return true;
|
||||
}
|
||||
if (Vec2f_ptr_from_PyTuple(obj, vec)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Vec3f_ptr_from_PyObject(PyObject *obj, Vec3f &vec)
|
||||
{
|
||||
if (Vec3f_ptr_from_Vector(obj, vec)) {
|
||||
return true;
|
||||
}
|
||||
if (Vec3f_ptr_from_Color(obj, vec)) {
|
||||
return true;
|
||||
}
|
||||
if (Vec3f_ptr_from_PyList(obj, vec)) {
|
||||
return true;
|
||||
}
|
||||
if (Vec3f_ptr_from_PyTuple(obj, vec)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Vec3r_ptr_from_PyObject(PyObject *obj, Vec3r &vec)
|
||||
{
|
||||
if (Vec3r_ptr_from_Vector(obj, vec)) {
|
||||
return true;
|
||||
}
|
||||
if (Vec3r_ptr_from_Color(obj, vec)) {
|
||||
return true;
|
||||
}
|
||||
if (Vec3r_ptr_from_PyList(obj, vec)) {
|
||||
return true;
|
||||
}
|
||||
if (Vec3r_ptr_from_PyTuple(obj, vec)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Vec2f_ptr_from_Vector(PyObject *obj, Vec2f &vec)
|
||||
{
|
||||
using namespace blender;
|
||||
if (!VectorObject_Check(obj) || ((VectorObject *)obj)->vec_num != 2) {
|
||||
return false;
|
||||
}
|
||||
if (BaseMath_ReadCallback((blender::BaseMathObject *)obj) == -1) {
|
||||
return false;
|
||||
}
|
||||
vec[0] = ((VectorObject *)obj)->vec[0];
|
||||
vec[1] = ((VectorObject *)obj)->vec[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec3f_ptr_from_Vector(PyObject *obj, Vec3f &vec)
|
||||
{
|
||||
using namespace blender;
|
||||
if (!VectorObject_Check(obj) || ((VectorObject *)obj)->vec_num != 3) {
|
||||
return false;
|
||||
}
|
||||
if (BaseMath_ReadCallback((blender::BaseMathObject *)obj) == -1) {
|
||||
return false;
|
||||
}
|
||||
vec[0] = ((VectorObject *)obj)->vec[0];
|
||||
vec[1] = ((VectorObject *)obj)->vec[1];
|
||||
vec[2] = ((VectorObject *)obj)->vec[2];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec3r_ptr_from_Vector(PyObject *obj, Vec3r &vec)
|
||||
{
|
||||
using namespace blender;
|
||||
if (!VectorObject_Check(obj) || ((VectorObject *)obj)->vec_num != 3) {
|
||||
return false;
|
||||
}
|
||||
if (BaseMath_ReadCallback((blender::BaseMathObject *)obj) == -1) {
|
||||
return false;
|
||||
}
|
||||
vec[0] = ((VectorObject *)obj)->vec[0];
|
||||
vec[1] = ((VectorObject *)obj)->vec[1];
|
||||
vec[2] = ((VectorObject *)obj)->vec[2];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec3f_ptr_from_Color(PyObject *obj, Vec3f &vec)
|
||||
{
|
||||
using namespace blender;
|
||||
if (!ColorObject_Check(obj)) {
|
||||
return false;
|
||||
}
|
||||
if (BaseMath_ReadCallback((blender::BaseMathObject *)obj) == -1) {
|
||||
return false;
|
||||
}
|
||||
vec[0] = ((ColorObject *)obj)->col[0];
|
||||
vec[1] = ((ColorObject *)obj)->col[1];
|
||||
vec[2] = ((ColorObject *)obj)->col[2];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec3r_ptr_from_Color(PyObject *obj, Vec3r &vec)
|
||||
{
|
||||
using namespace blender;
|
||||
if (!ColorObject_Check(obj)) {
|
||||
return false;
|
||||
}
|
||||
if (BaseMath_ReadCallback((blender::BaseMathObject *)obj) == -1) {
|
||||
return false;
|
||||
}
|
||||
vec[0] = ((ColorObject *)obj)->col[0];
|
||||
vec[1] = ((ColorObject *)obj)->col[1];
|
||||
vec[2] = ((ColorObject *)obj)->col[2];
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool float_array_from_PyList(PyObject *obj, float *v, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
v[i] = PyFloat_AsDouble(PyList_GET_ITEM(obj, i));
|
||||
if (v[i] == -1.0f && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "list elements must be a number");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec2f_ptr_from_PyList(PyObject *obj, Vec2f &vec)
|
||||
{
|
||||
float v[2];
|
||||
|
||||
if (!PyList_Check(obj) || PyList_GET_SIZE(obj) != 2) {
|
||||
return false;
|
||||
}
|
||||
if (!float_array_from_PyList(obj, v, 2)) {
|
||||
return false;
|
||||
}
|
||||
vec[0] = v[0];
|
||||
vec[1] = v[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec3f_ptr_from_PyList(PyObject *obj, Vec3f &vec)
|
||||
{
|
||||
float v[3];
|
||||
|
||||
if (!PyList_Check(obj) || PyList_GET_SIZE(obj) != 3) {
|
||||
return false;
|
||||
}
|
||||
if (!float_array_from_PyList(obj, v, 3)) {
|
||||
return false;
|
||||
}
|
||||
vec[0] = v[0];
|
||||
vec[1] = v[1];
|
||||
vec[2] = v[2];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec3r_ptr_from_PyList(PyObject *obj, Vec3r &vec)
|
||||
{
|
||||
float v[3];
|
||||
|
||||
if (!PyList_Check(obj) || PyList_GET_SIZE(obj) != 3) {
|
||||
return false;
|
||||
}
|
||||
if (!float_array_from_PyList(obj, v, 3)) {
|
||||
return false;
|
||||
}
|
||||
vec[0] = v[0];
|
||||
vec[1] = v[1];
|
||||
vec[2] = v[2];
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool float_array_from_PyTuple(PyObject *obj, float *v, int n)
|
||||
{
|
||||
for (int i = 0; i < n; i++) {
|
||||
v[i] = PyFloat_AsDouble(PyTuple_GET_ITEM(obj, i));
|
||||
if (v[i] == -1.0f && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "tuple elements must be a number");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec2f_ptr_from_PyTuple(PyObject *obj, Vec2f &vec)
|
||||
{
|
||||
float v[2];
|
||||
|
||||
if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 2) {
|
||||
return false;
|
||||
}
|
||||
if (!float_array_from_PyTuple(obj, v, 2)) {
|
||||
return false;
|
||||
}
|
||||
vec[0] = v[0];
|
||||
vec[1] = v[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec3f_ptr_from_PyTuple(PyObject *obj, Vec3f &vec)
|
||||
{
|
||||
float v[3];
|
||||
|
||||
if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 3) {
|
||||
return false;
|
||||
}
|
||||
if (!float_array_from_PyTuple(obj, v, 3)) {
|
||||
return false;
|
||||
}
|
||||
vec[0] = v[0];
|
||||
vec[1] = v[1];
|
||||
vec[2] = v[2];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vec3r_ptr_from_PyTuple(PyObject *obj, Vec3r &vec)
|
||||
{
|
||||
float v[3];
|
||||
|
||||
if (!PyTuple_Check(obj) || PyTuple_GET_SIZE(obj) != 3) {
|
||||
return false;
|
||||
}
|
||||
if (!float_array_from_PyTuple(obj, v, 3)) {
|
||||
return false;
|
||||
}
|
||||
vec[0] = v[0];
|
||||
vec[1] = v[1];
|
||||
vec[2] = v[2];
|
||||
return true;
|
||||
}
|
||||
|
||||
// helpers for argument parsing
|
||||
|
||||
bool float_array_from_PyObject(PyObject *obj, float *v, int n)
|
||||
{
|
||||
using namespace blender;
|
||||
if (VectorObject_Check(obj) && ((VectorObject *)obj)->vec_num == n) {
|
||||
if (BaseMath_ReadCallback((blender::BaseMathObject *)obj) == -1) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
v[i] = ((VectorObject *)obj)->vec[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (ColorObject_Check(obj) && n == 3) {
|
||||
if (BaseMath_ReadCallback((blender::BaseMathObject *)obj) == -1) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
v[i] = ((ColorObject *)obj)->col[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (PyList_Check(obj) && PyList_GET_SIZE(obj) == n) {
|
||||
return float_array_from_PyList(obj, v, n);
|
||||
}
|
||||
if (PyTuple_Check(obj) && PyTuple_GET_SIZE(obj) == n) {
|
||||
return float_array_from_PyTuple(obj, v, n);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int convert_v4(PyObject *obj, void *v)
|
||||
{
|
||||
return blender::mathutils_array_parse((float *)v, 4, 4, obj, "Error parsing 4D vector");
|
||||
}
|
||||
|
||||
int convert_v3(PyObject *obj, void *v)
|
||||
{
|
||||
return blender::mathutils_array_parse((float *)v, 3, 3, obj, "Error parsing 3D vector");
|
||||
}
|
||||
|
||||
int convert_v2(PyObject *obj, void *v)
|
||||
{
|
||||
return blender::mathutils_array_parse((float *)v, 2, 2, obj, "Error parsing 2D vector");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,163 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
#include "../geometry/Geom.h"
|
||||
|
||||
// BBox
|
||||
#include "../geometry/BBox.h"
|
||||
|
||||
// FEdge, FEdgeSharp, FEdgeSmooth, SShape, SVertex, FEdgeInternal::SVertexIterator
|
||||
#include "../view_map/Silhouette.h"
|
||||
|
||||
// Id
|
||||
#include "../system/Id.h"
|
||||
|
||||
// Interface0D, Interface0DIteratorNested, Interface0DIterator
|
||||
#include "../view_map/Interface0D.h"
|
||||
|
||||
// Interface1D
|
||||
#include "../view_map/Interface1D.h"
|
||||
|
||||
// FrsMaterial
|
||||
#include "../scene_graph/FrsMaterial.h"
|
||||
|
||||
// Nature::VertexNature, Nature::EdgeNature
|
||||
#include "../winged_edge/Nature.h"
|
||||
|
||||
// Stroke, StrokeAttribute, StrokeVertex
|
||||
#include "../stroke/Stroke.h"
|
||||
|
||||
// NonTVertex, TVertex, ViewEdge, ViewMap, ViewShape, ViewVertex
|
||||
#include "../view_map/ViewMap.h"
|
||||
|
||||
// CurvePoint, Curve
|
||||
#include "../stroke/Curve.h"
|
||||
|
||||
// Chain
|
||||
#include "../stroke/Chain.h"
|
||||
|
||||
//====== ITERATORS
|
||||
|
||||
// AdjacencyIterator, ChainingIterator, ChainSilhouetteIterator, ChainPredicateIterator
|
||||
#include "../stroke/ChainingIterators.h"
|
||||
|
||||
// ViewVertexInternal::orientedViewEdgeIterator
|
||||
// ViewEdgeInternal::SVertexIterator
|
||||
// ViewEdgeInternal::ViewEdgeIterator
|
||||
#include "../view_map/ViewMapIterators.h"
|
||||
|
||||
// StrokeInternal::StrokeVertexIterator
|
||||
#include "../stroke/StrokeIterators.h"
|
||||
|
||||
// CurveInternal::CurvePointIterator
|
||||
#include "../stroke/CurveIterators.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "generic/python_utildefines.hh"
|
||||
#include "mathutils/mathutils.hh"
|
||||
|
||||
//==============================
|
||||
// C++ => Python
|
||||
//==============================
|
||||
|
||||
PyObject *PyLong_subtype_new(PyTypeObject *ty, long value);
|
||||
void PyLong_subtype_add_to_dict(PyObject *dict, PyTypeObject *ty, const char *attr, long value);
|
||||
|
||||
PyObject *PyBool_from_bool(bool b);
|
||||
PyObject *Vector_from_Vec2f(Freestyle::Geometry::Vec2f &v);
|
||||
PyObject *Vector_from_Vec3f(Freestyle::Geometry::Vec3f &v);
|
||||
PyObject *Vector_from_Vec3r(Freestyle::Geometry::Vec3r &v);
|
||||
|
||||
PyObject *Any_BPy_Interface0D_from_Interface0D(Freestyle::Interface0D &if0D);
|
||||
PyObject *Any_BPy_Interface1D_from_Interface1D(Freestyle::Interface1D &if1D);
|
||||
PyObject *Any_BPy_FEdge_from_FEdge(Freestyle::FEdge &fe);
|
||||
PyObject *Any_BPy_ViewVertex_from_ViewVertex(Freestyle::ViewVertex &vv);
|
||||
|
||||
PyObject *BPy_BBox_from_BBox(const Freestyle::BBox<Freestyle::Geometry::Vec3r> &bb);
|
||||
PyObject *BPy_CurvePoint_from_CurvePoint(Freestyle::CurvePoint &cp);
|
||||
PyObject *BPy_directedViewEdge_from_directedViewEdge(Freestyle::ViewVertex::directedViewEdge &dve);
|
||||
PyObject *BPy_FEdge_from_FEdge(Freestyle::FEdge &fe);
|
||||
PyObject *BPy_FEdgeSharp_from_FEdgeSharp(Freestyle::FEdgeSharp &fes);
|
||||
PyObject *BPy_FEdgeSmooth_from_FEdgeSmooth(Freestyle::FEdgeSmooth &fes);
|
||||
PyObject *BPy_Id_from_Id(Freestyle::Id &id);
|
||||
PyObject *BPy_Interface0D_from_Interface0D(Freestyle::Interface0D &if0D);
|
||||
PyObject *BPy_Interface1D_from_Interface1D(Freestyle::Interface1D &if1D);
|
||||
PyObject *BPy_IntegrationType_from_IntegrationType(Freestyle::IntegrationType i);
|
||||
PyObject *BPy_FrsMaterial_from_FrsMaterial(const Freestyle::FrsMaterial &m);
|
||||
PyObject *BPy_Nature_from_Nature(ushort n);
|
||||
PyObject *BPy_MediumType_from_MediumType(Freestyle::Stroke::MediumType n);
|
||||
PyObject *BPy_SShape_from_SShape(Freestyle::SShape &ss);
|
||||
PyObject *BPy_Stroke_from_Stroke(Freestyle::Stroke &s);
|
||||
PyObject *BPy_StrokeAttribute_from_StrokeAttribute(Freestyle::StrokeAttribute &sa);
|
||||
PyObject *BPy_StrokeVertex_from_StrokeVertex(Freestyle::StrokeVertex &sv);
|
||||
PyObject *BPy_SVertex_from_SVertex(Freestyle::SVertex &sv);
|
||||
PyObject *BPy_ViewVertex_from_ViewVertex(Freestyle::ViewVertex &vv);
|
||||
PyObject *BPy_NonTVertex_from_NonTVertex(Freestyle::NonTVertex &ntv);
|
||||
PyObject *BPy_TVertex_from_TVertex(Freestyle::TVertex &tv);
|
||||
PyObject *BPy_ViewEdge_from_ViewEdge(Freestyle::ViewEdge &ve);
|
||||
PyObject *BPy_Chain_from_Chain(Freestyle::Chain &c);
|
||||
PyObject *BPy_ViewShape_from_ViewShape(Freestyle::ViewShape &vs);
|
||||
|
||||
PyObject *BPy_AdjacencyIterator_from_AdjacencyIterator(Freestyle::AdjacencyIterator &a_it);
|
||||
PyObject *BPy_Interface0DIterator_from_Interface0DIterator(Freestyle::Interface0DIterator &if0D_it,
|
||||
bool reversed);
|
||||
PyObject *BPy_CurvePointIterator_from_CurvePointIterator(
|
||||
Freestyle::CurveInternal::CurvePointIterator &cp_it);
|
||||
PyObject *BPy_StrokeVertexIterator_from_StrokeVertexIterator(
|
||||
Freestyle::StrokeInternal::StrokeVertexIterator &sv_it, bool reversed);
|
||||
PyObject *BPy_SVertexIterator_from_SVertexIterator(
|
||||
Freestyle::ViewEdgeInternal::SVertexIterator &sv_it);
|
||||
PyObject *BPy_orientedViewEdgeIterator_from_orientedViewEdgeIterator(
|
||||
Freestyle::ViewVertexInternal::orientedViewEdgeIterator &ove_it, bool reversed);
|
||||
PyObject *BPy_ViewEdgeIterator_from_ViewEdgeIterator(
|
||||
Freestyle::ViewEdgeInternal::ViewEdgeIterator &ve_it);
|
||||
PyObject *BPy_ChainingIterator_from_ChainingIterator(Freestyle::ChainingIterator &c_it);
|
||||
PyObject *BPy_ChainPredicateIterator_from_ChainPredicateIterator(
|
||||
Freestyle::ChainPredicateIterator &cp_it);
|
||||
PyObject *BPy_ChainSilhouetteIterator_from_ChainSilhouetteIterator(
|
||||
Freestyle::ChainSilhouetteIterator &cs_it);
|
||||
|
||||
//==============================
|
||||
// Python => C++
|
||||
//==============================
|
||||
|
||||
bool bool_from_PyBool(PyObject *b);
|
||||
Freestyle::IntegrationType IntegrationType_from_BPy_IntegrationType(PyObject *obj);
|
||||
Freestyle::Stroke::MediumType MediumType_from_BPy_MediumType(PyObject *obj);
|
||||
Freestyle::Nature::EdgeNature EdgeNature_from_BPy_Nature(PyObject *obj);
|
||||
bool Vec2f_ptr_from_PyObject(PyObject *obj, Freestyle::Geometry::Vec2f &vec);
|
||||
bool Vec3f_ptr_from_PyObject(PyObject *obj, Freestyle::Geometry::Vec3f &vec);
|
||||
bool Vec3r_ptr_from_PyObject(PyObject *obj, Freestyle::Geometry::Vec3r &vec);
|
||||
bool Vec2f_ptr_from_Vector(PyObject *obj, Freestyle::Geometry::Vec2f &vec);
|
||||
bool Vec3f_ptr_from_Vector(PyObject *obj, Freestyle::Geometry::Vec3f &vec);
|
||||
bool Vec3r_ptr_from_Vector(PyObject *obj, Freestyle::Geometry::Vec3r &vec);
|
||||
bool Vec3f_ptr_from_Color(PyObject *obj, Freestyle::Geometry::Vec3f &vec);
|
||||
bool Vec3r_ptr_from_Color(PyObject *obj, Freestyle::Geometry::Vec3r &vec);
|
||||
bool Vec2f_ptr_from_PyList(PyObject *obj, Freestyle::Geometry::Vec2f &vec);
|
||||
bool Vec3f_ptr_from_PyList(PyObject *obj, Freestyle::Geometry::Vec3f &vec);
|
||||
bool Vec3r_ptr_from_PyList(PyObject *obj, Freestyle::Geometry::Vec3r &vec);
|
||||
bool Vec2f_ptr_from_PyTuple(PyObject *obj, Freestyle::Geometry::Vec2f &vec);
|
||||
bool Vec3f_ptr_from_PyTuple(PyObject *obj, Freestyle::Geometry::Vec3f &vec);
|
||||
bool Vec3r_ptr_from_PyTuple(PyObject *obj, Freestyle::Geometry::Vec3r &vec);
|
||||
|
||||
bool float_array_from_PyObject(PyObject *obj, float *v, int n);
|
||||
|
||||
int convert_v4(PyObject *obj, void *v);
|
||||
int convert_v3(PyObject *obj, void *v);
|
||||
int convert_v2(PyObject *obj, void *v);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,612 @@
|
||||
/* SPDX-FileCopyrightText: 2008-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_Freestyle.h"
|
||||
|
||||
#include "BPy_BBox.h"
|
||||
#include "BPy_BinaryPredicate0D.h"
|
||||
#include "BPy_BinaryPredicate1D.h"
|
||||
#include "BPy_ContextFunctions.h"
|
||||
#include "BPy_Convert.h"
|
||||
#include "BPy_FrsMaterial.h"
|
||||
#include "BPy_FrsNoise.h"
|
||||
#include "BPy_Id.h"
|
||||
#include "BPy_IntegrationType.h"
|
||||
#include "BPy_Interface0D.h"
|
||||
#include "BPy_Interface1D.h"
|
||||
#include "BPy_Iterator.h"
|
||||
#include "BPy_MediumType.h"
|
||||
#include "BPy_Nature.h"
|
||||
#include "BPy_Operators.h"
|
||||
#include "BPy_SShape.h"
|
||||
#include "BPy_StrokeAttribute.h"
|
||||
#include "BPy_StrokeShader.h"
|
||||
#include "BPy_UnaryFunction0D.h"
|
||||
#include "BPy_UnaryFunction1D.h"
|
||||
#include "BPy_UnaryPredicate0D.h"
|
||||
#include "BPy_UnaryPredicate1D.h"
|
||||
#include "BPy_ViewMap.h"
|
||||
#include "BPy_ViewShape.h"
|
||||
|
||||
#include "BKE_appdir.hh"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "FRS_freestyle.h"
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_prototypes.hh"
|
||||
#include "bpy_rna.hh" /* pyrna_struct_CreatePyObject() */
|
||||
|
||||
#include "../generic/py_capi_utils.hh" /* #PyC_UnicodeFromBytes */
|
||||
|
||||
#include "BKE_colorband.hh" /* BKE_colorband_evaluate() */
|
||||
#include "BKE_colortools.hh" /* BKE_curvemapping_evaluateF() */
|
||||
#include "BKE_material.hh" /* ramp_blend() */
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------ MODULE FUNCTIONS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Freestyle_getCurrentScene___doc__,
|
||||
".. function:: getCurrentScene()\n"
|
||||
"\n"
|
||||
" Returns the current scene.\n"
|
||||
"\n"
|
||||
" :return: The current scene.\n"
|
||||
" :rtype: :class:`bpy.types.Scene`\n");
|
||||
static PyObject *Freestyle_getCurrentScene(PyObject * /*self*/)
|
||||
{
|
||||
blender::Scene *scene = blender::g_freestyle.scene;
|
||||
if (!scene) {
|
||||
PyErr_SetString(PyExc_TypeError, "current scene not available");
|
||||
return nullptr;
|
||||
}
|
||||
blender::PointerRNA ptr_scene = RNA_pointer_create_discrete(
|
||||
&scene->id, blender::RNA_Scene, scene);
|
||||
return pyrna_struct_CreatePyObject(&ptr_scene);
|
||||
}
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
|
||||
static int ramp_blend_type(const char *type)
|
||||
{
|
||||
if (STREQ(type, "MIX")) {
|
||||
return blender::MA_RAMP_BLEND;
|
||||
}
|
||||
if (STREQ(type, "ADD")) {
|
||||
return blender::MA_RAMP_ADD;
|
||||
}
|
||||
if (STREQ(type, "MULTIPLY")) {
|
||||
return blender::MA_RAMP_MULT;
|
||||
}
|
||||
if (STREQ(type, "SUBTRACT")) {
|
||||
return blender::MA_RAMP_SUB;
|
||||
}
|
||||
if (STREQ(type, "SCREEN")) {
|
||||
return blender::MA_RAMP_SCREEN;
|
||||
}
|
||||
if (STREQ(type, "DIVIDE")) {
|
||||
return blender::MA_RAMP_DIV;
|
||||
}
|
||||
if (STREQ(type, "DIFFERENCE")) {
|
||||
return blender::MA_RAMP_DIFF;
|
||||
}
|
||||
if (STREQ(type, "EXCLUSION")) {
|
||||
return blender::MA_RAMP_EXCLUSION;
|
||||
}
|
||||
if (STREQ(type, "DARKEN")) {
|
||||
return blender::MA_RAMP_DARK;
|
||||
}
|
||||
if (STREQ(type, "LIGHTEN")) {
|
||||
return blender::MA_RAMP_LIGHT;
|
||||
}
|
||||
if (STREQ(type, "OVERLAY")) {
|
||||
return blender::MA_RAMP_OVERLAY;
|
||||
}
|
||||
if (STREQ(type, "DODGE")) {
|
||||
return blender::MA_RAMP_DODGE;
|
||||
}
|
||||
if (STREQ(type, "BURN")) {
|
||||
return blender::MA_RAMP_BURN;
|
||||
}
|
||||
if (STREQ(type, "HUE")) {
|
||||
return blender::MA_RAMP_HUE;
|
||||
}
|
||||
if (STREQ(type, "SATURATION")) {
|
||||
return blender::MA_RAMP_SAT;
|
||||
}
|
||||
if (STREQ(type, "VALUE")) {
|
||||
return blender::MA_RAMP_VAL;
|
||||
}
|
||||
if (STREQ(type, "COLOR")) {
|
||||
return blender::MA_RAMP_COLOR;
|
||||
}
|
||||
if (STREQ(type, "SOFT_LIGHT")) {
|
||||
return blender::MA_RAMP_SOFT;
|
||||
}
|
||||
if (STREQ(type, "LINEAR_LIGHT")) {
|
||||
return blender::MA_RAMP_LINEAR;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Freestyle_blendRamp___doc__,
|
||||
".. function:: blendRamp(type, color1, fac, color2)\n"
|
||||
"\n"
|
||||
" Blend two colors according to a ramp blend type.\n"
|
||||
"\n"
|
||||
" :param type: Ramp blend type.\n"
|
||||
" :type type: int\n"
|
||||
" :param color1: 1st color.\n"
|
||||
" :type color1: :class:`mathutils.Vector` | tuple[float, float, float] | list[float]\n"
|
||||
" :param fac: Blend factor.\n"
|
||||
" :type fac: float\n"
|
||||
" :param color2: 1st color.\n"
|
||||
" :type color2: :class:`mathutils.Vector` | tuple[float, float, float] | list[float]\n"
|
||||
" :return: Blended color in RGB format.\n"
|
||||
" :rtype: :class:`mathutils.Vector`\n");
|
||||
static PyObject *Freestyle_blendRamp(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
PyObject *obj1, *obj2;
|
||||
char *s;
|
||||
int type;
|
||||
float a[4], fac, b[4];
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sOfO", &s, &obj1, &fac, &obj2)) {
|
||||
return nullptr;
|
||||
}
|
||||
type = ramp_blend_type(s);
|
||||
if (type < 0) {
|
||||
PyErr_SetString(PyExc_TypeError, "argument 1 is an unknown ramp blend type");
|
||||
return nullptr;
|
||||
}
|
||||
if (blender::mathutils_array_parse(a,
|
||||
3,
|
||||
3,
|
||||
obj1,
|
||||
"argument 2 must be a 3D vector "
|
||||
"(either a tuple/list of 3 elements or Vector)") == -1)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (blender::mathutils_array_parse(b,
|
||||
3,
|
||||
3,
|
||||
obj2,
|
||||
"argument 4 must be a 3D vector "
|
||||
"(either a tuple/list of 3 elements or Vector)") == -1)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
blender::ramp_blend(type, a, fac, b);
|
||||
return blender::Vector_CreatePyObject(a, 3, nullptr);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Freestyle_evaluateColorRamp___doc__,
|
||||
".. function:: evaluateColorRamp(ramp, in)\n"
|
||||
"\n"
|
||||
" Evaluate a color ramp at a point in the interval 0 to 1.\n"
|
||||
"\n"
|
||||
" :param ramp: Color ramp object.\n"
|
||||
" :type ramp: :class:`bpy.types.ColorRamp`\n"
|
||||
" :param in: Value in the interval 0 to 1.\n"
|
||||
" :type in: float\n"
|
||||
" :return: color in RGBA format.\n"
|
||||
" :rtype: :class:`mathutils.Vector`\n");
|
||||
static PyObject *Freestyle_evaluateColorRamp(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
blender::BPy_StructRNA *py_srna;
|
||||
blender::ColorBand *coba;
|
||||
float in, out[4];
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!f", &blender::pyrna_struct_Type, &py_srna, &in)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!RNA_struct_is_a(py_srna->ptr->type, blender::RNA_ColorRamp)) {
|
||||
PyErr_SetString(PyExc_TypeError, "1st argument is not a ColorRamp object");
|
||||
return nullptr;
|
||||
}
|
||||
coba = (blender::ColorBand *)py_srna->ptr->data;
|
||||
if (!BKE_colorband_evaluate(coba, in, out)) {
|
||||
PyErr_SetString(PyExc_ValueError, "failed to evaluate the color ramp");
|
||||
return nullptr;
|
||||
}
|
||||
return blender::Vector_CreatePyObject(out, 4, nullptr);
|
||||
}
|
||||
|
||||
#include "DNA_color_types.h"
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Freestyle_evaluateCurveMappingF___doc__,
|
||||
".. function:: evaluateCurveMappingF(cumap, cur, value)\n"
|
||||
"\n"
|
||||
" Evaluate a curve mapping at a point in the interval 0 to 1.\n"
|
||||
"\n"
|
||||
" :param cumap: Curve mapping object.\n"
|
||||
" :type cumap: :class:`bpy.types.CurveMapping`\n"
|
||||
" :param cur: Index of the curve to be used (0 <= cur <= 3).\n"
|
||||
" :type cur: int\n"
|
||||
" :param value: Input value in the interval 0 to 1.\n"
|
||||
" :type value: float\n"
|
||||
" :return: Mapped output value.\n"
|
||||
" :rtype: float\n");
|
||||
static PyObject *Freestyle_evaluateCurveMappingF(PyObject * /*self*/, PyObject *args)
|
||||
{
|
||||
blender::BPy_StructRNA *py_srna;
|
||||
blender::CurveMapping *cumap;
|
||||
int cur;
|
||||
float value;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!if", &blender::pyrna_struct_Type, &py_srna, &cur, &value)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!RNA_struct_is_a(py_srna->ptr->type, blender::RNA_CurveMapping)) {
|
||||
PyErr_SetString(PyExc_TypeError, "1st argument is not a CurveMapping object");
|
||||
return nullptr;
|
||||
}
|
||||
if (cur < 0 || cur > 3) {
|
||||
PyErr_SetString(PyExc_ValueError, "2nd argument is out of range");
|
||||
return nullptr;
|
||||
}
|
||||
cumap = (blender::CurveMapping *)py_srna->ptr->data;
|
||||
BKE_curvemapping_init(cumap);
|
||||
/* disable extrapolation if enabled */
|
||||
if (cumap->flag & blender::CUMA_EXTEND_EXTRAPOLATE) {
|
||||
cumap->flag &= ~blender::CUMA_EXTEND_EXTRAPOLATE;
|
||||
BKE_curvemapping_changed(cumap, false);
|
||||
}
|
||||
return PyFloat_FromDouble(BKE_curvemapping_evaluateF(cumap, cur, value));
|
||||
}
|
||||
|
||||
/*-----------------------Freestyle module docstring----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Force wrapped line. */
|
||||
module_docstring,
|
||||
"This module provides classes for defining line drawing rules (such as\n"
|
||||
"predicates, functions, chaining iterators, and stroke shaders), as well\n"
|
||||
"as helper functions for style module writing.\n"
|
||||
"\n"
|
||||
"Class hierarchy:\n"
|
||||
"\n"
|
||||
"- :class:`BBox`\n"
|
||||
"- :class:`BinaryPredicate0D`\n"
|
||||
"- :class:`BinaryPredicate1D`\n"
|
||||
"\n"
|
||||
" - :class:`FalseBP1D`\n"
|
||||
" - :class:`Length2DBP1D`\n"
|
||||
" - :class:`SameShapeIdBP1D`\n"
|
||||
" - :class:`TrueBP1D`\n"
|
||||
" - :class:`ViewMapGradientNormBP1D`\n"
|
||||
"\n"
|
||||
"- :class:`Id`\n"
|
||||
"- :class:`Interface0D`\n"
|
||||
"\n"
|
||||
" - :class:`CurvePoint`\n"
|
||||
"\n"
|
||||
" - :class:`StrokeVertex`\n"
|
||||
"\n"
|
||||
" - :class:`SVertex`\n"
|
||||
" - :class:`ViewVertex`\n"
|
||||
"\n"
|
||||
" - :class:`NonTVertex`\n"
|
||||
" - :class:`TVertex`\n"
|
||||
"\n"
|
||||
"- :class:`Interface1D`\n"
|
||||
"\n"
|
||||
" - :class:`Curve`\n"
|
||||
"\n"
|
||||
" - :class:`Chain`\n"
|
||||
"\n"
|
||||
" - :class:`FEdge`\n"
|
||||
"\n"
|
||||
" - :class:`FEdgeSharp`\n"
|
||||
" - :class:`FEdgeSmooth`\n"
|
||||
"\n"
|
||||
" - :class:`Stroke`\n"
|
||||
" - :class:`ViewEdge`\n"
|
||||
"\n"
|
||||
"- :class:`Iterator`\n"
|
||||
"\n"
|
||||
" - :class:`AdjacencyIterator`\n"
|
||||
" - :class:`CurvePointIterator`\n"
|
||||
" - :class:`Interface0DIterator`\n"
|
||||
" - :class:`SVertexIterator`\n"
|
||||
" - :class:`StrokeVertexIterator`\n"
|
||||
" - :class:`ViewEdgeIterator`\n"
|
||||
"\n"
|
||||
" - :class:`ChainingIterator`\n"
|
||||
"\n"
|
||||
" - :class:`ChainPredicateIterator`\n"
|
||||
" - :class:`ChainSilhouetteIterator`\n"
|
||||
"\n"
|
||||
" - :class:`orientedViewEdgeIterator`\n"
|
||||
"\n"
|
||||
"- :class:`Material`\n"
|
||||
"- :class:`Noise`\n"
|
||||
"- :class:`Operators`\n"
|
||||
"- :class:`SShape`\n"
|
||||
"- :class:`StrokeAttribute`\n"
|
||||
"- :class:`StrokeShader`\n"
|
||||
"\n"
|
||||
" - :class:`BackboneStretcherShader`\n"
|
||||
" - :class:`BezierCurveShader`\n"
|
||||
" - :class:`BlenderTextureShader`\n"
|
||||
" - :class:`CalligraphicShader`\n"
|
||||
" - :class:`ColorNoiseShader`\n"
|
||||
" - :class:`ColorVariationPatternShader`\n"
|
||||
" - :class:`ConstantColorShader`\n"
|
||||
" - :class:`ConstantThicknessShader`\n"
|
||||
" - :class:`ConstrainedIncreasingThicknessShader`\n"
|
||||
" - :class:`GuidingLinesShader`\n"
|
||||
" - :class:`IncreasingColorShader`\n"
|
||||
" - :class:`IncreasingThicknessShader`\n"
|
||||
" - :class:`PolygonalizationShader`\n"
|
||||
" - :class:`SamplingShader`\n"
|
||||
" - :class:`SmoothingShader`\n"
|
||||
" - :class:`SpatialNoiseShader`\n"
|
||||
" - :class:`StrokeTextureShader`\n"
|
||||
" - :class:`StrokeTextureStepShader`\n"
|
||||
" - :class:`TextureAssignerShader`\n"
|
||||
" - :class:`ThicknessNoiseShader`\n"
|
||||
" - :class:`ThicknessVariationPatternShader`\n"
|
||||
" - :class:`TipRemoverShader`\n"
|
||||
" - :class:`fstreamShader`\n"
|
||||
" - :class:`streamShader`\n"
|
||||
"\n"
|
||||
"- :class:`UnaryFunction0D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction0DDouble`\n"
|
||||
"\n"
|
||||
" - :class:`Curvature2DAngleF0D`\n"
|
||||
" - :class:`DensityF0D`\n"
|
||||
" - :class:`GetProjectedXF0D`\n"
|
||||
" - :class:`GetProjectedYF0D`\n"
|
||||
" - :class:`GetProjectedZF0D`\n"
|
||||
" - :class:`GetXF0D`\n"
|
||||
" - :class:`GetYF0D`\n"
|
||||
" - :class:`GetZF0D`\n"
|
||||
" - :class:`LocalAverageDepthF0D`\n"
|
||||
" - :class:`ZDiscontinuityF0D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction0DEdgeNature`\n"
|
||||
"\n"
|
||||
" - :class:`CurveNatureF0D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction0DFloat`\n"
|
||||
"\n"
|
||||
" - :class:`GetCurvilinearAbscissaF0D`\n"
|
||||
" - :class:`GetParameterF0D`\n"
|
||||
" - :class:`GetViewMapGradientNormF0D`\n"
|
||||
" - :class:`ReadCompleteViewMapPixelF0D`\n"
|
||||
" - :class:`ReadMapPixelF0D`\n"
|
||||
" - :class:`ReadSteerableViewMapPixelF0D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction0DId`\n"
|
||||
"\n"
|
||||
" - :class:`ShapeIdF0D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction0DMaterial`\n"
|
||||
"\n"
|
||||
" - :class:`MaterialF0D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction0DUnsigned`\n"
|
||||
"\n"
|
||||
" - :class:`QuantitativeInvisibilityF0D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction0DVec2f`\n"
|
||||
"\n"
|
||||
" - :class:`Normal2DF0D`\n"
|
||||
" - :class:`VertexOrientation2DF0D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction0DVec3f`\n"
|
||||
"\n"
|
||||
" - :class:`VertexOrientation3DF0D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction0DVectorViewShape`\n"
|
||||
"\n"
|
||||
" - :class:`GetOccludersF0D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction0DViewShape`\n"
|
||||
"\n"
|
||||
" - :class:`GetOccludeeF0D`\n"
|
||||
" - :class:`GetShapeF0D`\n"
|
||||
"\n"
|
||||
"- :class:`UnaryFunction1D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction1DDouble`\n"
|
||||
"\n"
|
||||
" - :class:`Curvature2DAngleF1D`\n"
|
||||
" - :class:`DensityF1D`\n"
|
||||
" - :class:`GetCompleteViewMapDensityF1D`\n"
|
||||
" - :class:`GetDirectionalViewMapDensityF1D`\n"
|
||||
" - :class:`GetProjectedXF1D`\n"
|
||||
" - :class:`GetProjectedYF1D`\n"
|
||||
" - :class:`GetProjectedZF1D`\n"
|
||||
" - :class:`GetSteerableViewMapDensityF1D`\n"
|
||||
" - :class:`GetViewMapGradientNormF1D`\n"
|
||||
" - :class:`GetXF1D`\n"
|
||||
" - :class:`GetYF1D`\n"
|
||||
" - :class:`GetZF1D`\n"
|
||||
" - :class:`LocalAverageDepthF1D`\n"
|
||||
" - :class:`ZDiscontinuityF1D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction1DEdgeNature`\n"
|
||||
"\n"
|
||||
" - :class:`CurveNatureF1D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction1DFloat`\n"
|
||||
" - :class:`UnaryFunction1DUnsigned`\n"
|
||||
"\n"
|
||||
" - :class:`QuantitativeInvisibilityF1D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction1DVec2f`\n"
|
||||
"\n"
|
||||
" - :class:`Normal2DF1D`\n"
|
||||
" - :class:`Orientation2DF1D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction1DVec3f`\n"
|
||||
"\n"
|
||||
" - :class:`Orientation3DF1D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction1DVectorViewShape`\n"
|
||||
"\n"
|
||||
" - :class:`GetOccludeeF1D`\n"
|
||||
" - :class:`GetOccludersF1D`\n"
|
||||
" - :class:`GetShapeF1D`\n"
|
||||
"\n"
|
||||
" - :class:`UnaryFunction1DVoid`\n"
|
||||
"\n"
|
||||
" - :class:`ChainingTimeStampF1D`\n"
|
||||
" - :class:`IncrementChainingTimeStampF1D`\n"
|
||||
" - :class:`TimeStampF1D`\n"
|
||||
"\n"
|
||||
"- :class:`UnaryPredicate0D`\n"
|
||||
"\n"
|
||||
" - :class:`FalseUP0D`\n"
|
||||
" - :class:`TrueUP0D`\n"
|
||||
"\n"
|
||||
"- :class:`UnaryPredicate1D`\n"
|
||||
"\n"
|
||||
" - :class:`ContourUP1D`\n"
|
||||
" - :class:`DensityLowerThanUP1D`\n"
|
||||
" - :class:`EqualToChainingTimeStampUP1D`\n"
|
||||
" - :class:`EqualToTimeStampUP1D`\n"
|
||||
" - :class:`ExternalContourUP1D`\n"
|
||||
" - :class:`FalseUP1D`\n"
|
||||
" - :class:`QuantitativeInvisibilityUP1D`\n"
|
||||
" - :class:`ShapeUP1D`\n"
|
||||
" - :class:`TrueUP1D`\n"
|
||||
" - :class:`WithinImageBoundaryUP1D`\n"
|
||||
"\n"
|
||||
"- :class:`ViewMap`\n"
|
||||
"- :class:`ViewShape`\n"
|
||||
"- :class:`IntegrationType`\n"
|
||||
"- :class:`MediumType`\n"
|
||||
"- :class:`Nature`\n"
|
||||
"\n");
|
||||
|
||||
/*-----------------------Freestyle module method def---------------------------*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef module_functions[] = {
|
||||
{"getCurrentScene",
|
||||
(PyCFunction)Freestyle_getCurrentScene,
|
||||
METH_NOARGS,
|
||||
Freestyle_getCurrentScene___doc__},
|
||||
{"blendRamp", (PyCFunction)Freestyle_blendRamp, METH_VARARGS, Freestyle_blendRamp___doc__},
|
||||
{"evaluateColorRamp",
|
||||
(PyCFunction)Freestyle_evaluateColorRamp,
|
||||
METH_VARARGS,
|
||||
Freestyle_evaluateColorRamp___doc__},
|
||||
{"evaluateCurveMappingF",
|
||||
(PyCFunction)Freestyle_evaluateCurveMappingF,
|
||||
METH_VARARGS,
|
||||
Freestyle_evaluateCurveMappingF___doc__},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*-----------------------Freestyle module definition---------------------------*/
|
||||
|
||||
static PyModuleDef module_definition = {
|
||||
/*m_base*/ PyModuleDef_HEAD_INIT,
|
||||
/*m_name*/ "_freestyle",
|
||||
/*m_doc*/ module_docstring,
|
||||
/*m_size*/ -1,
|
||||
/*m_methods*/ module_functions,
|
||||
/*m_slots*/ nullptr,
|
||||
/*m_traverse*/ nullptr,
|
||||
/*m_clear*/ nullptr,
|
||||
/*m_free*/ nullptr,
|
||||
};
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
PyObject *Freestyle_Init()
|
||||
{
|
||||
PyObject *module;
|
||||
|
||||
// initialize modules
|
||||
module = PyModule_Create(&module_definition);
|
||||
if (!module) {
|
||||
return nullptr;
|
||||
}
|
||||
PyDict_SetItemString(PySys_GetObject("modules"), module_definition.m_name, module);
|
||||
|
||||
// update 'sys.path' for Freestyle Python API modules
|
||||
const std::optional<std::string> path = BKE_appdir_folder_id(blender::BLENDER_SYSTEM_SCRIPTS,
|
||||
"freestyle");
|
||||
if (path.has_value()) {
|
||||
char modpath[FILE_MAX];
|
||||
blender::BLI_path_join(modpath, sizeof(modpath), path->c_str(), "modules");
|
||||
PyObject *sys_path = PySys_GetObject("path"); /* borrow */
|
||||
PyObject *py_modpath = blender::PyC_UnicodeFromBytes(modpath);
|
||||
PyList_Append(sys_path, py_modpath);
|
||||
Py_DECREF(py_modpath);
|
||||
#if 0
|
||||
printf("Adding Python path: %s\n", modpath);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
printf(
|
||||
"Freestyle: couldn't find 'scripts/freestyle/modules', Freestyle won't work properly.\n");
|
||||
}
|
||||
|
||||
// attach its classes (adding the object types to the module)
|
||||
|
||||
// those classes have to be initialized before the others
|
||||
MediumType_Init(module);
|
||||
Nature_Init(module);
|
||||
|
||||
BBox_Init(module);
|
||||
BinaryPredicate0D_Init(module);
|
||||
BinaryPredicate1D_Init(module);
|
||||
ContextFunctions_Init(module);
|
||||
FrsMaterial_Init(module);
|
||||
FrsNoise_Init(module);
|
||||
Id_Init(module);
|
||||
IntegrationType_Init(module);
|
||||
Interface0D_Init(module);
|
||||
Interface1D_Init(module);
|
||||
Iterator_Init(module);
|
||||
Operators_Init(module);
|
||||
SShape_Init(module);
|
||||
StrokeAttribute_Init(module);
|
||||
StrokeShader_Init(module);
|
||||
UnaryFunction0D_Init(module);
|
||||
UnaryFunction1D_Init(module);
|
||||
UnaryPredicate0D_Init(module);
|
||||
UnaryPredicate1D_Init(module);
|
||||
ViewMap_Init(module);
|
||||
ViewShape_Init(module);
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,19 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*---------------------------Python BPy_Freestyle visible prototypes-----------*/
|
||||
|
||||
PyObject *Freestyle_Init(void);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,594 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_FrsMaterial.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
|
||||
#include "BLI_hash_mm2a.hh"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int FrsMaterial_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&FrsMaterial_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Material", (PyObject *)&FrsMaterial_Type);
|
||||
|
||||
FrsMaterial_mathutils_register_callback();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsMaterial_doc,
|
||||
"Class defining a material.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(line, diffuse, ambient, specular, emission, shininess, priority)``\n"
|
||||
"\n"
|
||||
" Creates a :class:`FrsMaterial` using either default constructor,\n"
|
||||
" copy constructor, or an overloaded constructor\n"
|
||||
"\n"
|
||||
" :param brother: A Material object to be used as a copy constructor.\n"
|
||||
" :type brother: :class:`Material`\n"
|
||||
" :param line: The line color.\n"
|
||||
" :type line: :class:`mathutils.Vector` | tuple[float, float, float, float] | list[float]\n"
|
||||
" :param diffuse: The diffuse color.\n"
|
||||
" :type diffuse: \n"
|
||||
" :param ambient: The ambient color.\n"
|
||||
" :type ambient: :class:`mathutils.Vector` | tuple[float, float, float, float] | "
|
||||
"list[float]\n"
|
||||
" :param specular: The specular color.\n"
|
||||
" :type specular: :class:`mathutils.Vector` | tuple[float, float, float, float] | "
|
||||
"list[float]\n"
|
||||
" :param emission: The emissive color.\n"
|
||||
" :type emission: :class:`mathutils.Vector` | tuple[float, float, float, float] | "
|
||||
"list[float]\n"
|
||||
" :param shininess: The shininess coefficient.\n"
|
||||
" :type shininess: float\n"
|
||||
" :param priority: The line color priority.\n"
|
||||
" :type priority: int\n");
|
||||
static int FrsMaterial_init(BPy_FrsMaterial *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {
|
||||
"line", "diffuse", "ambient", "specular", "emission", "shininess", "priority", nullptr};
|
||||
PyObject *brother = nullptr;
|
||||
float line[4], diffuse[4], ambient[4], specular[4], emission[4], shininess;
|
||||
int priority;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "|O!", (char **)kwlist_1, &FrsMaterial_Type, &brother))
|
||||
{
|
||||
if (!brother) {
|
||||
self->m = new FrsMaterial();
|
||||
}
|
||||
else {
|
||||
FrsMaterial *m = ((BPy_FrsMaterial *)brother)->m;
|
||||
if (!m) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "invalid Material object");
|
||||
return -1;
|
||||
}
|
||||
self->m = new FrsMaterial(*m);
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O&O&O&O&O&fi",
|
||||
(char **)kwlist_2,
|
||||
convert_v4,
|
||||
line,
|
||||
convert_v4,
|
||||
diffuse,
|
||||
convert_v4,
|
||||
ambient,
|
||||
convert_v4,
|
||||
specular,
|
||||
convert_v4,
|
||||
emission,
|
||||
&shininess,
|
||||
&priority))
|
||||
{
|
||||
self->m = new FrsMaterial(line, diffuse, ambient, specular, emission, shininess, priority);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void FrsMaterial_dealloc(BPy_FrsMaterial *self)
|
||||
{
|
||||
delete self->m;
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *FrsMaterial_repr(BPy_FrsMaterial *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("Material - address: %p", self->m);
|
||||
}
|
||||
|
||||
/*----------------------mathutils callbacks ----------------------------*/
|
||||
|
||||
/* subtype */
|
||||
#define MATHUTILS_SUBTYPE_DIFFUSE 1
|
||||
#define MATHUTILS_SUBTYPE_SPECULAR 2
|
||||
#define MATHUTILS_SUBTYPE_AMBIENT 3
|
||||
#define MATHUTILS_SUBTYPE_EMISSION 4
|
||||
#define MATHUTILS_SUBTYPE_LINE 5
|
||||
|
||||
static int FrsMaterial_mathutils_check(blender::BaseMathObject *bmo)
|
||||
{
|
||||
if (!BPy_FrsMaterial_Check(bmo->cb_user)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FrsMaterial_mathutils_get(blender::BaseMathObject *bmo, int subtype)
|
||||
{
|
||||
BPy_FrsMaterial *self = (BPy_FrsMaterial *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_LINE:
|
||||
bmo->data[0] = self->m->lineR();
|
||||
bmo->data[1] = self->m->lineG();
|
||||
bmo->data[2] = self->m->lineB();
|
||||
bmo->data[3] = self->m->lineA();
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_DIFFUSE:
|
||||
bmo->data[0] = self->m->diffuseR();
|
||||
bmo->data[1] = self->m->diffuseG();
|
||||
bmo->data[2] = self->m->diffuseB();
|
||||
bmo->data[3] = self->m->diffuseA();
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_SPECULAR:
|
||||
bmo->data[0] = self->m->specularR();
|
||||
bmo->data[1] = self->m->specularG();
|
||||
bmo->data[2] = self->m->specularB();
|
||||
bmo->data[3] = self->m->specularA();
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_AMBIENT:
|
||||
bmo->data[0] = self->m->ambientR();
|
||||
bmo->data[1] = self->m->ambientG();
|
||||
bmo->data[2] = self->m->ambientB();
|
||||
bmo->data[3] = self->m->ambientA();
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_EMISSION:
|
||||
bmo->data[0] = self->m->emissionR();
|
||||
bmo->data[1] = self->m->emissionG();
|
||||
bmo->data[2] = self->m->emissionB();
|
||||
bmo->data[3] = self->m->emissionA();
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FrsMaterial_mathutils_set(blender::BaseMathObject *bmo, int subtype)
|
||||
{
|
||||
BPy_FrsMaterial *self = (BPy_FrsMaterial *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_LINE:
|
||||
self->m->setLine(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_DIFFUSE:
|
||||
self->m->setDiffuse(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_SPECULAR:
|
||||
self->m->setSpecular(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_AMBIENT:
|
||||
self->m->setAmbient(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_EMISSION:
|
||||
self->m->setEmission(bmo->data[0], bmo->data[1], bmo->data[2], bmo->data[3]);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FrsMaterial_mathutils_get_index(blender::BaseMathObject *bmo, int subtype, int index)
|
||||
{
|
||||
BPy_FrsMaterial *self = (BPy_FrsMaterial *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_LINE: {
|
||||
const float *color = self->m->line();
|
||||
bmo->data[index] = color[index];
|
||||
break;
|
||||
}
|
||||
case MATHUTILS_SUBTYPE_DIFFUSE: {
|
||||
const float *color = self->m->diffuse();
|
||||
bmo->data[index] = color[index];
|
||||
break;
|
||||
}
|
||||
case MATHUTILS_SUBTYPE_SPECULAR: {
|
||||
const float *color = self->m->specular();
|
||||
bmo->data[index] = color[index];
|
||||
break;
|
||||
}
|
||||
case MATHUTILS_SUBTYPE_AMBIENT: {
|
||||
const float *color = self->m->ambient();
|
||||
bmo->data[index] = color[index];
|
||||
break;
|
||||
}
|
||||
case MATHUTILS_SUBTYPE_EMISSION: {
|
||||
const float *color = self->m->emission();
|
||||
bmo->data[index] = color[index];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FrsMaterial_mathutils_set_index(blender::BaseMathObject *bmo, int subtype, int index)
|
||||
{
|
||||
BPy_FrsMaterial *self = (BPy_FrsMaterial *)bmo->cb_user;
|
||||
float color[4];
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_LINE:
|
||||
blender::copy_v4_v4(color, self->m->line());
|
||||
color[index] = bmo->data[index];
|
||||
self->m->setLine(color[0], color[1], color[2], color[3]);
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_DIFFUSE:
|
||||
blender::copy_v4_v4(color, self->m->diffuse());
|
||||
color[index] = bmo->data[index];
|
||||
self->m->setDiffuse(color[0], color[1], color[2], color[3]);
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_SPECULAR:
|
||||
blender::copy_v4_v4(color, self->m->specular());
|
||||
color[index] = bmo->data[index];
|
||||
self->m->setSpecular(color[0], color[1], color[2], color[3]);
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_AMBIENT:
|
||||
blender::copy_v4_v4(color, self->m->ambient());
|
||||
color[index] = bmo->data[index];
|
||||
self->m->setAmbient(color[0], color[1], color[2], color[3]);
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_EMISSION:
|
||||
blender::copy_v4_v4(color, self->m->emission());
|
||||
color[index] = bmo->data[index];
|
||||
self->m->setEmission(color[0], color[1], color[2], color[3]);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static blender::Mathutils_Callback FrsMaterial_mathutils_cb = {
|
||||
FrsMaterial_mathutils_check,
|
||||
FrsMaterial_mathutils_get,
|
||||
FrsMaterial_mathutils_set,
|
||||
FrsMaterial_mathutils_get_index,
|
||||
FrsMaterial_mathutils_set_index,
|
||||
};
|
||||
|
||||
static uchar FrsMaterial_mathutils_cb_index = -1;
|
||||
|
||||
void FrsMaterial_mathutils_register_callback()
|
||||
{
|
||||
FrsMaterial_mathutils_cb_index = Mathutils_RegisterCallback(&FrsMaterial_mathutils_cb);
|
||||
}
|
||||
|
||||
/*----------------------FrsMaterial get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsMaterial_line_doc,
|
||||
"RGBA components of the line color of the material.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Vector`\n");
|
||||
static PyObject *FrsMaterial_line_get(BPy_FrsMaterial *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Vector_CreatePyObject_cb(
|
||||
(PyObject *)self, 4, FrsMaterial_mathutils_cb_index, MATHUTILS_SUBTYPE_LINE);
|
||||
}
|
||||
|
||||
static int FrsMaterial_line_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float color[4];
|
||||
if (blender::mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") ==
|
||||
-1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
self->m->setLine(color[0], color[1], color[2], color[3]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsMaterial_diffuse_doc,
|
||||
"RGBA components of the diffuse color of the material.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Vector`\n");
|
||||
static PyObject *FrsMaterial_diffuse_get(BPy_FrsMaterial *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Vector_CreatePyObject_cb(
|
||||
(PyObject *)self, 4, FrsMaterial_mathutils_cb_index, MATHUTILS_SUBTYPE_DIFFUSE);
|
||||
}
|
||||
|
||||
static int FrsMaterial_diffuse_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float color[4];
|
||||
if (blender::mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") ==
|
||||
-1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
self->m->setDiffuse(color[0], color[1], color[2], color[3]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsMaterial_specular_doc,
|
||||
"RGBA components of the specular color of the material.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Vector`\n");
|
||||
static PyObject *FrsMaterial_specular_get(BPy_FrsMaterial *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Vector_CreatePyObject_cb(
|
||||
(PyObject *)self, 4, FrsMaterial_mathutils_cb_index, MATHUTILS_SUBTYPE_SPECULAR);
|
||||
}
|
||||
|
||||
static int FrsMaterial_specular_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float color[4];
|
||||
if (blender::mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") ==
|
||||
-1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
self->m->setSpecular(color[0], color[1], color[2], color[3]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsMaterial_ambient_doc,
|
||||
"RGBA components of the ambient color of the material.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Color`\n");
|
||||
static PyObject *FrsMaterial_ambient_get(BPy_FrsMaterial *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Vector_CreatePyObject_cb(
|
||||
(PyObject *)self, 4, FrsMaterial_mathutils_cb_index, MATHUTILS_SUBTYPE_AMBIENT);
|
||||
}
|
||||
|
||||
static int FrsMaterial_ambient_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float color[4];
|
||||
if (blender::mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") ==
|
||||
-1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
self->m->setAmbient(color[0], color[1], color[2], color[3]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsMaterial_emission_doc,
|
||||
"RGBA components of the emissive color of the material.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Color`\n");
|
||||
static PyObject *FrsMaterial_emission_get(BPy_FrsMaterial *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Vector_CreatePyObject_cb(
|
||||
(PyObject *)self, 4, FrsMaterial_mathutils_cb_index, MATHUTILS_SUBTYPE_EMISSION);
|
||||
}
|
||||
|
||||
static int FrsMaterial_emission_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float color[4];
|
||||
if (blender::mathutils_array_parse(color, 4, 4, value, "value must be a 4-dimensional vector") ==
|
||||
-1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
self->m->setEmission(color[0], color[1], color[2], color[3]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsMaterial_shininess_doc,
|
||||
"Shininess coefficient of the material.\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *FrsMaterial_shininess_get(BPy_FrsMaterial *self, void * /*closure*/)
|
||||
{
|
||||
return PyFloat_FromDouble(self->m->shininess());
|
||||
}
|
||||
|
||||
static int FrsMaterial_shininess_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float scalar;
|
||||
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
|
||||
/* parsed item not a number */
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a number");
|
||||
return -1;
|
||||
}
|
||||
self->m->setShininess(scalar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsMaterial_priority_doc,
|
||||
"Line color priority of the material.\n"
|
||||
"\n"
|
||||
":type: int\n");
|
||||
static PyObject *FrsMaterial_priority_get(BPy_FrsMaterial *self, void * /*closure*/)
|
||||
{
|
||||
return PyLong_FromLong(self->m->priority());
|
||||
}
|
||||
|
||||
static int FrsMaterial_priority_set(BPy_FrsMaterial *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
int scalar;
|
||||
if ((scalar = PyLong_AsLong(value)) == -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an integer");
|
||||
return -1;
|
||||
}
|
||||
self->m->setPriority(scalar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_FrsMaterial_getseters[] = {
|
||||
{"line",
|
||||
(getter)FrsMaterial_line_get,
|
||||
(setter)FrsMaterial_line_set,
|
||||
FrsMaterial_line_doc,
|
||||
nullptr},
|
||||
{"diffuse",
|
||||
(getter)FrsMaterial_diffuse_get,
|
||||
(setter)FrsMaterial_diffuse_set,
|
||||
FrsMaterial_diffuse_doc,
|
||||
nullptr},
|
||||
{"specular",
|
||||
(getter)FrsMaterial_specular_get,
|
||||
(setter)FrsMaterial_specular_set,
|
||||
FrsMaterial_specular_doc,
|
||||
nullptr},
|
||||
{"ambient",
|
||||
(getter)FrsMaterial_ambient_get,
|
||||
(setter)FrsMaterial_ambient_set,
|
||||
FrsMaterial_ambient_doc,
|
||||
nullptr},
|
||||
{"emission",
|
||||
(getter)FrsMaterial_emission_get,
|
||||
(setter)FrsMaterial_emission_set,
|
||||
FrsMaterial_emission_doc,
|
||||
nullptr},
|
||||
{"shininess",
|
||||
(getter)FrsMaterial_shininess_get,
|
||||
(setter)FrsMaterial_shininess_set,
|
||||
FrsMaterial_shininess_doc,
|
||||
nullptr},
|
||||
{"priority",
|
||||
(getter)FrsMaterial_priority_get,
|
||||
(setter)FrsMaterial_priority_set,
|
||||
FrsMaterial_priority_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
static PyObject *BPy_FrsMaterial_richcmpr(PyObject *objectA,
|
||||
PyObject *objectB,
|
||||
int comparison_type)
|
||||
{
|
||||
const BPy_FrsMaterial *matA = nullptr, *matB = nullptr;
|
||||
bool result = false;
|
||||
|
||||
if (!BPy_FrsMaterial_Check(objectA) || !BPy_FrsMaterial_Check(objectB)) {
|
||||
if (comparison_type == Py_NE) {
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
matA = (BPy_FrsMaterial *)objectA;
|
||||
matB = (BPy_FrsMaterial *)objectB;
|
||||
|
||||
switch (comparison_type) {
|
||||
case Py_NE:
|
||||
result = (*matA->m) != (*matB->m);
|
||||
break;
|
||||
case Py_EQ:
|
||||
result = (*matA->m) == (*matB->m);
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString(PyExc_TypeError, "Material does not support this comparison type");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (result == true) {
|
||||
Py_RETURN_TRUE;
|
||||
}
|
||||
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
|
||||
static Py_hash_t FrsMaterial_hash(PyObject *self)
|
||||
{
|
||||
return (Py_uhash_t)blender::BLI_hash_mm2((const uchar *)self, sizeof(*self), 0);
|
||||
}
|
||||
/*-----------------------BPy_FrsMaterial type definition ------------------------------*/
|
||||
|
||||
PyTypeObject FrsMaterial_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Material",
|
||||
/*tp_basicsize*/ sizeof(BPy_FrsMaterial),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)FrsMaterial_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)FrsMaterial_repr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ (hashfunc)FrsMaterial_hash,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ FrsMaterial_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ (richcmpfunc)BPy_FrsMaterial_richcmpr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_FrsMaterial_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)FrsMaterial_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,35 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../scene_graph/FrsMaterial.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject FrsMaterial_Type;
|
||||
|
||||
#define BPy_FrsMaterial_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&FrsMaterial_Type))
|
||||
|
||||
/*---------------------------Python BPy_FrsMaterial structure definition----------*/
|
||||
struct BPy_FrsMaterial {
|
||||
PyObject_HEAD
|
||||
Freestyle::FrsMaterial *m;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_FrsMaterial visible prototypes-----------*/
|
||||
|
||||
int FrsMaterial_Init(PyObject *module);
|
||||
void FrsMaterial_mathutils_register_callback();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,381 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_FrsNoise.h"
|
||||
#include "BPy_Convert.h"
|
||||
|
||||
#include "../system/RandGen.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int FrsNoise_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&FrsNoise_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Noise", (PyObject *)&FrsNoise_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsNoise_doc,
|
||||
"Class to provide Perlin noise functionalities.\n"
|
||||
"\n"
|
||||
".. method:: __init__(seed = -1)\n"
|
||||
"\n"
|
||||
" Builds a Noise object. Seed is an optional argument. The seed value is used\n"
|
||||
" as a seed for random number generation if it is equal to or greater than zero;\n"
|
||||
" otherwise, time is used as a seed.\n"
|
||||
"\n"
|
||||
" :param seed: Seed for random number generation.\n"
|
||||
" :type seed: int\n");
|
||||
static int FrsNoise_init(BPy_FrsNoise *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"seed", nullptr};
|
||||
long seed = -1;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|l", (char **)kwlist, &seed)) {
|
||||
return -1;
|
||||
}
|
||||
self->n = new Noise(seed);
|
||||
self->pn = new PseudoNoise();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void FrsNoise_dealloc(BPy_FrsNoise *self)
|
||||
{
|
||||
delete self->n;
|
||||
delete self->pn;
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *FrsNoise_repr(BPy_FrsNoise *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("Noise - address: %p", self->n);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsNoise_turbulence1_doc,
|
||||
".. method:: turbulence1(v, freq, amp, oct=4)\n"
|
||||
"\n"
|
||||
" Returns a noise value for a 1D element.\n"
|
||||
"\n"
|
||||
" :param v: One-dimensional sample point.\n"
|
||||
" :type v: float\n"
|
||||
" :param freq: Noise frequency.\n"
|
||||
" :type freq: float\n"
|
||||
" :param amp: Amplitude.\n"
|
||||
" :type amp: float\n"
|
||||
" :param oct: Number of octaves.\n"
|
||||
" :type oct: int\n"
|
||||
" :return: A noise value.\n"
|
||||
" :rtype: float\n");
|
||||
static PyObject *FrsNoise_drand(BPy_FrsNoise * /*self*/, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"seed", nullptr};
|
||||
long seed = 0;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|I", (char **)kwlist, &seed)) {
|
||||
PyErr_SetString(PyExc_TypeError, "optional argument 1 must be of type int");
|
||||
return nullptr;
|
||||
}
|
||||
if (seed) {
|
||||
RandGen::srand48(seed);
|
||||
}
|
||||
return PyFloat_FromDouble(RandGen::drand48());
|
||||
}
|
||||
|
||||
static PyObject *FrsNoise_turbulence_smooth(BPy_FrsNoise *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"v", "oct", nullptr};
|
||||
|
||||
double x; // NOTE: this has to be a double (not float)
|
||||
uint nbOctaves = 8;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "d|I", (char **)kwlist, &x, &nbOctaves)) {
|
||||
return nullptr;
|
||||
}
|
||||
return PyFloat_FromDouble(self->pn->turbulenceSmooth(x, nbOctaves));
|
||||
}
|
||||
|
||||
static PyObject *FrsNoise_turbulence1(BPy_FrsNoise *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"v", "freq", "amp", "oct", nullptr};
|
||||
float f1, f2, f3;
|
||||
uint i = 4;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "fff|I", (char **)kwlist, &f1, &f2, &f3, &i)) {
|
||||
return nullptr;
|
||||
}
|
||||
return PyFloat_FromDouble(self->n->turbulence1(f1, f2, f3, i));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsNoise_turbulence2_doc,
|
||||
".. method:: turbulence2(v, freq, amp, oct=4)\n"
|
||||
"\n"
|
||||
" Returns a noise value for a 2D element.\n"
|
||||
"\n"
|
||||
" :param v: Two-dimensional sample point.\n"
|
||||
" :type v: :class:`mathutils.Vector` | tuple[float, float] | list[float]\n"
|
||||
" :param freq: Noise frequency.\n"
|
||||
" :type freq: float\n"
|
||||
" :param amp: Amplitude.\n"
|
||||
" :type amp: float\n"
|
||||
" :param oct: Number of octaves.\n"
|
||||
" :type oct: int\n"
|
||||
" :return: A noise value.\n"
|
||||
" :rtype: float\n");
|
||||
static PyObject *FrsNoise_turbulence2(BPy_FrsNoise *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"v", "freq", "amp", "oct", nullptr};
|
||||
PyObject *obj1;
|
||||
float f2, f3;
|
||||
uint i = 4;
|
||||
Vec2f vec;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "Off|I", (char **)kwlist, &obj1, &f2, &f3, &i)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!Vec2f_ptr_from_PyObject(obj1, vec)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"argument 1 must be a 2D vector (either a list of 2 elements or Vector)");
|
||||
return nullptr;
|
||||
}
|
||||
float t = self->n->turbulence2(vec, f2, f3, i);
|
||||
return PyFloat_FromDouble(t);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsNoise_turbulence3_doc,
|
||||
".. method:: turbulence3(v, freq, amp, oct=4)\n"
|
||||
"\n"
|
||||
" Returns a noise value for a 3D element.\n"
|
||||
"\n"
|
||||
" :param v: Three-dimensional sample point.\n"
|
||||
" :type v: :class:`mathutils.Vector` | tuple[float, float, float] | list[float]\n"
|
||||
" :param freq: Noise frequency.\n"
|
||||
" :type freq: float\n"
|
||||
" :param amp: Amplitude.\n"
|
||||
" :type amp: float\n"
|
||||
" :param oct: Number of octaves.\n"
|
||||
" :type oct: int\n"
|
||||
" :return: A noise value.\n"
|
||||
" :rtype: float\n");
|
||||
static PyObject *FrsNoise_turbulence3(BPy_FrsNoise *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"v", "freq", "amp", "oct", nullptr};
|
||||
PyObject *obj1;
|
||||
float f2, f3;
|
||||
uint i = 4;
|
||||
Vec3f vec;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "Off|I", (char **)kwlist, &obj1, &f2, &f3, &i)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!Vec3f_ptr_from_PyObject(obj1, vec)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"argument 1 must be a 3D vector (either a list of 3 elements or Vector)");
|
||||
return nullptr;
|
||||
}
|
||||
float t = self->n->turbulence3(vec, f2, f3, i);
|
||||
return PyFloat_FromDouble(t);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsNoise_smoothNoise1_doc,
|
||||
".. method:: smoothNoise1(v)\n"
|
||||
"\n"
|
||||
" Returns a smooth noise value for a 1D element.\n"
|
||||
"\n"
|
||||
" :param v: One-dimensional sample point.\n"
|
||||
" :type v: float\n"
|
||||
" :return: A smooth noise value.\n"
|
||||
" :rtype: float\n");
|
||||
static PyObject *FrsNoise_smoothNoise1(BPy_FrsNoise *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"v", nullptr};
|
||||
float f;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist, &f)) {
|
||||
return nullptr;
|
||||
}
|
||||
return PyFloat_FromDouble(self->n->smoothNoise1(f));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsNoise_smoothNoise2_doc,
|
||||
".. method:: smoothNoise2(v)\n"
|
||||
"\n"
|
||||
" Returns a smooth noise value for a 2D element.\n"
|
||||
"\n"
|
||||
" :param v: Two-dimensional sample point.\n"
|
||||
" :type v: :class:`mathutils.Vector` | tuple[float, float] | list[float]\n"
|
||||
" :return: A smooth noise value.\n"
|
||||
" :rtype: float\n");
|
||||
static PyObject *FrsNoise_smoothNoise2(BPy_FrsNoise *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"v", nullptr};
|
||||
PyObject *obj;
|
||||
Vec2f vec;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", (char **)kwlist, &obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!Vec2f_ptr_from_PyObject(obj, vec)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"argument 1 must be a 2D vector (either a list of 2 elements or Vector)");
|
||||
return nullptr;
|
||||
}
|
||||
float t = self->n->smoothNoise2(vec);
|
||||
return PyFloat_FromDouble(t);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsNoise_smoothNoise3_doc,
|
||||
".. method:: smoothNoise3(v)\n"
|
||||
"\n"
|
||||
" Returns a smooth noise value for a 3D element.\n"
|
||||
"\n"
|
||||
" :param v: Three-dimensional sample point.\n"
|
||||
" :type v: :class:`mathutils.Vector` | tuple[float, float, float] | list[float]\n"
|
||||
" :return: A smooth noise value.\n"
|
||||
" :rtype: float\n");
|
||||
static PyObject *FrsNoise_smoothNoise3(BPy_FrsNoise *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"v", nullptr};
|
||||
PyObject *obj;
|
||||
Vec3f vec;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", (char **)kwlist, &obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!Vec3f_ptr_from_PyObject(obj, vec)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"argument 1 must be a 3D vector (either a list of 3 elements or Vector)");
|
||||
return nullptr;
|
||||
}
|
||||
float t = self->n->smoothNoise3(vec);
|
||||
return PyFloat_FromDouble(t);
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_FrsNoise_methods[] = {
|
||||
{"turbulence1",
|
||||
(PyCFunction)FrsNoise_turbulence1,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
FrsNoise_turbulence1_doc},
|
||||
{"turbulence2",
|
||||
(PyCFunction)FrsNoise_turbulence2,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
FrsNoise_turbulence2_doc},
|
||||
{"turbulence3",
|
||||
(PyCFunction)FrsNoise_turbulence3,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
FrsNoise_turbulence3_doc},
|
||||
{"smoothNoise1",
|
||||
(PyCFunction)FrsNoise_smoothNoise1,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
FrsNoise_smoothNoise1_doc},
|
||||
{"smoothNoise2",
|
||||
(PyCFunction)FrsNoise_smoothNoise2,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
FrsNoise_smoothNoise2_doc},
|
||||
{"smoothNoise3",
|
||||
(PyCFunction)FrsNoise_smoothNoise3,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
FrsNoise_smoothNoise3_doc},
|
||||
{"rand", (PyCFunction)FrsNoise_drand, METH_VARARGS | METH_KEYWORDS, nullptr},
|
||||
{"turbulence_smooth",
|
||||
(PyCFunction)FrsNoise_turbulence_smooth,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
nullptr},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*-----------------------BPy_FrsNoise type definition ------------------------------*/
|
||||
|
||||
PyTypeObject FrsNoise_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Noise",
|
||||
/*tp_basicsize*/ sizeof(BPy_FrsNoise),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)FrsNoise_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)FrsNoise_repr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ FrsNoise_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_FrsNoise_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)FrsNoise_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,35 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../geometry/Noise.h"
|
||||
#include "../system/PseudoNoise.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject FrsNoise_Type;
|
||||
|
||||
#define BPy_FrsNoise_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&FrsNoise_Type))
|
||||
|
||||
/*---------------------------Python BPy_FrsNoise structure definition----------*/
|
||||
struct BPy_FrsNoise {
|
||||
PyObject_HEAD
|
||||
Freestyle::Noise *n;
|
||||
Freestyle::PseudoNoise *pn;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_FrsNoise visible prototypes-----------*/
|
||||
|
||||
int FrsNoise_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
202
blender-5.2.0/source/blender/freestyle/intern/python/BPy_Id.cpp
Normal file
202
blender-5.2.0/source/blender/freestyle/intern/python/BPy_Id.cpp
Normal file
@@ -0,0 +1,202 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_Id.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int Id_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&Id_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyModule_AddObjectRef(module, "Id", (PyObject *)&Id_Type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Id_doc,
|
||||
"Class for representing an object Id.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args, **kwargs)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(first=0, second=0)``\n"
|
||||
"\n"
|
||||
" Build the Id from two numbers or another :class:`Id` using the copy constructor.\n"
|
||||
"\n"
|
||||
" :param brother: An Id object.\n"
|
||||
" :type brother: :class:`Id`\n"
|
||||
" :param first: The first number.\n"
|
||||
" :type first: int\n"
|
||||
" :param second: The second number.\n"
|
||||
" :type second: int\n");
|
||||
static int Id_init(BPy_Id *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"first", "second", nullptr};
|
||||
PyObject *brother;
|
||||
int first = 0, second = 0;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_1, &Id_Type, &brother)) {
|
||||
self->id = new Id(*(((BPy_Id *)brother)->id));
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(args, kwds, "|ii", (char **)kwlist_2, &first, &second))
|
||||
{
|
||||
self->id = new Id(first, second);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Id_dealloc(BPy_Id *self)
|
||||
{
|
||||
delete self->id;
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *Id_repr(BPy_Id *self)
|
||||
{
|
||||
return PyUnicode_FromFormat(
|
||||
"[ first: %i, second: %i ](BPy_Id)", self->id->getFirst(), self->id->getSecond());
|
||||
}
|
||||
|
||||
static PyObject *Id_RichCompare(BPy_Id *o1, BPy_Id *o2, int opid)
|
||||
{
|
||||
switch (opid) {
|
||||
case Py_LT:
|
||||
return PyBool_from_bool(o1->id->operator<(*(o2->id)));
|
||||
case Py_LE:
|
||||
return PyBool_from_bool(o1->id->operator<(*(o2->id)) || o1->id->operator==(*(o2->id)));
|
||||
case Py_EQ:
|
||||
return PyBool_from_bool(o1->id->operator==(*(o2->id)));
|
||||
case Py_NE:
|
||||
return PyBool_from_bool(o1->id->operator!=(*(o2->id)));
|
||||
case Py_GT:
|
||||
return PyBool_from_bool(!(o1->id->operator<(*(o2->id)) || o1->id->operator==(*(o2->id))));
|
||||
case Py_GE:
|
||||
return PyBool_from_bool(!o1->id->operator<(*(o2->id)));
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/*----------------------Id get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Id_first_doc,
|
||||
"The first number constituting the Id.\n"
|
||||
"\n"
|
||||
":type: int\n");
|
||||
static PyObject *Id_first_get(BPy_Id *self, void * /*closure*/)
|
||||
{
|
||||
return PyLong_FromLong(self->id->getFirst());
|
||||
}
|
||||
|
||||
static int Id_first_set(BPy_Id *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
int scalar;
|
||||
if ((scalar = PyLong_AsLong(value)) == -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an integer");
|
||||
return -1;
|
||||
}
|
||||
self->id->setFirst(scalar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Id_second_doc,
|
||||
"The second number constituting the Id.\n"
|
||||
"\n"
|
||||
":type: int\n");
|
||||
static PyObject *Id_second_get(BPy_Id *self, void * /*closure*/)
|
||||
{
|
||||
return PyLong_FromLong(self->id->getSecond());
|
||||
}
|
||||
|
||||
static int Id_second_set(BPy_Id *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
int scalar;
|
||||
if ((scalar = PyLong_AsLong(value)) == -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an integer");
|
||||
return -1;
|
||||
}
|
||||
self->id->setSecond(scalar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_Id_getseters[] = {
|
||||
{"first", (getter)Id_first_get, (setter)Id_first_set, Id_first_doc, nullptr},
|
||||
{"second", (getter)Id_second_get, (setter)Id_second_set, Id_second_doc, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_Id type definition ------------------------------*/
|
||||
|
||||
PyTypeObject Id_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Id",
|
||||
/*tp_basicsize*/ sizeof(BPy_Id),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)Id_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)Id_repr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ Id_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ (richcmpfunc)Id_RichCompare,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_Id_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)Id_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,35 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../system/Id.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject Id_Type;
|
||||
|
||||
#define BPy_Id_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Id_Type))
|
||||
|
||||
/*---------------------------Python BPy_Id structure definition----------*/
|
||||
struct BPy_Id {
|
||||
PyObject_HEAD
|
||||
Freestyle::Id *id;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_Id visible prototypes-----------*/
|
||||
|
||||
int Id_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,267 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_IntegrationType.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
#include "Iterator/BPy_Interface0DIterator.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DDouble.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DFloat.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------ MODULE FUNCTIONS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Integrator_integrate_doc,
|
||||
".. function:: integrate(func, it, it_end, integration_type)\n"
|
||||
"\n"
|
||||
" Returns a single value from a set of values evaluated at each 0D\n"
|
||||
" element of this 1D element.\n"
|
||||
"\n"
|
||||
" :param func: The UnaryFunction0D used to compute a value at each\n"
|
||||
" Interface0D.\n"
|
||||
" :type func: :class:`UnaryFunction0D`\n"
|
||||
" :param it: The Interface0DIterator used to iterate over the 0D\n"
|
||||
" elements of this 1D element. The integration will occur over\n"
|
||||
" the 0D elements starting from the one pointed by it.\n"
|
||||
" :type it: :class:`Interface0DIterator`\n"
|
||||
" :param it_end: The Interface0DIterator pointing the end of the 0D\n"
|
||||
" elements of the 1D element.\n"
|
||||
" :type it_end: :class:`Interface0DIterator`\n"
|
||||
" :param integration_type: The integration method used to compute a\n"
|
||||
" single value from a set of values.\n"
|
||||
" :type integration_type: :class:`IntegrationType`\n"
|
||||
" :return: The single value obtained for the 1D element. The return\n"
|
||||
" value type is float if func is of the :class:`UnaryFunction0DDouble`\n"
|
||||
" or :class:`UnaryFunction0DFloat` type, and int if func is of the\n"
|
||||
" :class:`UnaryFunction0DUnsigned` type.\n"
|
||||
" :rtype: int | float\n");
|
||||
static PyObject *Integrator_integrate(PyObject * /*self*/, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"func", "it", "it_end", "integration_type", nullptr};
|
||||
PyObject *obj1, *obj4 = nullptr;
|
||||
BPy_Interface0DIterator *obj2, *obj3;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!O!O!|O!",
|
||||
(char **)kwlist,
|
||||
&UnaryFunction0D_Type,
|
||||
&obj1,
|
||||
&Interface0DIterator_Type,
|
||||
&obj2,
|
||||
&Interface0DIterator_Type,
|
||||
&obj3,
|
||||
&IntegrationType_Type,
|
||||
&obj4))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Interface0DIterator it(*(obj2->if0D_it)), it_end(*(obj3->if0D_it));
|
||||
IntegrationType t = (obj4) ? IntegrationType_from_BPy_IntegrationType(obj4) : MEAN;
|
||||
|
||||
if (BPy_UnaryFunction0DDouble_Check(obj1)) {
|
||||
UnaryFunction0D<double> *fun = ((BPy_UnaryFunction0DDouble *)obj1)->uf0D_double;
|
||||
double res = integrate(*fun, it, it_end, t);
|
||||
return PyFloat_FromDouble(res);
|
||||
}
|
||||
if (BPy_UnaryFunction0DFloat_Check(obj1)) {
|
||||
UnaryFunction0D<float> *fun = ((BPy_UnaryFunction0DFloat *)obj1)->uf0D_float;
|
||||
float res = integrate(*fun, it, it_end, t);
|
||||
return PyFloat_FromDouble(res);
|
||||
}
|
||||
if (BPy_UnaryFunction0DUnsigned_Check(obj1)) {
|
||||
UnaryFunction0D<uint> *fun = ((BPy_UnaryFunction0DUnsigned *)obj1)->uf0D_unsigned;
|
||||
uint res = integrate(*fun, it, it_end, t);
|
||||
return PyLong_FromLong(res);
|
||||
}
|
||||
|
||||
string class_name(Py_TYPE(obj1)->tp_name);
|
||||
PyErr_SetString(PyExc_TypeError, ("unsupported function type: " + class_name).c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*-----------------------Integrator module docstring---------------------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
module_docstring,
|
||||
"The Blender Freestyle.Integrator submodule\n"
|
||||
"\n");
|
||||
|
||||
/*-----------------------Integrator module functions definitions---------------------------*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef module_functions[] = {
|
||||
{"integrate",
|
||||
(PyCFunction)Integrator_integrate,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
Integrator_integrate_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*-----------------------Integrator module definition--------------------------------------*/
|
||||
|
||||
static PyModuleDef module_definition = {
|
||||
/*m_base*/ PyModuleDef_HEAD_INIT,
|
||||
/*m_name*/ "Freestyle.Integrator",
|
||||
/*m_doc*/ module_docstring,
|
||||
/*m_size*/ -1,
|
||||
/*m_methods*/ module_functions,
|
||||
/*m_slots*/ nullptr,
|
||||
/*m_traverse*/ nullptr,
|
||||
/*m_clear*/ nullptr,
|
||||
/*m_free*/ nullptr,
|
||||
};
|
||||
|
||||
/*-----------------------BPy_IntegrationType type definition ------------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
IntegrationType_doc,
|
||||
"Class hierarchy: int > :class:`IntegrationType`\n"
|
||||
"\n"
|
||||
"Different integration methods that can be invoked to integrate into a\n"
|
||||
"single value the set of values obtained from each 0D element of an 1D\n"
|
||||
"element.\n"
|
||||
"\n"
|
||||
".. attribute:: MEAN\n"
|
||||
"\n"
|
||||
" The value computed for the 1D element is the mean of the values\n"
|
||||
" obtained for the 0D elements.\n"
|
||||
"\n"
|
||||
".. attribute:: MIN\n"
|
||||
"\n"
|
||||
" The value computed for the 1D element is the minimum of the values\n"
|
||||
" obtained for the 0D elements.\n"
|
||||
"\n"
|
||||
".. attribute:: MAX\n"
|
||||
"\n"
|
||||
" The value computed for the 1D element is the maximum of the values\n"
|
||||
" obtained for the 0D elements.\n"
|
||||
"\n"
|
||||
".. attribute:: FIRST\n"
|
||||
"\n"
|
||||
" The value computed for the 1D element is the first of the values\n"
|
||||
" obtained for the 0D elements.\n"
|
||||
"\n"
|
||||
".. attribute:: LAST\n"
|
||||
"\n"
|
||||
" The value computed for the 1D element is the last of the values\n"
|
||||
" obtained for the 0D elements.\n");
|
||||
PyTypeObject IntegrationType_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "IntegrationType",
|
||||
/*tp_basicsize*/ sizeof(PyLongObject),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT,
|
||||
/*tp_doc*/ IntegrationType_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ &PyLong_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ nullptr,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
/*-----------------------BPy_IntegrationType instance definitions -------------------------*/
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int IntegrationType_Init(PyObject *module)
|
||||
{
|
||||
PyObject *m, *d, *f;
|
||||
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&IntegrationType_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "IntegrationType", (PyObject *)&IntegrationType_Type);
|
||||
|
||||
#define ADD_TYPE_CONST(id) \
|
||||
PyLong_subtype_add_to_dict( \
|
||||
IntegrationType_Type.tp_dict, &IntegrationType_Type, STRINGIFY(id), id)
|
||||
|
||||
ADD_TYPE_CONST(MEAN);
|
||||
ADD_TYPE_CONST(MIN);
|
||||
ADD_TYPE_CONST(MAX);
|
||||
ADD_TYPE_CONST(FIRST);
|
||||
ADD_TYPE_CONST(LAST);
|
||||
|
||||
#undef ADD_TYPE_CONST
|
||||
|
||||
m = PyModule_Create(&module_definition);
|
||||
if (m == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Integrator", m);
|
||||
|
||||
// from Integrator import *
|
||||
d = PyModule_GetDict(m);
|
||||
for (PyMethodDef *p = module_functions; p->ml_name; p++) {
|
||||
f = PyDict_GetItemString(d, p->ml_name);
|
||||
PyModule_AddObjectRef(module, p->ml_name, f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,28 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../view_map/Interface1D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject IntegrationType_Type;
|
||||
|
||||
#define BPy_IntegrationType_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&IntegrationType_Type))
|
||||
|
||||
/*---------------------------Python BPy_IntegrationType visible prototypes-----------*/
|
||||
|
||||
int IntegrationType_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,359 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_Interface0D.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
#include "BPy_Nature.h"
|
||||
#include "Interface0D/BPy_CurvePoint.h"
|
||||
#include "Interface0D/BPy_SVertex.h"
|
||||
#include "Interface0D/BPy_ViewVertex.h"
|
||||
#include "Interface0D/CurvePoint/BPy_StrokeVertex.h"
|
||||
#include "Interface0D/ViewVertex/BPy_NonTVertex.h"
|
||||
#include "Interface0D/ViewVertex/BPy_TVertex.h"
|
||||
#include "Interface1D/BPy_FEdge.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int Interface0D_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&Interface0D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Interface0D", (PyObject *)&Interface0D_Type);
|
||||
|
||||
if (PyType_Ready(&CurvePoint_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "CurvePoint", (PyObject *)&CurvePoint_Type);
|
||||
|
||||
if (PyType_Ready(&SVertex_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "SVertex", (PyObject *)&SVertex_Type);
|
||||
|
||||
if (PyType_Ready(&ViewVertex_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ViewVertex", (PyObject *)&ViewVertex_Type);
|
||||
|
||||
if (PyType_Ready(&StrokeVertex_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "StrokeVertex", (PyObject *)&StrokeVertex_Type);
|
||||
|
||||
if (PyType_Ready(&NonTVertex_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "NonTVertex", (PyObject *)&NonTVertex_Type);
|
||||
|
||||
if (PyType_Ready(&TVertex_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "TVertex", (PyObject *)&TVertex_Type);
|
||||
|
||||
SVertex_mathutils_register_callback();
|
||||
StrokeVertex_mathutils_register_callback();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------Interface1D methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0D_doc,
|
||||
"Base class for any 0D element.\n"
|
||||
"\n"
|
||||
".. method:: __init__()\n"
|
||||
"\n"
|
||||
" Default constructor.\n");
|
||||
static int Interface0D_init(BPy_Interface0D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->if0D = new Interface0D();
|
||||
self->borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Interface0D_dealloc(BPy_Interface0D *self)
|
||||
{
|
||||
if (self->if0D && !self->borrowed) {
|
||||
delete self->if0D;
|
||||
}
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *Interface0D_repr(BPy_Interface0D *self)
|
||||
{
|
||||
return PyUnicode_FromFormat(
|
||||
"type: %s - address: %p", self->if0D->getExactTypeName().c_str(), self->if0D);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0D_get_fedge_doc,
|
||||
".. method:: get_fedge(inter)\n"
|
||||
"\n"
|
||||
" Returns the FEdge that lies between this 0D element and the 0D\n"
|
||||
" element given as the argument.\n"
|
||||
"\n"
|
||||
" :param inter: A 0D element.\n"
|
||||
" :type inter: :class:`Interface0D`\n"
|
||||
" :return: The FEdge lying between the two 0D elements.\n"
|
||||
" :rtype: :class:`FEdge`\n");
|
||||
static PyObject *Interface0D_get_fedge(BPy_Interface0D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"inter", nullptr};
|
||||
PyObject *py_if0D;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &Interface0D_Type, &py_if0D))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
FEdge *fe = self->if0D->getFEdge(*(((BPy_Interface0D *)py_if0D)->if0D));
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (fe) {
|
||||
return Any_BPy_FEdge_from_FEdge(*fe);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_Interface0D_methods[] = {
|
||||
{"get_fedge",
|
||||
(PyCFunction)Interface0D_get_fedge,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
Interface0D_get_fedge_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------Interface1D get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0D_name_doc,
|
||||
"The string of the name of this 0D element.\n"
|
||||
"\n"
|
||||
":type: str\n");
|
||||
static PyObject *Interface0D_name_get(BPy_Interface0D *self, void * /*closure*/)
|
||||
{
|
||||
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0D_point_3d_doc,
|
||||
"The 3D point of this 0D element.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Vector`\n");
|
||||
static PyObject *Interface0D_point_3d_get(BPy_Interface0D *self, void * /*closure*/)
|
||||
{
|
||||
Vec3f p(self->if0D->getPoint3D());
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
return Vector_from_Vec3f(p);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0D_projected_x_doc,
|
||||
"The X coordinate of the projected 3D point of this 0D element.\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *Interface0D_projected_x_get(BPy_Interface0D *self, void * /*closure*/)
|
||||
{
|
||||
real x = self->if0D->getProjectedX();
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
return PyFloat_FromDouble(x);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0D_projected_y_doc,
|
||||
"The Y coordinate of the projected 3D point of this 0D element.\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *Interface0D_projected_y_get(BPy_Interface0D *self, void * /*closure*/)
|
||||
{
|
||||
real y = self->if0D->getProjectedY();
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
return PyFloat_FromDouble(y);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0D_projected_z_doc,
|
||||
"The Z coordinate of the projected 3D point of this 0D element.\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *Interface0D_projected_z_get(BPy_Interface0D *self, void * /*closure*/)
|
||||
{
|
||||
real z = self->if0D->getProjectedZ();
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
return PyFloat_FromDouble(z);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0D_point_2d_doc,
|
||||
"The 2D point of this 0D element.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Vector`\n");
|
||||
static PyObject *Interface0D_point_2d_get(BPy_Interface0D *self, void * /*closure*/)
|
||||
{
|
||||
Vec2f p(self->if0D->getPoint2D());
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
return Vector_from_Vec2f(p);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0D_id_doc,
|
||||
"The Id of this 0D element.\n"
|
||||
"\n"
|
||||
":type: :class:`Id`\n");
|
||||
static PyObject *Interface0D_id_get(BPy_Interface0D *self, void * /*closure*/)
|
||||
{
|
||||
Id id(self->if0D->getId());
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
return BPy_Id_from_Id(id); // return a copy
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0D_nature_doc,
|
||||
"The nature of this 0D element.\n"
|
||||
"\n"
|
||||
":type: :class:`Nature`\n");
|
||||
static PyObject *Interface0D_nature_get(BPy_Interface0D *self, void * /*closure*/)
|
||||
{
|
||||
Nature::VertexNature nature = self->if0D->getNature();
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
return BPy_Nature_from_Nature(nature);
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_Interface0D_getseters[] = {
|
||||
{"name", (getter)Interface0D_name_get, (setter) nullptr, Interface0D_name_doc, nullptr},
|
||||
{"point_3d",
|
||||
(getter)Interface0D_point_3d_get,
|
||||
(setter) nullptr,
|
||||
Interface0D_point_3d_doc,
|
||||
nullptr},
|
||||
{"projected_x",
|
||||
(getter)Interface0D_projected_x_get,
|
||||
(setter) nullptr,
|
||||
Interface0D_projected_x_doc,
|
||||
nullptr},
|
||||
{"projected_y",
|
||||
(getter)Interface0D_projected_y_get,
|
||||
(setter) nullptr,
|
||||
Interface0D_projected_y_doc,
|
||||
nullptr},
|
||||
{"projected_z",
|
||||
(getter)Interface0D_projected_z_get,
|
||||
(setter) nullptr,
|
||||
Interface0D_projected_z_doc,
|
||||
nullptr},
|
||||
{"point_2d",
|
||||
(getter)Interface0D_point_2d_get,
|
||||
(setter) nullptr,
|
||||
Interface0D_point_2d_doc,
|
||||
nullptr},
|
||||
{"id", (getter)Interface0D_id_get, (setter) nullptr, Interface0D_id_doc, nullptr},
|
||||
{"nature", (getter)Interface0D_nature_get, (setter) nullptr, Interface0D_nature_doc, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_Interface0D type definition ------------------------------*/
|
||||
|
||||
PyTypeObject Interface0D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Interface0D",
|
||||
/*tp_basicsize*/ sizeof(BPy_Interface0D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)Interface0D_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)Interface0D_repr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ Interface0D_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_Interface0D_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_Interface0D_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)Interface0D_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,35 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../view_map/Interface0D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject Interface0D_Type;
|
||||
|
||||
#define BPy_Interface0D_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&Interface0D_Type))
|
||||
|
||||
/*---------------------------Python BPy_Interface0D structure definition----------*/
|
||||
struct BPy_Interface0D {
|
||||
PyObject_HEAD
|
||||
Freestyle::Interface0D *if0D;
|
||||
bool borrowed; /* true if *if0D is a borrowed object */
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_Interface0D visible prototypes-----------*/
|
||||
|
||||
int Interface0D_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,387 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_Interface1D.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
#include "Interface1D/BPy_FEdge.h"
|
||||
#include "Interface1D/BPy_FrsCurve.h"
|
||||
#include "Interface1D/BPy_Stroke.h"
|
||||
#include "Interface1D/BPy_ViewEdge.h"
|
||||
#include "Interface1D/Curve/BPy_Chain.h"
|
||||
#include "Interface1D/FEdge/BPy_FEdgeSharp.h"
|
||||
#include "Interface1D/FEdge/BPy_FEdgeSmooth.h"
|
||||
|
||||
#include "BPy_MediumType.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int Interface1D_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&Interface1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Interface1D", (PyObject *)&Interface1D_Type);
|
||||
|
||||
if (PyType_Ready(&FrsCurve_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Curve", (PyObject *)&FrsCurve_Type);
|
||||
|
||||
if (PyType_Ready(&Chain_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Chain", (PyObject *)&Chain_Type);
|
||||
|
||||
if (PyType_Ready(&FEdge_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "FEdge", (PyObject *)&FEdge_Type);
|
||||
|
||||
if (PyType_Ready(&FEdgeSharp_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "FEdgeSharp", (PyObject *)&FEdgeSharp_Type);
|
||||
|
||||
if (PyType_Ready(&FEdgeSmooth_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "FEdgeSmooth", (PyObject *)&FEdgeSmooth_Type);
|
||||
|
||||
if (PyType_Ready(&Stroke_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Stroke", (PyObject *)&Stroke_Type);
|
||||
|
||||
#define ADD_TYPE_CONST(id) \
|
||||
PyLong_subtype_add_to_dict(Stroke_Type.tp_dict, &MediumType_Type, STRINGIFY(id), Stroke::id)
|
||||
ADD_TYPE_CONST(DRY_MEDIUM);
|
||||
ADD_TYPE_CONST(HUMID_MEDIUM);
|
||||
ADD_TYPE_CONST(OPAQUE_MEDIUM);
|
||||
#undef ADD_TYPE_CONST
|
||||
|
||||
if (PyType_Ready(&ViewEdge_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ViewEdge", (PyObject *)&ViewEdge_Type);
|
||||
|
||||
FEdgeSharp_mathutils_register_callback();
|
||||
FEdgeSmooth_mathutils_register_callback();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------Interface1D methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface1D_doc,
|
||||
"Base class for any 1D element.\n"
|
||||
"\n"
|
||||
".. method:: __init__()\n"
|
||||
"\n"
|
||||
" Default constructor.\n");
|
||||
static int Interface1D_init(BPy_Interface1D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->if1D = new Interface1D();
|
||||
self->borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Interface1D_dealloc(BPy_Interface1D *self)
|
||||
{
|
||||
if (self->if1D && !self->borrowed) {
|
||||
delete self->if1D;
|
||||
}
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *Interface1D_repr(BPy_Interface1D *self)
|
||||
{
|
||||
return PyUnicode_FromFormat(
|
||||
"type: %s - address: %p", self->if1D->getExactTypeName().c_str(), self->if1D);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface1D_vertices_begin_doc,
|
||||
".. method:: vertices_begin()\n"
|
||||
"\n"
|
||||
" Returns an iterator over the Interface1D vertices, pointing to the\n"
|
||||
" first vertex.\n"
|
||||
"\n"
|
||||
" :return: An Interface0DIterator pointing to the first vertex.\n"
|
||||
" :rtype: :class:`Interface0DIterator`\n");
|
||||
static PyObject *Interface1D_vertices_begin(BPy_Interface1D *self)
|
||||
{
|
||||
Interface0DIterator if0D_it(self->if1D->verticesBegin());
|
||||
return BPy_Interface0DIterator_from_Interface0DIterator(if0D_it, false);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface1D_vertices_end_doc,
|
||||
".. method:: vertices_end()\n"
|
||||
"\n"
|
||||
" Returns an iterator over the Interface1D vertices, pointing after\n"
|
||||
" the last vertex.\n"
|
||||
"\n"
|
||||
" :return: An Interface0DIterator pointing after the last vertex.\n"
|
||||
" :rtype: :class:`Interface0DIterator`\n");
|
||||
static PyObject *Interface1D_vertices_end(BPy_Interface1D *self)
|
||||
{
|
||||
Interface0DIterator if0D_it(self->if1D->verticesEnd());
|
||||
return BPy_Interface0DIterator_from_Interface0DIterator(if0D_it, true);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface1D_points_begin_doc,
|
||||
".. method:: points_begin(t=0.0)\n"
|
||||
"\n"
|
||||
" Returns an iterator over the Interface1D points, pointing to the\n"
|
||||
" first point. The difference with vertices_begin() is that here we can\n"
|
||||
" iterate over points of the 1D element at a any given sampling.\n"
|
||||
" Indeed, for each iteration, a virtual point is created.\n"
|
||||
"\n"
|
||||
" :param t: A sampling with which we want to iterate over points of\n"
|
||||
" this 1D element.\n"
|
||||
" :type t: float\n"
|
||||
" :return: An Interface0DIterator pointing to the first point.\n"
|
||||
" :rtype: :class:`Interface0DIterator`\n");
|
||||
static PyObject *Interface1D_points_begin(BPy_Interface1D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"t", nullptr};
|
||||
float f = 0.0f;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|f", (char **)kwlist, &f)) {
|
||||
return nullptr;
|
||||
}
|
||||
Interface0DIterator if0D_it(self->if1D->pointsBegin(f));
|
||||
return BPy_Interface0DIterator_from_Interface0DIterator(if0D_it, false);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface1D_points_end_doc,
|
||||
".. method:: points_end(t=0.0)\n"
|
||||
"\n"
|
||||
" Returns an iterator over the Interface1D points, pointing after the\n"
|
||||
" last point. The difference with vertices_end() is that here we can\n"
|
||||
" iterate over points of the 1D element at a given sampling. Indeed,\n"
|
||||
" for each iteration, a virtual point is created.\n"
|
||||
"\n"
|
||||
" :param t: A sampling with which we want to iterate over points of\n"
|
||||
" this 1D element.\n"
|
||||
" :type t: float\n"
|
||||
" :return: An Interface0DIterator pointing after the last point.\n"
|
||||
" :rtype: :class:`Interface0DIterator`\n");
|
||||
static PyObject *Interface1D_points_end(BPy_Interface1D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"t", nullptr};
|
||||
float f = 0.0f;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|f", (char **)kwlist, &f)) {
|
||||
return nullptr;
|
||||
}
|
||||
Interface0DIterator if0D_it(self->if1D->pointsEnd(f));
|
||||
return BPy_Interface0DIterator_from_Interface0DIterator(if0D_it, true);
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_Interface1D_methods[] = {
|
||||
{"vertices_begin",
|
||||
(PyCFunction)Interface1D_vertices_begin,
|
||||
METH_NOARGS,
|
||||
Interface1D_vertices_begin_doc},
|
||||
{"vertices_end",
|
||||
(PyCFunction)Interface1D_vertices_end,
|
||||
METH_NOARGS,
|
||||
Interface1D_vertices_end_doc},
|
||||
{"points_begin",
|
||||
(PyCFunction)Interface1D_points_begin,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
Interface1D_points_begin_doc},
|
||||
{"points_end",
|
||||
(PyCFunction)Interface1D_points_end,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
Interface1D_points_end_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------Interface1D get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface1D_name_doc,
|
||||
"The string of the name of the 1D element.\n"
|
||||
"\n"
|
||||
":type: str\n");
|
||||
static PyObject *Interface1D_name_get(BPy_Interface1D *self, void * /*closure*/)
|
||||
{
|
||||
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface1D_id_doc,
|
||||
"The Id of this Interface1D.\n"
|
||||
"\n"
|
||||
":type: :class:`Id`\n");
|
||||
static PyObject *Interface1D_id_get(BPy_Interface1D *self, void * /*closure*/)
|
||||
{
|
||||
Id id(self->if1D->getId());
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
return BPy_Id_from_Id(id); // return a copy
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface1D_nature_doc,
|
||||
"The nature of this Interface1D.\n"
|
||||
"\n"
|
||||
":type: :class:`Nature`\n");
|
||||
static PyObject *Interface1D_nature_get(BPy_Interface1D *self, void * /*closure*/)
|
||||
{
|
||||
Nature::VertexNature nature = self->if1D->getNature();
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
return BPy_Nature_from_Nature(nature);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface1D_length_2d_doc,
|
||||
"The 2D length of this Interface1D.\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *Interface1D_length_2d_get(BPy_Interface1D *self, void * /*closure*/)
|
||||
{
|
||||
real length = self->if1D->getLength2D();
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
return PyFloat_FromDouble(double(length));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface1D_time_stamp_doc,
|
||||
"The time stamp of the 1D element, mainly used for selection.\n"
|
||||
"\n"
|
||||
":type: int\n");
|
||||
static PyObject *Interface1D_time_stamp_get(BPy_Interface1D *self, void * /*closure*/)
|
||||
{
|
||||
return PyLong_FromLong(self->if1D->getTimeStamp());
|
||||
}
|
||||
|
||||
static int Interface1D_time_stamp_set(BPy_Interface1D *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
int timestamp;
|
||||
|
||||
if ((timestamp = PyLong_AsLong(value)) == -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a number");
|
||||
return -1;
|
||||
}
|
||||
self->if1D->setTimeStamp(timestamp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_Interface1D_getseters[] = {
|
||||
{"name", (getter)Interface1D_name_get, (setter) nullptr, Interface1D_name_doc, nullptr},
|
||||
{"id", (getter)Interface1D_id_get, (setter) nullptr, Interface1D_id_doc, nullptr},
|
||||
{"nature", (getter)Interface1D_nature_get, (setter) nullptr, Interface1D_nature_doc, nullptr},
|
||||
{"length_2d",
|
||||
(getter)Interface1D_length_2d_get,
|
||||
(setter) nullptr,
|
||||
Interface1D_length_2d_doc,
|
||||
nullptr},
|
||||
{"time_stamp",
|
||||
(getter)Interface1D_time_stamp_get,
|
||||
(setter)Interface1D_time_stamp_set,
|
||||
Interface1D_time_stamp_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_Interface1D type definition ------------------------------*/
|
||||
|
||||
PyTypeObject Interface1D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Interface1D",
|
||||
/*tp_basicsize*/ sizeof(BPy_Interface1D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)Interface1D_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)Interface1D_repr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ Interface1D_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_Interface1D_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_Interface1D_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)Interface1D_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,35 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../view_map/Interface1D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject Interface1D_Type;
|
||||
|
||||
#define BPy_Interface1D_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&Interface1D_Type))
|
||||
|
||||
/*---------------------------Python BPy_Interface1D structure definition----------*/
|
||||
struct BPy_Interface1D {
|
||||
PyObject_HEAD
|
||||
Freestyle::Interface1D *if1D;
|
||||
bool borrowed; /* true if *if1D is a borrowed object */
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_Interface1D visible prototypes-----------*/
|
||||
|
||||
int Interface1D_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,268 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_Iterator.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
#include "Iterator/BPy_AdjacencyIterator.h"
|
||||
#include "Iterator/BPy_ChainPredicateIterator.h"
|
||||
#include "Iterator/BPy_ChainSilhouetteIterator.h"
|
||||
#include "Iterator/BPy_ChainingIterator.h"
|
||||
#include "Iterator/BPy_CurvePointIterator.h"
|
||||
#include "Iterator/BPy_Interface0DIterator.h"
|
||||
#include "Iterator/BPy_SVertexIterator.h"
|
||||
#include "Iterator/BPy_StrokeVertexIterator.h"
|
||||
#include "Iterator/BPy_ViewEdgeIterator.h"
|
||||
#include "Iterator/BPy_orientedViewEdgeIterator.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int Iterator_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&Iterator_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Iterator", (PyObject *)&Iterator_Type);
|
||||
|
||||
if (PyType_Ready(&AdjacencyIterator_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "AdjacencyIterator", (PyObject *)&AdjacencyIterator_Type);
|
||||
|
||||
if (PyType_Ready(&Interface0DIterator_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Interface0DIterator", (PyObject *)&Interface0DIterator_Type);
|
||||
|
||||
if (PyType_Ready(&CurvePointIterator_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "CurvePointIterator", (PyObject *)&CurvePointIterator_Type);
|
||||
|
||||
if (PyType_Ready(&StrokeVertexIterator_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "StrokeVertexIterator", (PyObject *)&StrokeVertexIterator_Type);
|
||||
|
||||
if (PyType_Ready(&SVertexIterator_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "SVertexIterator", (PyObject *)&SVertexIterator_Type);
|
||||
|
||||
if (PyType_Ready(&orientedViewEdgeIterator_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(
|
||||
module, "orientedViewEdgeIterator", (PyObject *)&orientedViewEdgeIterator_Type);
|
||||
|
||||
if (PyType_Ready(&ViewEdgeIterator_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ViewEdgeIterator", (PyObject *)&ViewEdgeIterator_Type);
|
||||
|
||||
if (PyType_Ready(&ChainingIterator_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ChainingIterator", (PyObject *)&ChainingIterator_Type);
|
||||
|
||||
if (PyType_Ready(&ChainPredicateIterator_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(
|
||||
module, "ChainPredicateIterator", (PyObject *)&ChainPredicateIterator_Type);
|
||||
|
||||
if (PyType_Ready(&ChainSilhouetteIterator_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(
|
||||
module, "ChainSilhouetteIterator", (PyObject *)&ChainSilhouetteIterator_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Iterator_doc,
|
||||
"Base class to define iterators.\n"
|
||||
"\n"
|
||||
".. method:: __init__()\n"
|
||||
"\n"
|
||||
" Default constructor.\n");
|
||||
static int Iterator_init(BPy_Iterator *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->it = new Iterator();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Iterator_dealloc(BPy_Iterator *self)
|
||||
{
|
||||
delete self->it;
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *Iterator_repr(BPy_Iterator *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("type: %s - address: %p", Py_TYPE(self)->tp_name, self->it);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Iterator_increment_doc,
|
||||
".. method:: increment()\n"
|
||||
"\n"
|
||||
" Makes the iterator point the next element.\n");
|
||||
static PyObject *Iterator_increment(BPy_Iterator *self)
|
||||
{
|
||||
if (self->it->isEnd()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "cannot increment any more");
|
||||
return nullptr;
|
||||
}
|
||||
self->it->increment();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Iterator_decrement_doc,
|
||||
".. method:: decrement()\n"
|
||||
"\n"
|
||||
" Makes the iterator point the previous element.\n");
|
||||
static PyObject *Iterator_decrement(BPy_Iterator *self)
|
||||
{
|
||||
if (self->it->isBegin()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "cannot decrement any more");
|
||||
return nullptr;
|
||||
}
|
||||
self->it->decrement();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_Iterator_methods[] = {
|
||||
{"increment", (PyCFunction)Iterator_increment, METH_NOARGS, Iterator_increment_doc},
|
||||
{"decrement", (PyCFunction)Iterator_decrement, METH_NOARGS, Iterator_decrement_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------Iterator get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Iterator_name_doc,
|
||||
"The string of the name of this iterator.\n"
|
||||
"\n"
|
||||
":type: str\n");
|
||||
static PyObject *Iterator_name_get(BPy_Iterator *self, void * /*closure*/)
|
||||
{
|
||||
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Iterator_is_begin_doc,
|
||||
"True if the iterator points to the first element.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *Iterator_is_begin_get(BPy_Iterator *self, void * /*closure*/)
|
||||
{
|
||||
return PyBool_from_bool(self->it->isBegin());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Iterator_is_end_doc,
|
||||
"True if the iterator points to the last element.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *Iterator_is_end_get(BPy_Iterator *self, void * /*closure*/)
|
||||
{
|
||||
return PyBool_from_bool(self->it->isEnd());
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_Iterator_getseters[] = {
|
||||
{"name", (getter)Iterator_name_get, (setter) nullptr, Iterator_name_doc, nullptr},
|
||||
{"is_begin", (getter)Iterator_is_begin_get, (setter) nullptr, Iterator_is_begin_doc, nullptr},
|
||||
{"is_end", (getter)Iterator_is_end_get, (setter) nullptr, Iterator_is_end_doc, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_Iterator type definition ------------------------------*/
|
||||
|
||||
PyTypeObject Iterator_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Iterator",
|
||||
/*tp_basicsize*/ sizeof(BPy_Iterator),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)Iterator_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)Iterator_repr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ Iterator_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_Iterator_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_Iterator_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)Iterator_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,33 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../system/Iterator.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject Iterator_Type;
|
||||
|
||||
#define BPy_Iterator_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Iterator_Type))
|
||||
|
||||
/*---------------------------Python BPy_Iterator structure definition----------*/
|
||||
struct BPy_Iterator {
|
||||
PyObject_HEAD
|
||||
Freestyle::Iterator *it;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_Iterator visible prototypes-----------*/
|
||||
|
||||
int Iterator_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,89 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_MediumType.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*-----------------------BPy_MediumType type definition ------------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
MediumType_doc,
|
||||
"Class hierarchy: int > :class:`MediumType`\n"
|
||||
"\n"
|
||||
"The different blending modes available to simulate the interaction\n"
|
||||
"media-medium:\n"
|
||||
"\n"
|
||||
"* Stroke.DRY_MEDIUM: To simulate a dry medium such as Pencil or Charcoal.\n"
|
||||
"* Stroke.HUMID_MEDIUM: To simulate ink painting (color subtraction blending).\n"
|
||||
"* Stroke.OPAQUE_MEDIUM: To simulate an opaque medium (oil, spray...).\n");
|
||||
PyTypeObject MediumType_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "MediumType",
|
||||
/*tp_basicsize*/ sizeof(PyLongObject),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT,
|
||||
/*tp_doc*/ MediumType_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ &PyLong_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ nullptr,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
/*-----------------------BPy_IntegrationType instance definitions -------------------------*/
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
|
||||
int MediumType_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&MediumType_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "MediumType", (PyObject *)&MediumType_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,32 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../stroke/Stroke.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject MediumType_Type;
|
||||
|
||||
#define BPy_MediumType_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&MediumType_Type))
|
||||
|
||||
/*---------------------------Python BPy_MediumType structure definition----------*/
|
||||
struct BPy_MediumType {
|
||||
PyLongObject i;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_MediumType visible prototypes-----------*/
|
||||
|
||||
int MediumType_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,265 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_Nature.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static PyObject *BPy_Nature_and(PyObject *a, PyObject *b);
|
||||
static PyObject *BPy_Nature_xor(PyObject *a, PyObject *b);
|
||||
static PyObject *BPy_Nature_or(PyObject *a, PyObject *b);
|
||||
|
||||
/*-----------------------BPy_Nature number method definitions --------------------*/
|
||||
|
||||
static PyNumberMethods nature_as_number = {
|
||||
/*nb_add*/ nullptr,
|
||||
/*nb_subtract*/ nullptr,
|
||||
/*nb_multiply*/ nullptr,
|
||||
/*nb_remainder*/ nullptr,
|
||||
/*nb_divmod*/ nullptr,
|
||||
/*nb_power*/ nullptr,
|
||||
/*nb_negative*/ nullptr,
|
||||
/*nb_positive*/ nullptr,
|
||||
/*nb_absolute*/ nullptr,
|
||||
/*nb_bool*/ nullptr,
|
||||
/*nb_invert*/ nullptr,
|
||||
/*nb_lshift*/ nullptr,
|
||||
/*nb_rshift*/ nullptr,
|
||||
/*nb_and*/ (binaryfunc)BPy_Nature_and,
|
||||
/*nb_xor*/ (binaryfunc)BPy_Nature_xor,
|
||||
/*nb_or*/ (binaryfunc)BPy_Nature_or,
|
||||
/*nb_int*/ nullptr,
|
||||
/*nb_reserved*/ nullptr,
|
||||
/*nb_float*/ nullptr,
|
||||
/*nb_inplace_add*/ nullptr,
|
||||
/*nb_inplace_subtract*/ nullptr,
|
||||
/*nb_inplace_multiply*/ nullptr,
|
||||
/*nb_inplace_remainder*/ nullptr,
|
||||
/*nb_inplace_power*/ nullptr,
|
||||
/*nb_inplace_lshift*/ nullptr,
|
||||
/*nb_inplace_rshift*/ nullptr,
|
||||
/*nb_inplace_and*/ nullptr,
|
||||
/*nb_inplace_xor*/ nullptr,
|
||||
/*nb_inplace_or*/ nullptr,
|
||||
/*nb_floor_divide*/ nullptr,
|
||||
/*nb_true_divide*/ nullptr,
|
||||
/*nb_inplace_floor_divide*/ nullptr,
|
||||
/*nb_inplace_true_divide*/ nullptr,
|
||||
/*nb_index*/ nullptr,
|
||||
/*nb_matrix_multiply*/ nullptr,
|
||||
/*nb_inplace_matrix_multiply*/ nullptr,
|
||||
};
|
||||
|
||||
/*-----------------------BPy_Nature type definition ------------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Nature_doc,
|
||||
"Class hierarchy: int > :class:`Nature`\n"
|
||||
"\n"
|
||||
"Different possible natures of 0D and 1D elements of the ViewMap.\n"
|
||||
"\n"
|
||||
"Vertex natures:\n"
|
||||
"\n"
|
||||
".. attribute:: POINT\n"
|
||||
"\n"
|
||||
" True for any 0D element.\n"
|
||||
"\n"
|
||||
".. attribute:: S_VERTEX\n"
|
||||
"\n"
|
||||
" True for SVertex.\n"
|
||||
"\n"
|
||||
".. attribute:: VIEW_VERTEX\n"
|
||||
"\n"
|
||||
" True for ViewVertex.\n"
|
||||
"\n"
|
||||
".. attribute:: NON_T_VERTEX\n"
|
||||
"\n"
|
||||
" True for NonTVertex.\n"
|
||||
"\n"
|
||||
".. attribute:: T_VERTEX\n"
|
||||
"\n"
|
||||
" True for TVertex.\n"
|
||||
"\n"
|
||||
".. attribute:: CUSP\n"
|
||||
"\n"
|
||||
" True for CUSP.\n"
|
||||
"\n"
|
||||
"Edge natures:\n"
|
||||
"\n"
|
||||
".. attribute:: NO_FEATURE\n"
|
||||
"\n"
|
||||
" True for non feature edges (always false for 1D elements of the ViewMap).\n"
|
||||
"\n"
|
||||
".. attribute:: SILHOUETTE\n"
|
||||
"\n"
|
||||
" True for silhouettes.\n"
|
||||
"\n"
|
||||
".. attribute:: BORDER\n"
|
||||
"\n"
|
||||
" True for borders.\n"
|
||||
"\n"
|
||||
".. attribute:: CREASE\n"
|
||||
"\n"
|
||||
" True for creases.\n"
|
||||
"\n"
|
||||
".. attribute:: RIDGE\n"
|
||||
"\n"
|
||||
" True for ridges.\n"
|
||||
"\n"
|
||||
".. attribute:: VALLEY\n"
|
||||
"\n"
|
||||
" True for valleys.\n"
|
||||
"\n"
|
||||
".. attribute:: SUGGESTIVE_CONTOUR\n"
|
||||
"\n"
|
||||
" True for suggestive contours.\n"
|
||||
"\n"
|
||||
".. attribute:: MATERIAL_BOUNDARY\n"
|
||||
"\n"
|
||||
" True for edges at material boundaries.\n"
|
||||
"\n"
|
||||
".. attribute:: EDGE_MARK\n"
|
||||
"\n"
|
||||
" True for edges having user-defined edge marks.\n");
|
||||
PyTypeObject Nature_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Nature",
|
||||
/*tp_basicsize*/ sizeof(PyLongObject),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ &nature_as_number,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT,
|
||||
/*tp_doc*/ Nature_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ &PyLong_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ nullptr,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
/*-----------------------BPy_Nature instance definitions ----------------------------------*/
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int Nature_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&Nature_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Nature", (PyObject *)&Nature_Type);
|
||||
|
||||
#define ADD_TYPE_CONST(id) \
|
||||
PyLong_subtype_add_to_dict(Nature_Type.tp_dict, &Nature_Type, STRINGIFY(id), Nature::id)
|
||||
|
||||
// VertexNature
|
||||
ADD_TYPE_CONST(POINT);
|
||||
ADD_TYPE_CONST(S_VERTEX);
|
||||
ADD_TYPE_CONST(VIEW_VERTEX);
|
||||
ADD_TYPE_CONST(NON_T_VERTEX);
|
||||
ADD_TYPE_CONST(T_VERTEX);
|
||||
ADD_TYPE_CONST(CUSP);
|
||||
|
||||
// EdgeNature
|
||||
ADD_TYPE_CONST(NO_FEATURE);
|
||||
ADD_TYPE_CONST(SILHOUETTE);
|
||||
ADD_TYPE_CONST(BORDER);
|
||||
ADD_TYPE_CONST(CREASE);
|
||||
ADD_TYPE_CONST(RIDGE);
|
||||
ADD_TYPE_CONST(VALLEY);
|
||||
ADD_TYPE_CONST(SUGGESTIVE_CONTOUR);
|
||||
ADD_TYPE_CONST(MATERIAL_BOUNDARY);
|
||||
ADD_TYPE_CONST(EDGE_MARK);
|
||||
|
||||
#undef ADD_TYPE_CONST
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *BPy_Nature_bitwise(PyObject *a, int op, PyObject *b)
|
||||
{
|
||||
long op1, op2, v;
|
||||
|
||||
if (!BPy_Nature_Check(a) || !BPy_Nature_Check(b)) {
|
||||
PyErr_SetString(PyExc_TypeError, "operands must be a Nature object");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ((op1 = PyLong_AsLong(a)) == -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_ValueError, "operand 1: unexpected Nature value");
|
||||
return nullptr;
|
||||
}
|
||||
if ((op2 = PyLong_AsLong(b)) == -1 && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_ValueError, "operand 2: unexpected Nature value");
|
||||
return nullptr;
|
||||
}
|
||||
switch (op) {
|
||||
case '&':
|
||||
v = op1 & op2;
|
||||
break;
|
||||
case '^':
|
||||
v = op1 ^ op2;
|
||||
break;
|
||||
case '|':
|
||||
v = op1 | op2;
|
||||
break;
|
||||
default:
|
||||
PyErr_BadArgument();
|
||||
return nullptr;
|
||||
}
|
||||
return PyLong_subtype_new(&Nature_Type, v);
|
||||
}
|
||||
|
||||
static PyObject *BPy_Nature_and(PyObject *a, PyObject *b)
|
||||
{
|
||||
return BPy_Nature_bitwise(a, '&', b);
|
||||
}
|
||||
|
||||
static PyObject *BPy_Nature_xor(PyObject *a, PyObject *b)
|
||||
{
|
||||
return BPy_Nature_bitwise(a, '^', b);
|
||||
}
|
||||
|
||||
static PyObject *BPy_Nature_or(PyObject *a, PyObject *b)
|
||||
{
|
||||
return BPy_Nature_bitwise(a, '|', b);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,32 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../winged_edge/Nature.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject Nature_Type;
|
||||
|
||||
#define BPy_Nature_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Nature_Type))
|
||||
|
||||
/*---------------------------Python BPy_Nature structure definition----------*/
|
||||
struct BPy_Nature {
|
||||
PyLongObject i;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_Nature visible prototypes-----------*/
|
||||
|
||||
int Nature_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,854 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_Operators.h"
|
||||
|
||||
#include "BPy_BinaryPredicate1D.h"
|
||||
#include "BPy_Convert.h"
|
||||
#include "BPy_StrokeShader.h"
|
||||
#include "BPy_UnaryPredicate0D.h"
|
||||
#include "BPy_UnaryPredicate1D.h"
|
||||
#include "Iterator/BPy_ChainingIterator.h"
|
||||
#include "Iterator/BPy_ViewEdgeIterator.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DDouble.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DVoid.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int Operators_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&Operators_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "Operators", (PyObject *)&Operators_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_doc,
|
||||
"Class defining the operators used in a style module. There are five\n"
|
||||
"types of operators: Selection, chaining, splitting, sorting and\n"
|
||||
"creation. All these operators are user controlled through functors,\n"
|
||||
"predicates and shaders that are taken as arguments.\n");
|
||||
static void Operators_dealloc(BPy_Operators *self)
|
||||
{
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_select_doc,
|
||||
".. staticmethod:: select(pred)\n"
|
||||
"\n"
|
||||
" Selects the ViewEdges of the ViewMap verifying a specified\n"
|
||||
" condition.\n"
|
||||
"\n"
|
||||
" :param pred: The predicate expressing this condition.\n"
|
||||
" :type pred: :class:`UnaryPredicate1D`\n");
|
||||
static PyObject *Operators_select(BPy_Operators * /*self*/, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"pred", nullptr};
|
||||
PyObject *obj = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!", (char **)kwlist, &UnaryPredicate1D_Type, &obj))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (!((BPy_UnaryPredicate1D *)obj)->up1D) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Operators.select(): 1st argument: invalid UnaryPredicate1D object");
|
||||
return nullptr;
|
||||
}
|
||||
if (Operators::select(*(((BPy_UnaryPredicate1D *)obj)->up1D)) < 0) {
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Operators.select() failed");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_chain_doc,
|
||||
".. staticmethod:: chain(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``chain(it, pred, modifier)``\n"
|
||||
" - ``chain(it, pred)``\n"
|
||||
"\n"
|
||||
" Builds a set of chains from the current set of ViewEdges. Each\n"
|
||||
" ViewEdge of the current list starts a new chain. The chaining\n"
|
||||
" operator then iterates over the ViewEdges of the ViewMap using the\n"
|
||||
" user specified iterator. This operator only iterates using the\n"
|
||||
" increment operator and is therefore unidirectional.\n"
|
||||
"\n"
|
||||
" :param it: The iterator on the ViewEdges of the ViewMap. It contains\n"
|
||||
" the chaining rule.\n"
|
||||
" :type it: :class:`ViewEdgeIterator`\n"
|
||||
" :param pred: The predicate on the ViewEdge that expresses the\n"
|
||||
" stopping condition.\n"
|
||||
" :type pred: :class:`UnaryPredicate1D`\n"
|
||||
" :param modifier: A function that takes a ViewEdge as argument and\n"
|
||||
" that is used to modify the processed ViewEdge state (the\n"
|
||||
" timestamp incrementation is a typical illustration of such a modifier).\n"
|
||||
" If this argument is not given, the time stamp is automatically managed.\n"
|
||||
" :type modifier: :class:`UnaryFunction1DVoid`\n");
|
||||
static PyObject *Operators_chain(BPy_Operators * /*self*/, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"it", "pred", "modifier", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr, *obj3 = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!O!|O!",
|
||||
(char **)kwlist,
|
||||
&ChainingIterator_Type,
|
||||
&obj1,
|
||||
&UnaryPredicate1D_Type,
|
||||
&obj2,
|
||||
&UnaryFunction1DVoid_Type,
|
||||
&obj3))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (!((BPy_ChainingIterator *)obj1)->c_it) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Operators.chain(): 1st argument: invalid ChainingIterator object");
|
||||
return nullptr;
|
||||
}
|
||||
if (!((BPy_UnaryPredicate1D *)obj2)->up1D) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Operators.chain(): 2nd argument: invalid UnaryPredicate1D object");
|
||||
return nullptr;
|
||||
}
|
||||
if (!obj3) {
|
||||
if (Operators::chain(*(((BPy_ChainingIterator *)obj1)->c_it),
|
||||
*(((BPy_UnaryPredicate1D *)obj2)->up1D)) < 0)
|
||||
{
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Operators.chain() failed");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!((BPy_UnaryFunction1DVoid *)obj3)->uf1D_void) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Operators.chain(): 3rd argument: invalid UnaryFunction1DVoid object");
|
||||
return nullptr;
|
||||
}
|
||||
if (Operators::chain(*(((BPy_ChainingIterator *)obj1)->c_it),
|
||||
*(((BPy_UnaryPredicate1D *)obj2)->up1D),
|
||||
*(((BPy_UnaryFunction1DVoid *)obj3)->uf1D_void)) < 0)
|
||||
{
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Operators.chain() failed");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_bidirectional_chain_doc,
|
||||
".. staticmethod:: bidirectional_chain(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``bidirectional_chain(it, pred)``\n"
|
||||
" - ``bidirectional_chain(it)``\n"
|
||||
"\n"
|
||||
" Builds a set of chains from the current set of ViewEdges. Each\n"
|
||||
" ViewEdge of the current list potentially starts a new chain. The\n"
|
||||
" chaining operator then iterates over the ViewEdges of the ViewMap\n"
|
||||
" using the user specified iterator. This operator iterates both using\n"
|
||||
" the increment and decrement operators and is therefore bidirectional.\n"
|
||||
" This operator works with a ChainingIterator which contains the\n"
|
||||
" chaining rules. It is this last one which can be told to chain only\n"
|
||||
" edges that belong to the selection or not to process twice a ViewEdge\n"
|
||||
" during the chaining. Each time a ViewEdge is added to a chain, its\n"
|
||||
" chaining time stamp is incremented. This allows you to keep track of\n"
|
||||
" the number of chains to which a ViewEdge belongs to.\n"
|
||||
"\n"
|
||||
" :param it: The ChainingIterator on the ViewEdges of the ViewMap. It\n"
|
||||
" contains the chaining rule.\n"
|
||||
" :type it: :class:`ChainingIterator`\n"
|
||||
" :param pred: The predicate on the ViewEdge that expresses the stopping condition.\n"
|
||||
" This parameter is optional, you make not want to pass a stopping criterion\n"
|
||||
" when the stopping criterion is already contained in the iterator definition.\n"
|
||||
" :type pred: :class:`UnaryPredicate1D`\n");
|
||||
static PyObject *Operators_bidirectional_chain(BPy_Operators * /*self*/,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"it", "pred", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!|O!",
|
||||
(char **)kwlist,
|
||||
&ChainingIterator_Type,
|
||||
&obj1,
|
||||
&UnaryPredicate1D_Type,
|
||||
&obj2))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (!((BPy_ChainingIterator *)obj1)->c_it) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
"Operators.bidirectional_chain(): 1st argument: invalid ChainingIterator object");
|
||||
return nullptr;
|
||||
}
|
||||
if (!obj2) {
|
||||
if (Operators::bidirectionalChain(*(((BPy_ChainingIterator *)obj1)->c_it)) < 0) {
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Operators.bidirectional_chain() failed");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!((BPy_UnaryPredicate1D *)obj2)->up1D) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
"Operators.bidirectional_chain(): 2nd argument: invalid UnaryPredicate1D object");
|
||||
return nullptr;
|
||||
}
|
||||
if (Operators::bidirectionalChain(*(((BPy_ChainingIterator *)obj1)->c_it),
|
||||
*(((BPy_UnaryPredicate1D *)obj2)->up1D)) < 0)
|
||||
{
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Operators.bidirectional_chain() failed");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_sequential_split_doc,
|
||||
".. staticmethod:: sequential_split(*args, **kwargs)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``sequential_split(starting_pred, stopping_pred, sampling=0.0)``\n"
|
||||
" - ``sequential_split(pred, sampling=0.0)``\n"
|
||||
"\n"
|
||||
" Splits each chain of the current set of chains in a sequential way.\n"
|
||||
" The points of each chain are processed (with a specified sampling)\n"
|
||||
" sequentially. The first point of the initial chain is the\n"
|
||||
" first point of one of the resulting chains. The splitting ends when\n"
|
||||
" no more chain can start.\n"
|
||||
"\n"
|
||||
" .. tip::\n"
|
||||
"\n"
|
||||
" By specifying a starting and stopping predicate allows\n"
|
||||
" the chains to overlap rather than chains partitioning.\n"
|
||||
"\n"
|
||||
" :param starting_pred: The predicate on a point that expresses the\n"
|
||||
" starting condition. Each time this condition is verified, a new chain begins\n"
|
||||
" :type starting_pred: :class:`UnaryPredicate0D`\n"
|
||||
" :param stopping_pred: The predicate on a point that expresses the\n"
|
||||
" stopping condition. The chain ends as soon as this predicate is verified.\n"
|
||||
" :type stopping_pred: :class:`UnaryPredicate0D`\n"
|
||||
" :param pred: The predicate on a point that expresses the splitting condition.\n"
|
||||
" Each time the condition is verified, the chain is split into two chains.\n"
|
||||
" The resulting set of chains is a partition of the initial chain\n"
|
||||
" :type pred: :class:`UnaryPredicate0D`\n"
|
||||
" :param sampling: The resolution used to sample the chain for the\n"
|
||||
" predicates evaluation. (The chain is not actually resampled;\n"
|
||||
" a virtual point only progresses along the curve using this\n"
|
||||
" resolution.)\n"
|
||||
" :type sampling: float\n");
|
||||
static PyObject *Operators_sequential_split(BPy_Operators * /*self*/,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"starting_pred", "stopping_pred", "sampling", nullptr};
|
||||
static const char *kwlist_2[] = {"pred", "sampling", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr;
|
||||
float f = 0.0f;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!O!|f",
|
||||
(char **)kwlist_1,
|
||||
&UnaryPredicate0D_Type,
|
||||
&obj1,
|
||||
&UnaryPredicate0D_Type,
|
||||
&obj2,
|
||||
&f))
|
||||
{
|
||||
if (!((BPy_UnaryPredicate0D *)obj1)->up0D) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
"Operators.sequential_split(): 1st argument: invalid UnaryPredicate0D object");
|
||||
return nullptr;
|
||||
}
|
||||
if (!((BPy_UnaryPredicate0D *)obj2)->up0D) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
"Operators.sequential_split(): 2nd argument: invalid UnaryPredicate0D object");
|
||||
return nullptr;
|
||||
}
|
||||
if (Operators::sequentialSplit(*(((BPy_UnaryPredicate0D *)obj1)->up0D),
|
||||
*(((BPy_UnaryPredicate0D *)obj2)->up0D),
|
||||
f) < 0)
|
||||
{
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Operators.sequential_split() failed");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
(void)(f = 0.0f),
|
||||
PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!|f", (char **)kwlist_2, &UnaryPredicate0D_Type, &obj1, &f))
|
||||
{
|
||||
if (!((BPy_UnaryPredicate0D *)obj1)->up0D) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
"Operators.sequential_split(): 1st argument: invalid UnaryPredicate0D object");
|
||||
return nullptr;
|
||||
}
|
||||
if (Operators::sequentialSplit(*(((BPy_UnaryPredicate0D *)obj1)->up0D), f) < 0) {
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Operators.sequential_split() failed");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return nullptr;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_recursive_split_doc,
|
||||
".. staticmethod:: recursive_split(*args, **kwargs)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``recursive_split(func, pred_1d, sampling=0.0)``\n"
|
||||
" - ``recursive_split(func, pred_0d, pred_1d, sampling=0.0)``\n"
|
||||
"\n"
|
||||
" Splits the current set of chains in a recursive way. We process the\n"
|
||||
" points of each chain (with a specified sampling) to find the point\n"
|
||||
" minimizing a specified function. The chain is split in two at this\n"
|
||||
" point and the two new chains are processed in the same way. The\n"
|
||||
" recursivity level is controlled through a predicate 1D that expresses\n"
|
||||
" a stopping condition on the chain that is about to be processed.\n"
|
||||
"\n"
|
||||
" The user can also specify a 0D predicate to make a first selection on the points\n"
|
||||
" that can potentially be split. A point that doesn't verify the 0D\n"
|
||||
" predicate won't be candidate in realizing the min.\n"
|
||||
"\n"
|
||||
" :param func: The Unary Function evaluated at each point of the chain.\n"
|
||||
" The splitting point is the point minimizing this function.\n"
|
||||
" :type func: :class:`UnaryFunction0DDouble`\n"
|
||||
" :param pred_0d: The Unary Predicate 0D used to select the candidate\n"
|
||||
" points where the split can occur. For example, it is very likely\n"
|
||||
" that would rather have your chain splitting around its middle\n"
|
||||
" point than around one of its extremities. A 0D predicate working\n"
|
||||
" on the curvilinear abscissa allows to add this kind of constraints.\n"
|
||||
" :type pred_0d: :class:`UnaryPredicate0D`\n"
|
||||
" :param pred_1d: The Unary Predicate expressing the recursivity stopping\n"
|
||||
" condition. This predicate is evaluated for each curve before it\n"
|
||||
" actually gets split. If pred_1d(chain) is true, the curve won't be\n"
|
||||
" split anymore.\n"
|
||||
" :type pred_1d: :class:`UnaryPredicate1D`\n"
|
||||
" :param sampling: The resolution used to sample the chain for the\n"
|
||||
" predicates evaluation. (The chain is not actually resampled; a\n"
|
||||
" virtual point only progresses along the curve using this\n"
|
||||
" resolution.)\n"
|
||||
" :type sampling: float\n");
|
||||
static PyObject *Operators_recursive_split(BPy_Operators * /*self*/,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"func", "pred_1d", "sampling", nullptr};
|
||||
static const char *kwlist_2[] = {"func", "pred_0d", "pred_1d", "sampling", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr, *obj3 = nullptr;
|
||||
float f = 0.0f;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!O!|f",
|
||||
(char **)kwlist_1,
|
||||
&UnaryFunction0DDouble_Type,
|
||||
&obj1,
|
||||
&UnaryPredicate1D_Type,
|
||||
&obj2,
|
||||
&f))
|
||||
{
|
||||
if (!((BPy_UnaryFunction0DDouble *)obj1)->uf0D_double) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
"Operators.recursive_split(): 1st argument: invalid UnaryFunction0DDouble object");
|
||||
return nullptr;
|
||||
}
|
||||
if (!((BPy_UnaryPredicate1D *)obj2)->up1D) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
"Operators.recursive_split(): 2nd argument: invalid UnaryPredicate1D object");
|
||||
return nullptr;
|
||||
}
|
||||
if (Operators::recursiveSplit(*(((BPy_UnaryFunction0DDouble *)obj1)->uf0D_double),
|
||||
*(((BPy_UnaryPredicate1D *)obj2)->up1D),
|
||||
f) < 0)
|
||||
{
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Operators.recursive_split() failed");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
(void)(f = 0.0f),
|
||||
PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!O!O!|f",
|
||||
(char **)kwlist_2,
|
||||
&UnaryFunction0DDouble_Type,
|
||||
&obj1,
|
||||
&UnaryPredicate0D_Type,
|
||||
&obj2,
|
||||
&UnaryPredicate1D_Type,
|
||||
&obj3,
|
||||
&f))
|
||||
{
|
||||
if (!((BPy_UnaryFunction0DDouble *)obj1)->uf0D_double) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
"Operators.recursive_split(): 1st argument: invalid UnaryFunction0DDouble object");
|
||||
return nullptr;
|
||||
}
|
||||
if (!((BPy_UnaryPredicate0D *)obj2)->up0D) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
"Operators.recursive_split(): 2nd argument: invalid UnaryPredicate0D object");
|
||||
return nullptr;
|
||||
}
|
||||
if (!((BPy_UnaryPredicate1D *)obj3)->up1D) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
"Operators.recursive_split(): 3rd argument: invalid UnaryPredicate1D object");
|
||||
return nullptr;
|
||||
}
|
||||
if (Operators::recursiveSplit(*(((BPy_UnaryFunction0DDouble *)obj1)->uf0D_double),
|
||||
*(((BPy_UnaryPredicate0D *)obj2)->up0D),
|
||||
*(((BPy_UnaryPredicate1D *)obj3)->up1D),
|
||||
f) < 0)
|
||||
{
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Operators.recursive_split() failed");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return nullptr;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_sort_doc,
|
||||
".. staticmethod:: sort(pred)\n"
|
||||
"\n"
|
||||
" Sorts the current set of chains (or viewedges) according to the\n"
|
||||
" comparison predicate given as argument.\n"
|
||||
"\n"
|
||||
" :param pred: The binary predicate used for the comparison.\n"
|
||||
" :type pred: :class:`BinaryPredicate1D`\n");
|
||||
static PyObject *Operators_sort(BPy_Operators * /*self*/, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"pred", nullptr};
|
||||
PyObject *obj = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!", (char **)kwlist, &BinaryPredicate1D_Type, &obj))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (!((BPy_BinaryPredicate1D *)obj)->bp1D) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Operators.sort(): 1st argument: invalid BinaryPredicate1D object");
|
||||
return nullptr;
|
||||
}
|
||||
if (Operators::sort(*(((BPy_BinaryPredicate1D *)obj)->bp1D)) < 0) {
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Operators.sort() failed");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_create_doc,
|
||||
".. staticmethod:: create(pred, shaders)\n"
|
||||
"\n"
|
||||
" Creates and shades the strokes from the current set of chains. A\n"
|
||||
" predicate can be specified to make a selection pass on the chains.\n"
|
||||
"\n"
|
||||
" :param pred: The predicate that a chain must verify in order to be\n"
|
||||
" transform as a stroke.\n"
|
||||
" :type pred: :class:`UnaryPredicate1D`\n"
|
||||
" :param shaders: The list of shaders used to shade the strokes.\n"
|
||||
" :type shaders: list[:class:`StrokeShader`]\n");
|
||||
static PyObject *Operators_create(BPy_Operators * /*self*/, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"pred", "shaders", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!O!", (char **)kwlist, &UnaryPredicate1D_Type, &obj1, &PyList_Type, &obj2))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (!((BPy_UnaryPredicate1D *)obj1)->up1D) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Operators.create(): 1st argument: invalid UnaryPredicate1D object");
|
||||
return nullptr;
|
||||
}
|
||||
vector<StrokeShader *> shaders;
|
||||
shaders.reserve(PyList_Size(obj2));
|
||||
for (int i = 0; i < PyList_Size(obj2); i++) {
|
||||
PyObject *py_ss = PyList_GET_ITEM(obj2, i);
|
||||
if (!BPy_StrokeShader_Check(py_ss)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Operators.create(): 2nd argument must be a list of StrokeShader objects");
|
||||
return nullptr;
|
||||
}
|
||||
StrokeShader *shader = ((BPy_StrokeShader *)py_ss)->ss;
|
||||
if (!shader) {
|
||||
stringstream ss;
|
||||
ss << "Operators.create(): item " << (i + 1)
|
||||
<< " of the shaders list is invalid likely due to missing call of "
|
||||
"StrokeShader.__init__()";
|
||||
PyErr_SetString(PyExc_TypeError, ss.str().c_str());
|
||||
return nullptr;
|
||||
}
|
||||
shaders.push_back(shader);
|
||||
}
|
||||
if (Operators::create(*(((BPy_UnaryPredicate1D *)obj1)->up1D), shaders) < 0) {
|
||||
if (!PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Operators.create() failed");
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_reset_doc,
|
||||
".. staticmethod:: reset(delete_strokes=True)\n"
|
||||
"\n"
|
||||
" Resets the line stylization process to the initial state. The results of\n"
|
||||
" stroke creation are accumulated if **delete_strokes** is set to False.\n"
|
||||
"\n"
|
||||
" :param delete_strokes: Delete the strokes that are currently stored.\n"
|
||||
" :type delete_strokes: bool\n");
|
||||
static PyObject *Operators_reset(BPy_Operators * /*self*/, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"delete_strokes", nullptr};
|
||||
PyObject *obj1 = nullptr;
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist, &PyBool_Type, &obj1)) {
|
||||
// true is the default
|
||||
Operators::reset(obj1 ? bool_from_PyBool(obj1) : true);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Operators.reset() failed");
|
||||
return nullptr;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_get_viewedge_from_index_doc,
|
||||
".. staticmethod:: get_viewedge_from_index(i)\n"
|
||||
"\n"
|
||||
" Returns the ViewEdge at the index in the current set of ViewEdges.\n"
|
||||
"\n"
|
||||
" :param i: index (0 <= i < Operators.get_view_edges_size()).\n"
|
||||
" :type i: int\n"
|
||||
" :return: The ViewEdge object.\n"
|
||||
" :rtype: :class:`ViewEdge`\n");
|
||||
static PyObject *Operators_get_viewedge_from_index(BPy_Operators * /*self*/,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"i", nullptr};
|
||||
uint i;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", (char **)kwlist, &i)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (i >= Operators::getViewEdgesSize()) {
|
||||
PyErr_SetString(PyExc_IndexError, "index out of range");
|
||||
return nullptr;
|
||||
}
|
||||
return BPy_ViewEdge_from_ViewEdge(*(Operators::getViewEdgeFromIndex(i)));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_get_chain_from_index_doc,
|
||||
".. staticmethod:: get_chain_from_index(i)\n"
|
||||
"\n"
|
||||
" Returns the Chain at the index in the current set of Chains.\n"
|
||||
"\n"
|
||||
" :param i: index (0 <= i < Operators.get_chains_size()).\n"
|
||||
" :type i: int\n"
|
||||
" :return: The Chain object.\n"
|
||||
" :rtype: :class:`Chain`\n");
|
||||
static PyObject *Operators_get_chain_from_index(BPy_Operators * /*self*/,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"i", nullptr};
|
||||
uint i;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", (char **)kwlist, &i)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (i >= Operators::getChainsSize()) {
|
||||
PyErr_SetString(PyExc_IndexError, "index out of range");
|
||||
return nullptr;
|
||||
}
|
||||
return BPy_Chain_from_Chain(*(Operators::getChainFromIndex(i)));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_get_stroke_from_index_doc,
|
||||
".. staticmethod:: get_stroke_from_index(i)\n"
|
||||
"\n"
|
||||
" Returns the Stroke at the index in the current set of Strokes.\n"
|
||||
"\n"
|
||||
" :param i: index (0 <= i < Operators.get_strokes_size()).\n"
|
||||
" :type i: int\n"
|
||||
" :return: The Stroke object.\n"
|
||||
" :rtype: :class:`Stroke`\n");
|
||||
static PyObject *Operators_get_stroke_from_index(BPy_Operators * /*self*/,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"i", nullptr};
|
||||
uint i;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "I", (char **)kwlist, &i)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (i >= Operators::getStrokesSize()) {
|
||||
PyErr_SetString(PyExc_IndexError, "index out of range");
|
||||
return nullptr;
|
||||
}
|
||||
return BPy_Stroke_from_Stroke(*(Operators::getStrokeFromIndex(i)));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_get_view_edges_size_doc,
|
||||
".. staticmethod:: get_view_edges_size()\n"
|
||||
"\n"
|
||||
" Returns the number of ViewEdges.\n"
|
||||
"\n"
|
||||
" :return: The number of ViewEdges.\n"
|
||||
" :rtype: int\n");
|
||||
static PyObject *Operators_get_view_edges_size(BPy_Operators * /*self*/)
|
||||
{
|
||||
return PyLong_FromLong(Operators::getViewEdgesSize());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_get_chains_size_doc,
|
||||
".. staticmethod:: get_chains_size()\n"
|
||||
"\n"
|
||||
" Returns the number of Chains.\n"
|
||||
"\n"
|
||||
" :return: The number of Chains.\n"
|
||||
" :rtype: int\n");
|
||||
static PyObject *Operators_get_chains_size(BPy_Operators * /*self*/)
|
||||
{
|
||||
return PyLong_FromLong(Operators::getChainsSize());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Operators_get_strokes_size_doc,
|
||||
".. staticmethod:: get_strokes_size()\n"
|
||||
"\n"
|
||||
" Returns the number of Strokes.\n"
|
||||
"\n"
|
||||
" :return: The number of Strokes.\n"
|
||||
" :rtype: int\n");
|
||||
static PyObject *Operators_get_strokes_size(BPy_Operators * /*self*/)
|
||||
{
|
||||
return PyLong_FromLong(Operators::getStrokesSize());
|
||||
}
|
||||
|
||||
/*----------------------Operators instance definitions ----------------------------*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_Operators_methods[] = {
|
||||
{"select",
|
||||
(PyCFunction)Operators_select,
|
||||
METH_VARARGS | METH_KEYWORDS | METH_STATIC,
|
||||
Operators_select_doc},
|
||||
{"chain",
|
||||
(PyCFunction)Operators_chain,
|
||||
METH_VARARGS | METH_KEYWORDS | METH_STATIC,
|
||||
Operators_chain_doc},
|
||||
{"bidirectional_chain",
|
||||
(PyCFunction)Operators_bidirectional_chain,
|
||||
METH_VARARGS | METH_KEYWORDS | METH_STATIC,
|
||||
Operators_bidirectional_chain_doc},
|
||||
{"sequential_split",
|
||||
(PyCFunction)Operators_sequential_split,
|
||||
METH_VARARGS | METH_KEYWORDS | METH_STATIC,
|
||||
Operators_sequential_split_doc},
|
||||
{"recursive_split",
|
||||
(PyCFunction)Operators_recursive_split,
|
||||
METH_VARARGS | METH_KEYWORDS | METH_STATIC,
|
||||
Operators_recursive_split_doc},
|
||||
{"sort",
|
||||
(PyCFunction)Operators_sort,
|
||||
METH_VARARGS | METH_KEYWORDS | METH_STATIC,
|
||||
Operators_sort_doc},
|
||||
{"create",
|
||||
(PyCFunction)Operators_create,
|
||||
METH_VARARGS | METH_KEYWORDS | METH_STATIC,
|
||||
Operators_create_doc},
|
||||
{"reset",
|
||||
(PyCFunction)Operators_reset,
|
||||
METH_VARARGS | METH_KEYWORDS | METH_STATIC,
|
||||
Operators_reset_doc},
|
||||
{"get_viewedge_from_index",
|
||||
(PyCFunction)Operators_get_viewedge_from_index,
|
||||
METH_VARARGS | METH_KEYWORDS | METH_STATIC,
|
||||
Operators_get_viewedge_from_index_doc},
|
||||
{"get_chain_from_index",
|
||||
(PyCFunction)Operators_get_chain_from_index,
|
||||
METH_VARARGS | METH_KEYWORDS | METH_STATIC,
|
||||
Operators_get_chain_from_index_doc},
|
||||
{"get_stroke_from_index",
|
||||
(PyCFunction)Operators_get_stroke_from_index,
|
||||
METH_VARARGS | METH_KEYWORDS | METH_STATIC,
|
||||
Operators_get_stroke_from_index_doc},
|
||||
{"get_view_edges_size",
|
||||
(PyCFunction)Operators_get_view_edges_size,
|
||||
METH_NOARGS | METH_STATIC,
|
||||
Operators_get_view_edges_size_doc},
|
||||
{"get_chains_size",
|
||||
(PyCFunction)Operators_get_chains_size,
|
||||
METH_NOARGS | METH_STATIC,
|
||||
Operators_get_chains_size_doc},
|
||||
{"get_strokes_size",
|
||||
(PyCFunction)Operators_get_strokes_size,
|
||||
METH_NOARGS | METH_STATIC,
|
||||
Operators_get_strokes_size_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*-----------------------BPy_Operators type definition ------------------------------*/
|
||||
|
||||
PyTypeObject Operators_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Operators",
|
||||
/*tp_basicsize*/ sizeof(BPy_Operators),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)Operators_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT,
|
||||
/*tp_doc*/ Operators_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_Operators_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ nullptr,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,32 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../stroke/Operators.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject Operators_Type;
|
||||
|
||||
#define BPy_Operators_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Operators_Type))
|
||||
|
||||
/*---------------------------Python BPy_Operators structure definition----------*/
|
||||
struct BPy_Operators {
|
||||
PyObject_HEAD
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_Operators visible prototypes-----------*/
|
||||
|
||||
int Operators_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,338 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_SShape.h"
|
||||
|
||||
#include "BPy_BBox.h"
|
||||
#include "BPy_Convert.h"
|
||||
#include "BPy_Id.h"
|
||||
#include "Interface0D/BPy_SVertex.h"
|
||||
#include "Interface1D/BPy_FEdge.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#include "../generic/py_capi_utils.hh"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int SShape_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&SShape_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "SShape", (PyObject *)&SShape_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------SShape methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SShape_doc,
|
||||
"Class to define a feature shape. It is the gathering of feature\n"
|
||||
"elements from an identified input shape.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
"\n"
|
||||
" Creates a :class:`SShape` class using either a default constructor or copy constructor.\n"
|
||||
"\n"
|
||||
" :param brother: An SShape object.\n"
|
||||
" :type brother: :class:`SShape`\n");
|
||||
static int SShape_init(BPy_SShape *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"brother", nullptr};
|
||||
PyObject *brother = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist, &SShape_Type, &brother)) {
|
||||
return -1;
|
||||
}
|
||||
if (!brother) {
|
||||
self->ss = new SShape();
|
||||
}
|
||||
else {
|
||||
self->ss = new SShape(*(((BPy_SShape *)brother)->ss));
|
||||
}
|
||||
self->borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SShape_dealloc(BPy_SShape *self)
|
||||
{
|
||||
if (self->ss && !self->borrowed) {
|
||||
delete self->ss;
|
||||
}
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *SShape_repr(BPy_SShape *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("SShape - address: %p", self->ss);
|
||||
}
|
||||
|
||||
static char SShape_add_edge_doc[] =
|
||||
".. method:: add_edge(edge)\n"
|
||||
"\n"
|
||||
" Adds an FEdge to the list of FEdges.\n"
|
||||
"\n"
|
||||
" :param edge: An FEdge object.\n"
|
||||
" :type edge: :class:`FEdge`\n";
|
||||
|
||||
static PyObject *SShape_add_edge(BPy_SShape *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"edge", nullptr};
|
||||
PyObject *py_fe = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &FEdge_Type, &py_fe)) {
|
||||
return nullptr;
|
||||
}
|
||||
self->ss->AddEdge(((BPy_FEdge *)py_fe)->fe);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SShape_add_vertex_doc,
|
||||
".. method:: add_vertex(vertex)\n"
|
||||
"\n"
|
||||
" Adds an SVertex to the list of SVertex of this Shape. The SShape\n"
|
||||
" attribute of the SVertex is also set to this SShape.\n"
|
||||
"\n"
|
||||
" :param vertex: An SVertex object.\n"
|
||||
" :type vertex: :class:`SVertex`\n");
|
||||
static PyObject *SShape_add_vertex(BPy_SShape *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"edge", nullptr};
|
||||
PyObject *py_sv = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &SVertex_Type, &py_sv)) {
|
||||
return nullptr;
|
||||
}
|
||||
self->ss->AddNewVertex(((BPy_SVertex *)py_sv)->sv);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SShape_compute_bbox_doc,
|
||||
".. method:: compute_bbox()\n"
|
||||
"\n"
|
||||
" Compute the bbox of the SShape.\n");
|
||||
static PyObject *SShape_compute_bbox(BPy_SShape *self)
|
||||
{
|
||||
self->ss->ComputeBBox();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
// const Material & material (uint i) const
|
||||
// const vector< Material > & materials () const
|
||||
// void SetMaterials (const vector< Material > &iMaterials)
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_SShape_methods[] = {
|
||||
{"add_edge", (PyCFunction)SShape_add_edge, METH_VARARGS | METH_KEYWORDS, SShape_add_edge_doc},
|
||||
{"add_vertex",
|
||||
(PyCFunction)SShape_add_vertex,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
SShape_add_vertex_doc},
|
||||
{"compute_bbox", (PyCFunction)SShape_compute_bbox, METH_NOARGS, SShape_compute_bbox_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------SShape get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SShape_id_doc,
|
||||
"The Id of this SShape.\n"
|
||||
"\n"
|
||||
":type: :class:`Id`\n");
|
||||
static PyObject *SShape_id_get(BPy_SShape *self, void * /*closure*/)
|
||||
{
|
||||
Id id(self->ss->getId());
|
||||
return BPy_Id_from_Id(id); // return a copy
|
||||
}
|
||||
|
||||
static int SShape_id_set(BPy_SShape *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_Id_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an Id");
|
||||
return -1;
|
||||
}
|
||||
self->ss->setId(*(((BPy_Id *)value)->id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SShape_name_doc,
|
||||
"The name of the SShape.\n"
|
||||
"\n"
|
||||
":type: str\n");
|
||||
static PyObject *SShape_name_get(BPy_SShape *self, void * /*closure*/)
|
||||
{
|
||||
return blender::PyC_UnicodeFromStdStr(self->ss->getName());
|
||||
}
|
||||
|
||||
static int SShape_name_set(BPy_SShape *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!PyUnicode_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a string");
|
||||
return -1;
|
||||
}
|
||||
const char *name = PyUnicode_AsUTF8(value);
|
||||
self->ss->setName(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SShape_bbox_doc,
|
||||
"The bounding box of the SShape.\n"
|
||||
"\n"
|
||||
":type: :class:`BBox`\n");
|
||||
static PyObject *SShape_bbox_get(BPy_SShape *self, void * /*closure*/)
|
||||
{
|
||||
BBox<Vec3r> bb(self->ss->bbox());
|
||||
return BPy_BBox_from_BBox(bb); // return a copy
|
||||
}
|
||||
|
||||
static int SShape_bbox_set(BPy_SShape *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_BBox_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a BBox");
|
||||
return -1;
|
||||
}
|
||||
self->ss->setBBox(*(((BPy_BBox *)value)->bb));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SShape_vertices_doc,
|
||||
"The list of vertices constituting this SShape.\n"
|
||||
"\n"
|
||||
":type: list[:class:`SVertex`]\n");
|
||||
static PyObject *SShape_vertices_get(BPy_SShape *self, void * /*closure*/)
|
||||
{
|
||||
|
||||
vector<SVertex *> vertices = self->ss->getVertexList();
|
||||
vector<SVertex *>::iterator it;
|
||||
PyObject *py_vertices = PyList_New(vertices.size());
|
||||
uint i = 0;
|
||||
|
||||
for (it = vertices.begin(); it != vertices.end(); it++) {
|
||||
PyList_SET_ITEM(py_vertices, i++, BPy_SVertex_from_SVertex(*(*it)));
|
||||
}
|
||||
|
||||
return py_vertices;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SShape_edges_doc,
|
||||
"The list of edges constituting this SShape.\n"
|
||||
"\n"
|
||||
":type: list[:class:`FEdge`]\n");
|
||||
static PyObject *SShape_edges_get(BPy_SShape *self, void * /*closure*/)
|
||||
{
|
||||
|
||||
vector<FEdge *> edges = self->ss->getEdgeList();
|
||||
vector<FEdge *>::iterator it;
|
||||
PyObject *py_edges = PyList_New(edges.size());
|
||||
uint i = 0;
|
||||
|
||||
for (it = edges.begin(); it != edges.end(); it++) {
|
||||
PyList_SET_ITEM(py_edges, i++, Any_BPy_FEdge_from_FEdge(*(*it)));
|
||||
}
|
||||
|
||||
return py_edges;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_SShape_getseters[] = {
|
||||
{"id", (getter)SShape_id_get, (setter)SShape_id_set, SShape_id_doc, nullptr},
|
||||
{"name", (getter)SShape_name_get, (setter)SShape_name_set, SShape_name_doc, nullptr},
|
||||
{"bbox", (getter)SShape_bbox_get, (setter)SShape_bbox_set, SShape_bbox_doc, nullptr},
|
||||
{"edges", (getter)SShape_edges_get, (setter) nullptr, SShape_edges_doc, nullptr},
|
||||
{"vertices", (getter)SShape_vertices_get, (setter) nullptr, SShape_vertices_doc, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_SShape type definition ------------------------------*/
|
||||
|
||||
PyTypeObject SShape_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "SShape",
|
||||
/*tp_basicsize*/ sizeof(BPy_SShape),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)SShape_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)SShape_repr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ SShape_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_SShape_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_SShape_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)SShape_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,34 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../view_map/Silhouette.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject SShape_Type;
|
||||
|
||||
#define BPy_SShape_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&SShape_Type))
|
||||
|
||||
/*---------------------------Python BPy_SShape structure definition----------*/
|
||||
struct BPy_SShape {
|
||||
PyObject_HEAD
|
||||
Freestyle::SShape *ss;
|
||||
bool borrowed; /* true if *ss is a borrowed object */
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_SShape visible prototypes-----------*/
|
||||
|
||||
int SShape_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,750 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_StrokeAttribute.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
|
||||
#include "../generic/py_capi_utils.hh"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int StrokeAttribute_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&StrokeAttribute_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "StrokeAttribute", (PyObject *)&StrokeAttribute_Type);
|
||||
|
||||
StrokeAttribute_mathutils_register_callback();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_doc,
|
||||
"Class to define a set of attributes associated with a :class:`StrokeVertex`.\n"
|
||||
"The attribute set stores the color, alpha and thickness values for a Stroke\n"
|
||||
"Vertex.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(red, green, blue, alpha, thickness_right, thickness_left)``\n"
|
||||
" - ``__init__(attribute1, attribute2, t)``\n"
|
||||
"\n"
|
||||
" Creates a :class:`StrokeAttribute` object using either a default constructor,\n"
|
||||
" copy constructor, overloaded constructor, or and interpolation constructor\n"
|
||||
" to interpolate between two :class:`StrokeAttribute` objects.\n"
|
||||
"\n"
|
||||
" :param brother: A StrokeAttribute object to be used as a copy constructor.\n"
|
||||
" :type brother: :class:`StrokeAttribute`\n"
|
||||
" :param red: Red component of a stroke color.\n"
|
||||
" :type red: float\n"
|
||||
" :param green: Green component of a stroke color.\n"
|
||||
" :type green: float\n"
|
||||
" :param blue: Blue component of a stroke color.\n"
|
||||
" :type blue: float\n"
|
||||
" :param alpha: Alpha component of a stroke color.\n"
|
||||
" :type alpha: float\n"
|
||||
" :param thickness_right: Stroke thickness on the right.\n"
|
||||
" :type thickness_right: float\n"
|
||||
" :param thickness_left: Stroke thickness on the left.\n"
|
||||
" :type thickness_left: float\n"
|
||||
" :param attribute1: The first StrokeAttribute object.\n"
|
||||
" :type attribute1: :class:`StrokeAttribute`\n"
|
||||
" :param attribute2: The second StrokeAttribute object.\n"
|
||||
" :type attribute2: :class:`StrokeAttribute`\n"
|
||||
" :param t: The interpolation parameter (0 <= t <= 1).\n"
|
||||
" :type t: float\n");
|
||||
static int StrokeAttribute_init(BPy_StrokeAttribute *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"attribute1", "attribute2", "t", nullptr};
|
||||
static const char *kwlist_3[] = {
|
||||
"red", "green", "blue", "alpha", "thickness_right", "thickness_left", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr;
|
||||
float red, green, blue, alpha, thickness_right, thickness_left, t;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "|O!", (char **)kwlist_1, &StrokeAttribute_Type, &obj1))
|
||||
{
|
||||
if (!obj1) {
|
||||
self->sa = new StrokeAttribute();
|
||||
}
|
||||
else {
|
||||
self->sa = new StrokeAttribute(*(((BPy_StrokeAttribute *)obj1)->sa));
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!O!f",
|
||||
(char **)kwlist_2,
|
||||
&StrokeAttribute_Type,
|
||||
&obj1,
|
||||
&StrokeAttribute_Type,
|
||||
&obj2,
|
||||
&t))
|
||||
{
|
||||
self->sa = new StrokeAttribute(
|
||||
*(((BPy_StrokeAttribute *)obj1)->sa), *(((BPy_StrokeAttribute *)obj2)->sa), t);
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"ffffff",
|
||||
(char **)kwlist_3,
|
||||
&red,
|
||||
&green,
|
||||
&blue,
|
||||
&alpha,
|
||||
&thickness_right,
|
||||
&thickness_left))
|
||||
{
|
||||
self->sa = new StrokeAttribute(red, green, blue, alpha, thickness_right, thickness_left);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void StrokeAttribute_dealloc(BPy_StrokeAttribute *self)
|
||||
{
|
||||
if (self->sa && !self->borrowed) {
|
||||
delete self->sa;
|
||||
}
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *StrokeAttribute_repr(BPy_StrokeAttribute *self)
|
||||
{
|
||||
stringstream repr("StrokeAttribute:");
|
||||
repr << " r: " << self->sa->getColorR() << " g: " << self->sa->getColorG()
|
||||
<< " b: " << self->sa->getColorB() << " a: " << self->sa->getAlpha()
|
||||
<< " - R: " << self->sa->getThicknessR() << " L: " << self->sa->getThicknessL();
|
||||
|
||||
return blender::PyC_UnicodeFromStdStr(repr.str());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_get_attribute_real_doc,
|
||||
".. method:: get_attribute_real(name)\n"
|
||||
"\n"
|
||||
" Returns an attribute of float type.\n"
|
||||
"\n"
|
||||
" :param name: The name of the attribute.\n"
|
||||
" :type name: str\n"
|
||||
" :return: The attribute value.\n"
|
||||
" :rtype: float\n");
|
||||
static PyObject *StrokeAttribute_get_attribute_real(BPy_StrokeAttribute *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"name", nullptr};
|
||||
char *attr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", (char **)kwlist, &attr)) {
|
||||
return nullptr;
|
||||
}
|
||||
double a = self->sa->getAttributeReal(attr);
|
||||
return PyFloat_FromDouble(a);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_get_attribute_vec2_doc,
|
||||
".. method:: get_attribute_vec2(name)\n"
|
||||
"\n"
|
||||
" Returns an attribute of two-dimensional vector type.\n"
|
||||
"\n"
|
||||
" :param name: The name of the attribute.\n"
|
||||
" :type name: str\n"
|
||||
" :return: The attribute value.\n"
|
||||
" :rtype: :class:`mathutils.Vector`\n");
|
||||
static PyObject *StrokeAttribute_get_attribute_vec2(BPy_StrokeAttribute *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"name", nullptr};
|
||||
char *attr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", (char **)kwlist, &attr)) {
|
||||
return nullptr;
|
||||
}
|
||||
Vec2f a = self->sa->getAttributeVec2f(attr);
|
||||
return Vector_from_Vec2f(a);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_get_attribute_vec3_doc,
|
||||
".. method:: get_attribute_vec3(name)\n"
|
||||
"\n"
|
||||
" Returns an attribute of three-dimensional vector type.\n"
|
||||
"\n"
|
||||
" :param name: The name of the attribute.\n"
|
||||
" :type name: str\n"
|
||||
" :return: The attribute value.\n"
|
||||
" :rtype: :class:`mathutils.Vector`\n");
|
||||
static PyObject *StrokeAttribute_get_attribute_vec3(BPy_StrokeAttribute *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"name", nullptr};
|
||||
char *attr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", (char **)kwlist, &attr)) {
|
||||
return nullptr;
|
||||
}
|
||||
Vec3f a = self->sa->getAttributeVec3f(attr);
|
||||
return Vector_from_Vec3f(a);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_has_attribute_real_doc,
|
||||
".. method:: has_attribute_real(name)\n"
|
||||
"\n"
|
||||
" Checks whether the attribute name of float type is available.\n"
|
||||
"\n"
|
||||
" :param name: The name of the attribute.\n"
|
||||
" :type name: str\n"
|
||||
" :return: True if the attribute is available.\n"
|
||||
" :rtype: bool\n");
|
||||
static PyObject *StrokeAttribute_has_attribute_real(BPy_StrokeAttribute *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"name", nullptr};
|
||||
char *attr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", (char **)kwlist, &attr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return PyBool_from_bool(self->sa->isAttributeAvailableReal(attr));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_has_attribute_vec2_doc,
|
||||
".. method:: has_attribute_vec2(name)\n"
|
||||
"\n"
|
||||
" Checks whether the attribute name of two-dimensional vector type\n"
|
||||
" is available.\n"
|
||||
"\n"
|
||||
" :param name: The name of the attribute.\n"
|
||||
" :type name: str\n"
|
||||
" :return: True if the attribute is available.\n"
|
||||
" :rtype: bool\n");
|
||||
static PyObject *StrokeAttribute_has_attribute_vec2(BPy_StrokeAttribute *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"name", nullptr};
|
||||
char *attr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", (char **)kwlist, &attr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return PyBool_from_bool(self->sa->isAttributeAvailableVec2f(attr));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_has_attribute_vec3_doc,
|
||||
".. method:: has_attribute_vec3(name)\n"
|
||||
"\n"
|
||||
" Checks whether the attribute name of three-dimensional vector\n"
|
||||
" type is available.\n"
|
||||
"\n"
|
||||
" :param name: The name of the attribute.\n"
|
||||
" :type name: str\n"
|
||||
" :return: True if the attribute is available.\n"
|
||||
" :rtype: bool\n");
|
||||
static PyObject *StrokeAttribute_has_attribute_vec3(BPy_StrokeAttribute *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"name", nullptr};
|
||||
char *attr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", (char **)kwlist, &attr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return PyBool_from_bool(self->sa->isAttributeAvailableVec3f(attr));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_set_attribute_real_doc,
|
||||
".. method:: set_attribute_real(name, value)\n"
|
||||
"\n"
|
||||
" Adds a user-defined attribute of float type. If there is no\n"
|
||||
" attribute of the given name, it is added. Otherwise, the new value\n"
|
||||
" replaces the old one.\n"
|
||||
"\n"
|
||||
" :param name: The name of the attribute.\n"
|
||||
" :type name: str\n"
|
||||
" :param value: The attribute value.\n"
|
||||
" :type value: float\n");
|
||||
static PyObject *StrokeAttribute_set_attribute_real(BPy_StrokeAttribute *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"name", "value", nullptr};
|
||||
char *s = nullptr;
|
||||
double d = 0;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "sd", (char **)kwlist, &s, &d)) {
|
||||
return nullptr;
|
||||
}
|
||||
self->sa->setAttributeReal(s, d);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_set_attribute_vec2_doc,
|
||||
".. method:: set_attribute_vec2(name, value)\n"
|
||||
"\n"
|
||||
" Adds a user-defined attribute of two-dimensional vector type. If\n"
|
||||
" there is no attribute of the given name, it is added. Otherwise,\n"
|
||||
" the new value replaces the old one.\n"
|
||||
"\n"
|
||||
" :param name: The name of the attribute.\n"
|
||||
" :type name: str\n"
|
||||
" :param value: The attribute value.\n"
|
||||
" :type value: :class:`mathutils.Vector` | tuple[float, float, float] | list[float]\n");
|
||||
static PyObject *StrokeAttribute_set_attribute_vec2(BPy_StrokeAttribute *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"name", "value", nullptr};
|
||||
char *s;
|
||||
PyObject *obj = nullptr;
|
||||
Vec2f vec;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO", (char **)kwlist, &s, &obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!Vec2f_ptr_from_PyObject(obj, vec)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"argument 2 must be a 2D vector (either a list of 2 elements or Vector)");
|
||||
return nullptr;
|
||||
}
|
||||
self->sa->setAttributeVec2f(s, vec);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_set_attribute_vec3_doc,
|
||||
".. method:: set_attribute_vec3(name, value)\n"
|
||||
"\n"
|
||||
" Adds a user-defined attribute of three-dimensional vector type.\n"
|
||||
" If there is no attribute of the given name, it is added.\n"
|
||||
" Otherwise, the new value replaces the old one.\n"
|
||||
"\n"
|
||||
" :param name: The name of the attribute.\n"
|
||||
" :type name: str\n"
|
||||
" :param value: The attribute value as a 3D vector.\n"
|
||||
" :type value: :class:`mathutils.Vector` | tuple[float, float, float] | list[float]\n");
|
||||
static PyObject *StrokeAttribute_set_attribute_vec3(BPy_StrokeAttribute *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"name", "value", nullptr};
|
||||
char *s;
|
||||
PyObject *obj = nullptr;
|
||||
Vec3f vec;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO", (char **)kwlist, &s, &obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!Vec3f_ptr_from_PyObject(obj, vec)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"argument 2 must be a 3D vector (either a list of 3 elements or Vector)");
|
||||
return nullptr;
|
||||
}
|
||||
self->sa->setAttributeVec3f(s, vec);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_StrokeAttribute_methods[] = {
|
||||
{"get_attribute_real",
|
||||
(PyCFunction)StrokeAttribute_get_attribute_real,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
StrokeAttribute_get_attribute_real_doc},
|
||||
{"get_attribute_vec2",
|
||||
(PyCFunction)StrokeAttribute_get_attribute_vec2,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
StrokeAttribute_get_attribute_vec2_doc},
|
||||
{"get_attribute_vec3",
|
||||
(PyCFunction)StrokeAttribute_get_attribute_vec3,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
StrokeAttribute_get_attribute_vec3_doc},
|
||||
{"has_attribute_real",
|
||||
(PyCFunction)StrokeAttribute_has_attribute_real,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
StrokeAttribute_has_attribute_real_doc},
|
||||
{"has_attribute_vec2",
|
||||
(PyCFunction)StrokeAttribute_has_attribute_vec2,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
StrokeAttribute_has_attribute_vec2_doc},
|
||||
{"has_attribute_vec3",
|
||||
(PyCFunction)StrokeAttribute_has_attribute_vec3,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
StrokeAttribute_has_attribute_vec3_doc},
|
||||
{"set_attribute_real",
|
||||
(PyCFunction)StrokeAttribute_set_attribute_real,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
StrokeAttribute_set_attribute_real_doc},
|
||||
{"set_attribute_vec2",
|
||||
(PyCFunction)StrokeAttribute_set_attribute_vec2,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
StrokeAttribute_set_attribute_vec2_doc},
|
||||
{"set_attribute_vec3",
|
||||
(PyCFunction)StrokeAttribute_set_attribute_vec3,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
StrokeAttribute_set_attribute_vec3_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------mathutils callbacks ----------------------------*/
|
||||
|
||||
/* subtype */
|
||||
#define MATHUTILS_SUBTYPE_COLOR 1
|
||||
#define MATHUTILS_SUBTYPE_THICKNESS 2
|
||||
|
||||
static int StrokeAttribute_mathutils_check(blender::BaseMathObject *bmo)
|
||||
{
|
||||
if (!BPy_StrokeAttribute_Check(bmo->cb_user)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int StrokeAttribute_mathutils_get(blender::BaseMathObject *bmo, int subtype)
|
||||
{
|
||||
BPy_StrokeAttribute *self = (BPy_StrokeAttribute *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_COLOR:
|
||||
bmo->data[0] = self->sa->getColorR();
|
||||
bmo->data[1] = self->sa->getColorG();
|
||||
bmo->data[2] = self->sa->getColorB();
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_THICKNESS:
|
||||
bmo->data[0] = self->sa->getThicknessR();
|
||||
bmo->data[1] = self->sa->getThicknessL();
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int StrokeAttribute_mathutils_set(blender::BaseMathObject *bmo, int subtype)
|
||||
{
|
||||
BPy_StrokeAttribute *self = (BPy_StrokeAttribute *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_COLOR:
|
||||
self->sa->setColor(bmo->data[0], bmo->data[1], bmo->data[2]);
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_THICKNESS:
|
||||
self->sa->setThickness(bmo->data[0], bmo->data[1]);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int StrokeAttribute_mathutils_get_index(blender::BaseMathObject *bmo,
|
||||
int subtype,
|
||||
int index)
|
||||
{
|
||||
BPy_StrokeAttribute *self = (BPy_StrokeAttribute *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_COLOR:
|
||||
switch (index) {
|
||||
case 0:
|
||||
bmo->data[0] = self->sa->getColorR();
|
||||
break;
|
||||
case 1:
|
||||
bmo->data[1] = self->sa->getColorG();
|
||||
break;
|
||||
case 2:
|
||||
bmo->data[2] = self->sa->getColorB();
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_THICKNESS:
|
||||
switch (index) {
|
||||
case 0:
|
||||
bmo->data[0] = self->sa->getThicknessR();
|
||||
break;
|
||||
case 1:
|
||||
bmo->data[1] = self->sa->getThicknessL();
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int StrokeAttribute_mathutils_set_index(blender::BaseMathObject *bmo,
|
||||
int subtype,
|
||||
int index)
|
||||
{
|
||||
BPy_StrokeAttribute *self = (BPy_StrokeAttribute *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_COLOR: {
|
||||
float r = (index == 0) ? bmo->data[0] : self->sa->getColorR();
|
||||
float g = (index == 1) ? bmo->data[1] : self->sa->getColorG();
|
||||
float b = (index == 2) ? bmo->data[2] : self->sa->getColorB();
|
||||
self->sa->setColor(r, g, b);
|
||||
break;
|
||||
}
|
||||
case MATHUTILS_SUBTYPE_THICKNESS: {
|
||||
float tr = (index == 0) ? bmo->data[0] : self->sa->getThicknessR();
|
||||
float tl = (index == 1) ? bmo->data[1] : self->sa->getThicknessL();
|
||||
self->sa->setThickness(tr, tl);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static blender::Mathutils_Callback StrokeAttribute_mathutils_cb = {
|
||||
StrokeAttribute_mathutils_check,
|
||||
StrokeAttribute_mathutils_get,
|
||||
StrokeAttribute_mathutils_set,
|
||||
StrokeAttribute_mathutils_get_index,
|
||||
StrokeAttribute_mathutils_set_index,
|
||||
};
|
||||
|
||||
static uchar StrokeAttribute_mathutils_cb_index = -1;
|
||||
|
||||
void StrokeAttribute_mathutils_register_callback()
|
||||
{
|
||||
StrokeAttribute_mathutils_cb_index = Mathutils_RegisterCallback(&StrokeAttribute_mathutils_cb);
|
||||
}
|
||||
|
||||
/*----------------------StrokeAttribute get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_alpha_doc,
|
||||
"Alpha component of the stroke color.\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *StrokeAttribute_alpha_get(BPy_StrokeAttribute *self, void * /*closure*/)
|
||||
{
|
||||
return PyFloat_FromDouble(self->sa->getAlpha());
|
||||
}
|
||||
|
||||
static int StrokeAttribute_alpha_set(BPy_StrokeAttribute *self,
|
||||
PyObject *value,
|
||||
void * /*closure*/)
|
||||
{
|
||||
float scalar;
|
||||
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
|
||||
/* parsed item not a number */
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a number");
|
||||
return -1;
|
||||
}
|
||||
self->sa->setAlpha(scalar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_color_doc,
|
||||
"RGB components of the stroke color.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Color`\n");
|
||||
static PyObject *StrokeAttribute_color_get(BPy_StrokeAttribute *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Color_CreatePyObject_cb(
|
||||
(PyObject *)self, StrokeAttribute_mathutils_cb_index, MATHUTILS_SUBTYPE_COLOR);
|
||||
}
|
||||
|
||||
static int StrokeAttribute_color_set(BPy_StrokeAttribute *self,
|
||||
PyObject *value,
|
||||
void * /*closure*/)
|
||||
{
|
||||
float v[3];
|
||||
if (blender::mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
self->sa->setColor(v[0], v[1], v[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_thickness_doc,
|
||||
"Right and left components of the stroke thickness.\n"
|
||||
"The right (left) component is the thickness on the right (left) of the vertex\n"
|
||||
"when following the stroke.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Vector`\n");
|
||||
static PyObject *StrokeAttribute_thickness_get(BPy_StrokeAttribute *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Vector_CreatePyObject_cb(
|
||||
(PyObject *)self, 2, StrokeAttribute_mathutils_cb_index, MATHUTILS_SUBTYPE_THICKNESS);
|
||||
}
|
||||
|
||||
static int StrokeAttribute_thickness_set(BPy_StrokeAttribute *self,
|
||||
PyObject *value,
|
||||
void * /*closure*/)
|
||||
{
|
||||
float v[2];
|
||||
if (blender::mathutils_array_parse(v, 2, 2, value, "value must be a 2-dimensional vector") == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
self->sa->setThickness(v[0], v[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeAttribute_visible_doc,
|
||||
"The visibility flag. True if the StrokeVertex is visible.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *StrokeAttribute_visible_get(BPy_StrokeAttribute *self, void * /*closure*/)
|
||||
{
|
||||
return PyBool_from_bool(self->sa->isVisible());
|
||||
}
|
||||
|
||||
static int StrokeAttribute_visible_set(BPy_StrokeAttribute *self,
|
||||
PyObject *value,
|
||||
void * /*closure*/)
|
||||
{
|
||||
if (!PyBool_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be boolean");
|
||||
return -1;
|
||||
}
|
||||
self->sa->setVisible(bool_from_PyBool(value));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_StrokeAttribute_getseters[] = {
|
||||
{"alpha",
|
||||
(getter)StrokeAttribute_alpha_get,
|
||||
(setter)StrokeAttribute_alpha_set,
|
||||
StrokeAttribute_alpha_doc,
|
||||
nullptr},
|
||||
{"color",
|
||||
(getter)StrokeAttribute_color_get,
|
||||
(setter)StrokeAttribute_color_set,
|
||||
StrokeAttribute_color_doc,
|
||||
nullptr},
|
||||
{"thickness",
|
||||
(getter)StrokeAttribute_thickness_get,
|
||||
(setter)StrokeAttribute_thickness_set,
|
||||
StrokeAttribute_thickness_doc,
|
||||
nullptr},
|
||||
{"visible",
|
||||
(getter)StrokeAttribute_visible_get,
|
||||
(setter)StrokeAttribute_visible_set,
|
||||
StrokeAttribute_visible_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_StrokeAttribute type definition ------------------------------*/
|
||||
|
||||
PyTypeObject StrokeAttribute_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "StrokeAttribute",
|
||||
/*tp_basicsize*/ sizeof(BPy_StrokeAttribute),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)StrokeAttribute_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)StrokeAttribute_repr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ StrokeAttribute_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_StrokeAttribute_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_StrokeAttribute_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)StrokeAttribute_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,36 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../stroke/Stroke.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject StrokeAttribute_Type;
|
||||
|
||||
#define BPy_StrokeAttribute_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&StrokeAttribute_Type))
|
||||
|
||||
/*---------------------------Python BPy_StrokeAttribute structure definition----------*/
|
||||
struct BPy_StrokeAttribute {
|
||||
PyObject_HEAD
|
||||
Freestyle::StrokeAttribute *sa;
|
||||
bool borrowed; /* true if *sa is a borrowed reference */
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_StrokeAttribute visible prototypes-----------*/
|
||||
|
||||
int StrokeAttribute_Init(PyObject *module);
|
||||
void StrokeAttribute_mathutils_register_callback();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,313 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_StrokeShader.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
#include "Interface1D/BPy_Stroke.h"
|
||||
|
||||
#include "StrokeShader/BPy_BackboneStretcherShader.h"
|
||||
#include "StrokeShader/BPy_BezierCurveShader.h"
|
||||
#include "StrokeShader/BPy_BlenderTextureShader.h"
|
||||
#include "StrokeShader/BPy_CalligraphicShader.h"
|
||||
#include "StrokeShader/BPy_ColorNoiseShader.h"
|
||||
#include "StrokeShader/BPy_ConstantColorShader.h"
|
||||
#include "StrokeShader/BPy_ConstantThicknessShader.h"
|
||||
#include "StrokeShader/BPy_ConstrainedIncreasingThicknessShader.h"
|
||||
#include "StrokeShader/BPy_GuidingLinesShader.h"
|
||||
#include "StrokeShader/BPy_IncreasingColorShader.h"
|
||||
#include "StrokeShader/BPy_IncreasingThicknessShader.h"
|
||||
#include "StrokeShader/BPy_PolygonalizationShader.h"
|
||||
#include "StrokeShader/BPy_SamplingShader.h"
|
||||
#include "StrokeShader/BPy_SmoothingShader.h"
|
||||
#include "StrokeShader/BPy_SpatialNoiseShader.h"
|
||||
#include "StrokeShader/BPy_StrokeTextureStepShader.h"
|
||||
#include "StrokeShader/BPy_ThicknessNoiseShader.h"
|
||||
#include "StrokeShader/BPy_TipRemoverShader.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int StrokeShader_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&StrokeShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "StrokeShader", (PyObject *)&StrokeShader_Type);
|
||||
|
||||
if (PyType_Ready(&BackboneStretcherShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(
|
||||
module, "BackboneStretcherShader", (PyObject *)&BackboneStretcherShader_Type);
|
||||
|
||||
if (PyType_Ready(&BezierCurveShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "BezierCurveShader", (PyObject *)&BezierCurveShader_Type);
|
||||
|
||||
if (PyType_Ready(&BlenderTextureShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "BlenderTextureShader", (PyObject *)&BlenderTextureShader_Type);
|
||||
|
||||
if (PyType_Ready(&CalligraphicShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "CalligraphicShader", (PyObject *)&CalligraphicShader_Type);
|
||||
|
||||
if (PyType_Ready(&ColorNoiseShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ColorNoiseShader", (PyObject *)&ColorNoiseShader_Type);
|
||||
|
||||
if (PyType_Ready(&ConstantColorShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ConstantColorShader", (PyObject *)&ConstantColorShader_Type);
|
||||
|
||||
if (PyType_Ready(&ConstantThicknessShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(
|
||||
module, "ConstantThicknessShader", (PyObject *)&ConstantThicknessShader_Type);
|
||||
|
||||
if (PyType_Ready(&ConstrainedIncreasingThicknessShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module,
|
||||
"ConstrainedIncreasingThicknessShader",
|
||||
(PyObject *)&ConstrainedIncreasingThicknessShader_Type);
|
||||
|
||||
if (PyType_Ready(&GuidingLinesShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "GuidingLinesShader", (PyObject *)&GuidingLinesShader_Type);
|
||||
|
||||
if (PyType_Ready(&IncreasingColorShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "IncreasingColorShader", (PyObject *)&IncreasingColorShader_Type);
|
||||
|
||||
if (PyType_Ready(&IncreasingThicknessShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(
|
||||
module, "IncreasingThicknessShader", (PyObject *)&IncreasingThicknessShader_Type);
|
||||
|
||||
if (PyType_Ready(&PolygonalizationShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(
|
||||
module, "PolygonalizationShader", (PyObject *)&PolygonalizationShader_Type);
|
||||
|
||||
if (PyType_Ready(&SamplingShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "SamplingShader", (PyObject *)&SamplingShader_Type);
|
||||
|
||||
if (PyType_Ready(&SmoothingShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "SmoothingShader", (PyObject *)&SmoothingShader_Type);
|
||||
|
||||
if (PyType_Ready(&SpatialNoiseShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "SpatialNoiseShader", (PyObject *)&SpatialNoiseShader_Type);
|
||||
|
||||
if (PyType_Ready(&StrokeTextureStepShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(
|
||||
module, "StrokeTextureStepShader", (PyObject *)&StrokeTextureStepShader_Type);
|
||||
|
||||
if (PyType_Ready(&ThicknessNoiseShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ThicknessNoiseShader", (PyObject *)&ThicknessNoiseShader_Type);
|
||||
|
||||
if (PyType_Ready(&TipRemoverShader_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "TipRemoverShader", (PyObject *)&TipRemoverShader_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeShader___doc__,
|
||||
"Base class for stroke shaders. Any stroke shader must inherit from\n"
|
||||
"this class and overload the shade() method. A StrokeShader is\n"
|
||||
"designed to modify stroke attributes such as thickness, color,\n"
|
||||
"geometry, texture, blending mode, and so on. The basic way for this\n"
|
||||
"operation is to iterate over the stroke vertices of the :class:`Stroke`\n"
|
||||
"and to modify the :class:`StrokeAttribute` of each vertex. Here is a\n"
|
||||
"code example of such an iteration::\n"
|
||||
"\n"
|
||||
" it = ioStroke.strokeVerticesBegin()\n"
|
||||
" while not it.is_end:\n"
|
||||
" att = it.object.attribute\n"
|
||||
" ## perform here any attribute modification\n"
|
||||
" it.increment()\n"
|
||||
"\n"
|
||||
".. method:: __init__()\n"
|
||||
"\n"
|
||||
" Default constructor.\n");
|
||||
static int StrokeShader___init__(BPy_StrokeShader *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->ss = new StrokeShader();
|
||||
self->ss->py_ss = (PyObject *)self;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void StrokeShader___dealloc__(BPy_StrokeShader *self)
|
||||
{
|
||||
delete self->ss;
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *StrokeShader___repr__(BPy_StrokeShader *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("type: %s - address: %p", Py_TYPE(self)->tp_name, self->ss);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeShader_shade___doc__,
|
||||
".. method:: shade(stroke)\n"
|
||||
"\n"
|
||||
" The shading method. Must be overloaded by inherited classes.\n"
|
||||
"\n"
|
||||
" :param stroke: A Stroke object.\n"
|
||||
" :type stroke: :class:`Stroke`\n");
|
||||
static PyObject *StrokeShader_shade(BPy_StrokeShader *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"stroke", nullptr};
|
||||
PyObject *py_s = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &Stroke_Type, &py_s)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (typeid(*(self->ss)) == typeid(StrokeShader)) {
|
||||
PyErr_SetString(PyExc_TypeError, "shade method not properly overridden");
|
||||
return nullptr;
|
||||
}
|
||||
if (self->ss->shade(*(((BPy_Stroke *)py_s)->s)) < 0) {
|
||||
if (!PyErr_Occurred()) {
|
||||
string class_name(Py_TYPE(self)->tp_name);
|
||||
PyErr_SetString(PyExc_RuntimeError, (class_name + " shade method failed").c_str());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_StrokeShader_methods[] = {
|
||||
{"shade",
|
||||
(PyCFunction)StrokeShader_shade,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
StrokeShader_shade___doc__},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------StrokeShader get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeShader_name_doc,
|
||||
"The name of the stroke shader.\n"
|
||||
"\n"
|
||||
":type: str\n");
|
||||
static PyObject *StrokeShader_name_get(BPy_StrokeShader *self, void * /*closure*/)
|
||||
{
|
||||
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_StrokeShader_getseters[] = {
|
||||
{"name", (getter)StrokeShader_name_get, (setter) nullptr, StrokeShader_name_doc, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_StrokeShader type definition ------------------------------*/
|
||||
|
||||
PyTypeObject StrokeShader_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "StrokeShader",
|
||||
/*tp_basicsize*/ sizeof(BPy_StrokeShader),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)StrokeShader___dealloc__,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)StrokeShader___repr__,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ StrokeShader___doc__,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_StrokeShader_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_StrokeShader_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)StrokeShader___init__,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,36 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../system/FreestyleConfig.h"
|
||||
|
||||
#include "../stroke/StrokeShader.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject StrokeShader_Type;
|
||||
|
||||
#define BPy_StrokeShader_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&StrokeShader_Type))
|
||||
|
||||
/*---------------------------Python BPy_StrokeShader structure definition----------*/
|
||||
struct BPy_StrokeShader {
|
||||
PyObject_HEAD
|
||||
Freestyle::StrokeShader *ss;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_StrokeShader visible prototypes-----------*/
|
||||
|
||||
int StrokeShader_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,150 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_UnaryFunction0D.h"
|
||||
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DDouble.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DFloat.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DId.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DMaterial.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DVec2f.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DVec3f.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DViewShape.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int UnaryFunction0D_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&UnaryFunction0D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "UnaryFunction0D", (PyObject *)&UnaryFunction0D_Type);
|
||||
|
||||
UnaryFunction0DDouble_Init(module);
|
||||
UnaryFunction0DEdgeNature_Init(module);
|
||||
UnaryFunction0DFloat_Init(module);
|
||||
UnaryFunction0DId_Init(module);
|
||||
UnaryFunction0DMaterial_Init(module);
|
||||
UnaryFunction0DUnsigned_Init(module);
|
||||
UnaryFunction0DVec2f_Init(module);
|
||||
UnaryFunction0DVec3f_Init(module);
|
||||
UnaryFunction0DVectorViewShape_Init(module);
|
||||
UnaryFunction0DViewShape_Init(module);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
UnaryFunction0D___doc__,
|
||||
"Base class for Unary Functions (functors) working on\n"
|
||||
":class:`Interface0DIterator`. A unary function will be used by\n"
|
||||
"invoking __call__() on an Interface0DIterator. In Python, several\n"
|
||||
"different subclasses of UnaryFunction0D are used depending on the\n"
|
||||
"types of functors' return values. For example, you would inherit from\n"
|
||||
"a :class:`UnaryFunction0DDouble` if you wish to define a function that\n"
|
||||
"returns a double value. Available UnaryFunction0D subclasses are:\n"
|
||||
"\n"
|
||||
"* :class:`UnaryFunction0DDouble`\n"
|
||||
"* :class:`UnaryFunction0DEdgeNature`\n"
|
||||
"* :class:`UnaryFunction0DFloat`\n"
|
||||
"* :class:`UnaryFunction0DId`\n"
|
||||
"* :class:`UnaryFunction0DMaterial`\n"
|
||||
"* :class:`UnaryFunction0DUnsigned`\n"
|
||||
"* :class:`UnaryFunction0DVec2f`\n"
|
||||
"* :class:`UnaryFunction0DVec3f`\n"
|
||||
"* :class:`UnaryFunction0DVectorViewShape`\n"
|
||||
"* :class:`UnaryFunction0DViewShape`\n");
|
||||
static void UnaryFunction0D___dealloc__(BPy_UnaryFunction0D *self)
|
||||
{
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *UnaryFunction0D___repr__(BPy_UnaryFunction0D * /*self*/)
|
||||
{
|
||||
return PyUnicode_FromString("UnaryFunction0D");
|
||||
}
|
||||
|
||||
/*----------------------UnaryFunction0D get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
UnaryFunction0D_name_doc,
|
||||
"The name of the unary 0D function.\n"
|
||||
"\n"
|
||||
":type: str\n");
|
||||
static PyObject *UnaryFunction0D_name_get(BPy_UnaryFunction0D *self, void * /*closure*/)
|
||||
{
|
||||
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_UnaryFunction0D_getseters[] = {
|
||||
{"name",
|
||||
(getter)UnaryFunction0D_name_get,
|
||||
(setter) nullptr,
|
||||
UnaryFunction0D_name_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_UnaryFunction0D type definition ------------------------------*/
|
||||
|
||||
PyTypeObject UnaryFunction0D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "UnaryFunction0D",
|
||||
/*tp_basicsize*/ sizeof(BPy_UnaryFunction0D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)UnaryFunction0D___dealloc__,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)UnaryFunction0D___repr__,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ UnaryFunction0D___doc__,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_UnaryFunction0D_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ nullptr,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,34 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../view_map/Functions0D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject UnaryFunction0D_Type;
|
||||
|
||||
#define BPy_UnaryFunction0D_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryFunction0D_Type))
|
||||
|
||||
/*---------------------------Python BPy_UnaryFunction0D structure definition----------*/
|
||||
struct BPy_UnaryFunction0D {
|
||||
PyObject_HEAD
|
||||
PyObject *py_uf0D;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_UnaryFunction0D visible prototypes-----------*/
|
||||
|
||||
int UnaryFunction0D_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,144 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_UnaryFunction1D.h"
|
||||
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DDouble.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DFloat.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DVec2f.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DVec3f.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DVoid.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int UnaryFunction1D_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&UnaryFunction1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "UnaryFunction1D", (PyObject *)&UnaryFunction1D_Type);
|
||||
|
||||
UnaryFunction1DDouble_Init(module);
|
||||
UnaryFunction1DEdgeNature_Init(module);
|
||||
UnaryFunction1DFloat_Init(module);
|
||||
UnaryFunction1DUnsigned_Init(module);
|
||||
UnaryFunction1DVec2f_Init(module);
|
||||
UnaryFunction1DVec3f_Init(module);
|
||||
UnaryFunction1DVectorViewShape_Init(module);
|
||||
UnaryFunction1DVoid_Init(module);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
UnaryFunction1D___doc__,
|
||||
"Base class for Unary Functions (functors) working on\n"
|
||||
":class:`Interface1D`. A unary function will be used by invoking\n"
|
||||
"__call__() on an Interface1D. In Python, several different subclasses\n"
|
||||
"of UnaryFunction1D are used depending on the types of functors' return\n"
|
||||
"values. For example, you would inherit from a\n"
|
||||
":class:`UnaryFunction1DDouble` if you wish to define a function that\n"
|
||||
"returns a double value. Available UnaryFunction1D subclasses are:\n"
|
||||
"\n"
|
||||
"* :class:`UnaryFunction1DDouble`\n"
|
||||
"* :class:`UnaryFunction1DEdgeNature`\n"
|
||||
"* :class:`UnaryFunction1DFloat`\n"
|
||||
"* :class:`UnaryFunction1DUnsigned`\n"
|
||||
"* :class:`UnaryFunction1DVec2f`\n"
|
||||
"* :class:`UnaryFunction1DVec3f`\n"
|
||||
"* :class:`UnaryFunction1DVectorViewShape`\n"
|
||||
"* :class:`UnaryFunction1DVoid`\n");
|
||||
static void UnaryFunction1D___dealloc__(BPy_UnaryFunction1D *self)
|
||||
{
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *UnaryFunction1D___repr__(BPy_UnaryFunction1D * /*self*/)
|
||||
{
|
||||
return PyUnicode_FromString("UnaryFunction1D");
|
||||
}
|
||||
|
||||
/*----------------------UnaryFunction1D get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
UnaryFunction1D_name_doc,
|
||||
"The name of the unary 1D function.\n"
|
||||
"\n"
|
||||
":type: str\n");
|
||||
static PyObject *UnaryFunction1D_name_get(BPy_UnaryFunction1D *self, void * /*closure*/)
|
||||
{
|
||||
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_UnaryFunction1D_getseters[] = {
|
||||
{"name",
|
||||
(getter)UnaryFunction1D_name_get,
|
||||
(setter) nullptr,
|
||||
UnaryFunction1D_name_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_UnaryFunction1D type definition ------------------------------*/
|
||||
|
||||
PyTypeObject UnaryFunction1D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "UnaryFunction1D",
|
||||
/*tp_basicsize*/ sizeof(BPy_UnaryFunction1D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)UnaryFunction1D___dealloc__,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)UnaryFunction1D___repr__,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ UnaryFunction1D___doc__,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_UnaryFunction1D_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ nullptr,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,34 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../view_map/Functions1D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject UnaryFunction1D_Type;
|
||||
|
||||
#define BPy_UnaryFunction1D_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryFunction1D_Type))
|
||||
|
||||
/*---------------------------Python BPy_UnaryFunction1D structure definition----------*/
|
||||
struct BPy_UnaryFunction1D {
|
||||
PyObject_HEAD
|
||||
PyObject *py_uf1D;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_UnaryFunction1D visible prototypes-----------*/
|
||||
|
||||
int UnaryFunction1D_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,192 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_UnaryPredicate0D.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
#include "Iterator/BPy_Interface0DIterator.h"
|
||||
#include "UnaryPredicate0D/BPy_FalseUP0D.h"
|
||||
#include "UnaryPredicate0D/BPy_TrueUP0D.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int UnaryPredicate0D_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&UnaryPredicate0D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "UnaryPredicate0D", (PyObject *)&UnaryPredicate0D_Type);
|
||||
|
||||
if (PyType_Ready(&FalseUP0D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "FalseUP0D", (PyObject *)&FalseUP0D_Type);
|
||||
|
||||
if (PyType_Ready(&TrueUP0D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "TrueUP0D", (PyObject *)&TrueUP0D_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
UnaryPredicate0D___doc__,
|
||||
"Base class for unary predicates that work on\n"
|
||||
":class:`Interface0DIterator`. A UnaryPredicate0D is a functor that\n"
|
||||
"evaluates a condition on an Interface0DIterator and returns true or\n"
|
||||
"false depending on whether this condition is satisfied or not. The\n"
|
||||
"UnaryPredicate0D is used by invoking its __call__() method. Any\n"
|
||||
"inherited class must overload the __call__() method.\n"
|
||||
"\n"
|
||||
".. method:: __init__()\n"
|
||||
"\n"
|
||||
" Default constructor.\n"
|
||||
"\n"
|
||||
".. method:: __call__(it)\n"
|
||||
"\n"
|
||||
" Must be overload by inherited classes.\n"
|
||||
"\n"
|
||||
" :param it: The Interface0DIterator pointing onto the Interface0D at\n"
|
||||
" which we wish to evaluate the predicate.\n"
|
||||
" :type it: :class:`Interface0DIterator`\n"
|
||||
" :return: True if the condition is satisfied, false otherwise.\n"
|
||||
" :rtype: bool\n");
|
||||
static int UnaryPredicate0D___init__(BPy_UnaryPredicate0D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->up0D = new UnaryPredicate0D();
|
||||
self->up0D->py_up0D = (PyObject *)self;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void UnaryPredicate0D___dealloc__(BPy_UnaryPredicate0D *self)
|
||||
{
|
||||
delete self->up0D;
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *UnaryPredicate0D___repr__(BPy_UnaryPredicate0D *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("type: %s - address: %p", Py_TYPE(self)->tp_name, self->up0D);
|
||||
}
|
||||
|
||||
static PyObject *UnaryPredicate0D___call__(BPy_UnaryPredicate0D *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"it", nullptr};
|
||||
PyObject *py_if0D_it;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!", (char **)kwlist, &Interface0DIterator_Type, &py_if0D_it))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Interface0DIterator *if0D_it = ((BPy_Interface0DIterator *)py_if0D_it)->if0D_it;
|
||||
|
||||
if (!if0D_it) {
|
||||
string class_name(Py_TYPE(self)->tp_name);
|
||||
PyErr_SetString(PyExc_RuntimeError, (class_name + " has no Interface0DIterator").c_str());
|
||||
return nullptr;
|
||||
}
|
||||
if (typeid(*(self->up0D)) == typeid(UnaryPredicate0D)) {
|
||||
PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden");
|
||||
return nullptr;
|
||||
}
|
||||
if (self->up0D->operator()(*if0D_it) < 0) {
|
||||
if (!PyErr_Occurred()) {
|
||||
string class_name(Py_TYPE(self)->tp_name);
|
||||
PyErr_SetString(PyExc_RuntimeError, (class_name + " __call__ method failed").c_str());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return PyBool_from_bool(self->up0D->result);
|
||||
}
|
||||
|
||||
/*----------------------UnaryPredicate0D get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
UnaryPredicate0D_name_doc,
|
||||
"The name of the unary 0D predicate.\n"
|
||||
"\n"
|
||||
":type: str\n");
|
||||
static PyObject *UnaryPredicate0D_name_get(BPy_UnaryPredicate0D *self, void * /*closure*/)
|
||||
{
|
||||
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_UnaryPredicate0D_getseters[] = {
|
||||
{"name",
|
||||
(getter)UnaryPredicate0D_name_get,
|
||||
(setter) nullptr,
|
||||
UnaryPredicate0D_name_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_UnaryPredicate0D type definition ------------------------------*/
|
||||
|
||||
PyTypeObject UnaryPredicate0D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "UnaryPredicate0D",
|
||||
/*tp_basicsize*/ sizeof(BPy_UnaryPredicate0D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)UnaryPredicate0D___dealloc__,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)UnaryPredicate0D___repr__,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ (ternaryfunc)UnaryPredicate0D___call__,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ UnaryPredicate0D___doc__,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_UnaryPredicate0D_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)UnaryPredicate0D___init__,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,34 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../stroke/Predicates0D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject UnaryPredicate0D_Type;
|
||||
|
||||
#define BPy_UnaryPredicate0D_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryPredicate0D_Type))
|
||||
|
||||
/*---------------------------Python BPy_UnaryPredicate0D structure definition----------*/
|
||||
struct BPy_UnaryPredicate0D {
|
||||
PyObject_HEAD
|
||||
Freestyle::UnaryPredicate0D *up0D;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_UnaryPredicate0D visible prototypes-----------*/
|
||||
|
||||
int UnaryPredicate0D_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,242 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_UnaryPredicate1D.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
#include "BPy_Interface1D.h"
|
||||
|
||||
#include "UnaryPredicate1D/BPy_ContourUP1D.h"
|
||||
#include "UnaryPredicate1D/BPy_DensityLowerThanUP1D.h"
|
||||
#include "UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.h"
|
||||
#include "UnaryPredicate1D/BPy_EqualToTimeStampUP1D.h"
|
||||
#include "UnaryPredicate1D/BPy_ExternalContourUP1D.h"
|
||||
#include "UnaryPredicate1D/BPy_FalseUP1D.h"
|
||||
#include "UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.h"
|
||||
#include "UnaryPredicate1D/BPy_ShapeUP1D.h"
|
||||
#include "UnaryPredicate1D/BPy_TrueUP1D.h"
|
||||
#include "UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int UnaryPredicate1D_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&UnaryPredicate1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "UnaryPredicate1D", (PyObject *)&UnaryPredicate1D_Type);
|
||||
|
||||
if (PyType_Ready(&ContourUP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ContourUP1D", (PyObject *)&ContourUP1D_Type);
|
||||
|
||||
if (PyType_Ready(&DensityLowerThanUP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "DensityLowerThanUP1D", (PyObject *)&DensityLowerThanUP1D_Type);
|
||||
|
||||
if (PyType_Ready(&EqualToChainingTimeStampUP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(
|
||||
module, "EqualToChainingTimeStampUP1D", (PyObject *)&EqualToChainingTimeStampUP1D_Type);
|
||||
|
||||
if (PyType_Ready(&EqualToTimeStampUP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "EqualToTimeStampUP1D", (PyObject *)&EqualToTimeStampUP1D_Type);
|
||||
|
||||
if (PyType_Ready(&ExternalContourUP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ExternalContourUP1D", (PyObject *)&ExternalContourUP1D_Type);
|
||||
|
||||
if (PyType_Ready(&FalseUP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "FalseUP1D", (PyObject *)&FalseUP1D_Type);
|
||||
|
||||
if (PyType_Ready(&QuantitativeInvisibilityUP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(
|
||||
module, "QuantitativeInvisibilityUP1D", (PyObject *)&QuantitativeInvisibilityUP1D_Type);
|
||||
|
||||
if (PyType_Ready(&ShapeUP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ShapeUP1D", (PyObject *)&ShapeUP1D_Type);
|
||||
|
||||
if (PyType_Ready(&TrueUP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "TrueUP1D", (PyObject *)&TrueUP1D_Type);
|
||||
|
||||
if (PyType_Ready(&WithinImageBoundaryUP1D_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(
|
||||
module, "WithinImageBoundaryUP1D", (PyObject *)&WithinImageBoundaryUP1D_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
UnaryPredicate1D___doc__,
|
||||
"Base class for unary predicates that work on :class:`Interface1D`. A\n"
|
||||
"UnaryPredicate1D is a functor that evaluates a condition on a\n"
|
||||
"Interface1D and returns true or false depending on whether this\n"
|
||||
"condition is satisfied or not. The UnaryPredicate1D is used by\n"
|
||||
"invoking its __call__() method. Any inherited class must overload the\n"
|
||||
"__call__() method.\n"
|
||||
"\n"
|
||||
".. method:: __init__()\n"
|
||||
"\n"
|
||||
" Default constructor.\n"
|
||||
"\n"
|
||||
".. method:: __call__(inter)\n"
|
||||
"\n"
|
||||
" Must be overload by inherited classes.\n"
|
||||
"\n"
|
||||
" :param inter: The Interface1D on which we wish to evaluate the predicate.\n"
|
||||
" :type inter: :class:`Interface1D`\n"
|
||||
" :return: True if the condition is satisfied, false otherwise.\n"
|
||||
" :rtype: bool\n");
|
||||
static int UnaryPredicate1D___init__(BPy_UnaryPredicate1D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->up1D = new UnaryPredicate1D();
|
||||
self->up1D->py_up1D = (PyObject *)self;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void UnaryPredicate1D___dealloc__(BPy_UnaryPredicate1D *self)
|
||||
{
|
||||
delete self->up1D;
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *UnaryPredicate1D___repr__(BPy_UnaryPredicate1D *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("type: %s - address: %p", Py_TYPE(self)->tp_name, self->up1D);
|
||||
}
|
||||
|
||||
static PyObject *UnaryPredicate1D___call__(BPy_UnaryPredicate1D *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"inter", nullptr};
|
||||
PyObject *py_if1D;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &Interface1D_Type, &py_if1D))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Interface1D *if1D = ((BPy_Interface1D *)py_if1D)->if1D;
|
||||
|
||||
if (!if1D) {
|
||||
string class_name(Py_TYPE(self)->tp_name);
|
||||
PyErr_SetString(PyExc_RuntimeError, (class_name + " has no Interface1D").c_str());
|
||||
return nullptr;
|
||||
}
|
||||
if (typeid(*(self->up1D)) == typeid(UnaryPredicate1D)) {
|
||||
PyErr_SetString(PyExc_TypeError, "__call__ method not properly overridden");
|
||||
return nullptr;
|
||||
}
|
||||
if (self->up1D->operator()(*if1D) < 0) {
|
||||
if (!PyErr_Occurred()) {
|
||||
string class_name(Py_TYPE(self)->tp_name);
|
||||
PyErr_SetString(PyExc_RuntimeError, (class_name + " __call__ method failed").c_str());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return PyBool_from_bool(self->up1D->result);
|
||||
}
|
||||
|
||||
/*----------------------UnaryPredicate1D get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
UnaryPredicate1D_name_doc,
|
||||
"The name of the unary 1D predicate.\n"
|
||||
"\n"
|
||||
":type: str\n");
|
||||
static PyObject *UnaryPredicate1D_name_get(BPy_UnaryPredicate1D *self, void * /*closure*/)
|
||||
{
|
||||
return PyUnicode_FromString(Py_TYPE(self)->tp_name);
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_UnaryPredicate1D_getseters[] = {
|
||||
{"name",
|
||||
(getter)UnaryPredicate1D_name_get,
|
||||
(setter) nullptr,
|
||||
UnaryPredicate1D_name_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_UnaryPredicate1D type definition ------------------------------*/
|
||||
|
||||
PyTypeObject UnaryPredicate1D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "UnaryPredicate1D",
|
||||
/*tp_basicsize*/ sizeof(BPy_UnaryPredicate1D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)UnaryPredicate1D___dealloc__,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)UnaryPredicate1D___repr__,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ (ternaryfunc)UnaryPredicate1D___call__,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ UnaryPredicate1D___doc__,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_UnaryPredicate1D_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)UnaryPredicate1D___init__,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,34 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../stroke/Predicates1D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject UnaryPredicate1D_Type;
|
||||
|
||||
#define BPy_UnaryPredicate1D_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&UnaryPredicate1D_Type))
|
||||
|
||||
/*---------------------------Python BPy_UnaryPredicate1D structure definition----------*/
|
||||
struct BPy_UnaryPredicate1D {
|
||||
PyObject_HEAD
|
||||
Freestyle::UnaryPredicate1D *up1D;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_UnaryPredicate1D visible prototypes-----------*/
|
||||
|
||||
int UnaryPredicate1D_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,230 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_ViewMap.h"
|
||||
|
||||
#include "BPy_BBox.h"
|
||||
#include "BPy_Convert.h"
|
||||
#include "Interface1D/BPy_FEdge.h"
|
||||
#include "Interface1D/BPy_ViewEdge.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
int ViewMap_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&ViewMap_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ViewMap", (PyObject *)&ViewMap_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------ViewMap methods----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewMap_doc,
|
||||
"Class defining the ViewMap.\n"
|
||||
"\n"
|
||||
".. method:: __init__()\n"
|
||||
"\n"
|
||||
" Default constructor.\n");
|
||||
static int ViewMap_init(BPy_ViewMap *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->vm = new ViewMap();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ViewMap_dealloc(BPy_ViewMap *self)
|
||||
{
|
||||
delete self->vm;
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *ViewMap_repr(BPy_ViewMap *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("ViewMap - address: %p", self->vm);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewMap_get_closest_viewedge_doc,
|
||||
".. method:: get_closest_viewedge(x, y)\n"
|
||||
"\n"
|
||||
" Gets the ViewEdge nearest to the 2D point specified as arguments.\n"
|
||||
"\n"
|
||||
" :param x: X coordinate of a 2D point.\n"
|
||||
" :type x: float\n"
|
||||
" :param y: Y coordinate of a 2D point.\n"
|
||||
" :type y: float\n"
|
||||
" :return: The ViewEdge nearest to the specified 2D point.\n"
|
||||
" :rtype: :class:`ViewEdge`\n");
|
||||
static PyObject *ViewMap_get_closest_viewedge(BPy_ViewMap *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"x", "y", nullptr};
|
||||
double x, y;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "dd", (char **)kwlist, &x, &y)) {
|
||||
return nullptr;
|
||||
}
|
||||
ViewEdge *ve = const_cast<ViewEdge *>(self->vm->getClosestViewEdge(x, y));
|
||||
if (ve) {
|
||||
return BPy_ViewEdge_from_ViewEdge(*ve);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewMap_get_closest_fedge_doc,
|
||||
".. method:: get_closest_fedge(x, y)\n"
|
||||
"\n"
|
||||
" Gets the FEdge nearest to the 2D point specified as arguments.\n"
|
||||
"\n"
|
||||
" :param x: X coordinate of a 2D point.\n"
|
||||
" :type x: float\n"
|
||||
" :param y: Y coordinate of a 2D point.\n"
|
||||
" :type y: float\n"
|
||||
" :return: The FEdge nearest to the specified 2D point.\n"
|
||||
" :rtype: :class:`FEdge`\n");
|
||||
static PyObject *ViewMap_get_closest_fedge(BPy_ViewMap *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"x", "y", nullptr};
|
||||
double x, y;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "dd", (char **)kwlist, &x, &y)) {
|
||||
return nullptr;
|
||||
}
|
||||
FEdge *fe = const_cast<FEdge *>(self->vm->getClosestFEdge(x, y));
|
||||
if (fe) {
|
||||
return Any_BPy_FEdge_from_FEdge(*fe);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
// static ViewMap *getInstance ();
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_ViewMap_methods[] = {
|
||||
{"get_closest_viewedge",
|
||||
(PyCFunction)ViewMap_get_closest_viewedge,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
ViewMap_get_closest_viewedge_doc},
|
||||
{"get_closest_fedge",
|
||||
(PyCFunction)ViewMap_get_closest_fedge,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
ViewMap_get_closest_fedge_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------ViewMap get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewMap_scene_bbox_doc,
|
||||
"The 3D bounding box of the scene.\n"
|
||||
"\n"
|
||||
":type: :class:`BBox`\n");
|
||||
static PyObject *ViewMap_scene_bbox_get(BPy_ViewMap *self, void * /*closure*/)
|
||||
{
|
||||
return BPy_BBox_from_BBox(self->vm->getScene3dBBox());
|
||||
}
|
||||
|
||||
static int ViewMap_scene_bbox_set(BPy_ViewMap *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_BBox_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a BBox");
|
||||
return -1;
|
||||
}
|
||||
self->vm->setScene3dBBox(*(((BPy_BBox *)value)->bb));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_ViewMap_getseters[] = {
|
||||
{"scene_bbox",
|
||||
(getter)ViewMap_scene_bbox_get,
|
||||
(setter)ViewMap_scene_bbox_set,
|
||||
ViewMap_scene_bbox_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_ViewMap type definition ------------------------------*/
|
||||
|
||||
PyTypeObject ViewMap_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "ViewMap",
|
||||
/*tp_basicsize*/ sizeof(BPy_ViewMap),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)ViewMap_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)ViewMap_repr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ ViewMap_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_ViewMap_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_ViewMap_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)ViewMap_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,33 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../view_map/ViewMap.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject ViewMap_Type;
|
||||
|
||||
#define BPy_ViewMap_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ViewMap_Type))
|
||||
|
||||
/*---------------------------Python BPy_ViewMap structure definition----------*/
|
||||
struct BPy_ViewMap {
|
||||
PyObject_HEAD
|
||||
Freestyle::ViewMap *vm;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_ViewMap visible prototypes-----------*/
|
||||
|
||||
int ViewMap_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,413 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_ViewShape.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
#include "BPy_SShape.h"
|
||||
#include "Interface0D/BPy_ViewVertex.h"
|
||||
#include "Interface1D/BPy_ViewEdge.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
#include "../generic/py_capi_utils.hh"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------MODULE INITIALIZATION--------------------------------
|
||||
|
||||
int ViewShape_Init(PyObject *module)
|
||||
{
|
||||
if (module == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (PyType_Ready(&ViewShape_Type) < 0) {
|
||||
return -1;
|
||||
}
|
||||
PyModule_AddObjectRef(module, "ViewShape", (PyObject *)&ViewShape_Type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------ViewShape methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewShape_doc,
|
||||
"Class gathering the elements of the ViewMap (i.e., :class:`ViewVertex`\n"
|
||||
"and :class:`ViewEdge`) that are issued from the same input shape.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(sshape)``\n"
|
||||
"\n"
|
||||
" Builds a :class:`ViewShape` using the default constructor,\n"
|
||||
" copy constructor, or from a :class:`SShape`.\n"
|
||||
"\n"
|
||||
" :param brother: A ViewShape object.\n"
|
||||
" :type brother: :class:`ViewShape`\n"
|
||||
" :param sshape: An SShape object.\n"
|
||||
" :type sshape: :class:`SShape`\n");
|
||||
static int ViewShape_init(BPy_ViewShape *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"sshape", nullptr};
|
||||
PyObject *obj = nullptr;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &ViewShape_Type, &obj)) {
|
||||
if (!obj) {
|
||||
self->vs = new ViewShape();
|
||||
self->py_ss = nullptr;
|
||||
}
|
||||
else {
|
||||
self->vs = new ViewShape(*(((BPy_ViewShape *)obj)->vs));
|
||||
self->py_ss = ((BPy_ViewShape *)obj)->py_ss;
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_2, &SShape_Type, &obj))
|
||||
{
|
||||
BPy_SShape *py_ss = (BPy_SShape *)obj;
|
||||
self->vs = new ViewShape(py_ss->ss);
|
||||
self->py_ss = (!py_ss->borrowed) ? py_ss : nullptr;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->borrowed = false;
|
||||
Py_XINCREF(self->py_ss);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ViewShape_dealloc(BPy_ViewShape *self)
|
||||
{
|
||||
if (self->py_ss) {
|
||||
self->vs->setSShape((SShape *)nullptr);
|
||||
Py_DECREF(self->py_ss);
|
||||
}
|
||||
if (self->vs && !self->borrowed) {
|
||||
delete self->vs;
|
||||
}
|
||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||
}
|
||||
|
||||
static PyObject *ViewShape_repr(BPy_ViewShape *self)
|
||||
{
|
||||
return PyUnicode_FromFormat("ViewShape - address: %p", self->vs);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewShape_add_edge_doc,
|
||||
".. method:: add_edge(edge)\n"
|
||||
"\n"
|
||||
" Adds a ViewEdge to the list of ViewEdge objects.\n"
|
||||
"\n"
|
||||
" :param edge: A ViewEdge object.\n"
|
||||
" :type edge: :class:`ViewEdge`\n");
|
||||
static PyObject *ViewShape_add_edge(BPy_ViewShape *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"edge", nullptr};
|
||||
PyObject *py_ve = nullptr;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &ViewEdge_Type, &py_ve)) {
|
||||
return nullptr;
|
||||
}
|
||||
self->vs->AddEdge(((BPy_ViewEdge *)py_ve)->ve);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewShape_add_vertex_doc,
|
||||
".. method:: add_vertex(vertex)\n"
|
||||
"\n"
|
||||
" Adds a ViewVertex to the list of the ViewVertex objects.\n"
|
||||
"\n"
|
||||
" :param vertex: A ViewVertex object.\n"
|
||||
" :type vertex: :class:`ViewVertex`\n");
|
||||
static PyObject *ViewShape_add_vertex(BPy_ViewShape *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"vertex", nullptr};
|
||||
PyObject *py_vv = nullptr;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &ViewVertex_Type, &py_vv)) {
|
||||
return nullptr;
|
||||
}
|
||||
self->vs->AddVertex(((BPy_ViewVertex *)py_vv)->vv);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
// virtual ViewShape *duplicate()
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_ViewShape_methods[] = {
|
||||
{"add_edge",
|
||||
(PyCFunction)ViewShape_add_edge,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
ViewShape_add_edge_doc},
|
||||
{"add_vertex",
|
||||
(PyCFunction)ViewShape_add_vertex,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
ViewShape_add_vertex_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------ViewShape get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewShape_sshape_doc,
|
||||
"The SShape on top of which this ViewShape is built.\n"
|
||||
"\n"
|
||||
":type: :class:`SShape`\n");
|
||||
static PyObject *ViewShape_sshape_get(BPy_ViewShape *self, void * /*closure*/)
|
||||
{
|
||||
SShape *ss = self->vs->sshape();
|
||||
if (!ss) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
return BPy_SShape_from_SShape(*ss);
|
||||
}
|
||||
|
||||
static int ViewShape_sshape_set(BPy_ViewShape *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_SShape_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an SShape");
|
||||
return -1;
|
||||
}
|
||||
BPy_SShape *py_ss = (BPy_SShape *)value;
|
||||
self->vs->setSShape(py_ss->ss);
|
||||
if (self->py_ss) {
|
||||
Py_DECREF(self->py_ss);
|
||||
}
|
||||
if (!py_ss->borrowed) {
|
||||
self->py_ss = py_ss;
|
||||
Py_INCREF(self->py_ss);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewShape_vertices_doc,
|
||||
"The list of ViewVertex objects contained in this ViewShape.\n"
|
||||
"\n"
|
||||
":type: list[:class:`ViewVertex`]\n");
|
||||
static PyObject *ViewShape_vertices_get(BPy_ViewShape *self, void * /*closure*/)
|
||||
{
|
||||
vector<ViewVertex *> vertices = self->vs->vertices();
|
||||
vector<ViewVertex *>::iterator it;
|
||||
PyObject *py_vertices = PyList_New(vertices.size());
|
||||
uint i = 0;
|
||||
|
||||
for (it = vertices.begin(); it != vertices.end(); it++) {
|
||||
PyList_SET_ITEM(py_vertices, i++, Any_BPy_ViewVertex_from_ViewVertex(*(*it)));
|
||||
}
|
||||
return py_vertices;
|
||||
}
|
||||
|
||||
static int ViewShape_vertices_set(BPy_ViewShape *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
PyObject *item;
|
||||
vector<ViewVertex *> v;
|
||||
|
||||
if (!PyList_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a list of ViewVertex objects");
|
||||
return -1;
|
||||
}
|
||||
|
||||
v.reserve(PyList_GET_SIZE(value));
|
||||
for (uint i = 0; i < PyList_GET_SIZE(value); i++) {
|
||||
item = PyList_GET_ITEM(value, i);
|
||||
if (BPy_ViewVertex_Check(item)) {
|
||||
v.push_back(((BPy_ViewVertex *)item)->vv);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a list of ViewVertex objects");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
self->vs->setVertices(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewShape_edges_doc,
|
||||
"The list of ViewEdge objects contained in this ViewShape.\n"
|
||||
"\n"
|
||||
":type: list[:class:`ViewEdge`]\n");
|
||||
static PyObject *ViewShape_edges_get(BPy_ViewShape *self, void * /*closure*/)
|
||||
{
|
||||
vector<ViewEdge *> edges = self->vs->edges();
|
||||
vector<ViewEdge *>::iterator it;
|
||||
PyObject *py_edges = PyList_New(edges.size());
|
||||
uint i = 0;
|
||||
|
||||
for (it = edges.begin(); it != edges.end(); it++) {
|
||||
PyList_SET_ITEM(py_edges, i++, BPy_ViewEdge_from_ViewEdge(*(*it)));
|
||||
}
|
||||
return py_edges;
|
||||
}
|
||||
|
||||
static int ViewShape_edges_set(BPy_ViewShape *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
PyObject *item;
|
||||
vector<ViewEdge *> v;
|
||||
|
||||
if (!PyList_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a list of ViewEdge objects");
|
||||
return -1;
|
||||
}
|
||||
|
||||
v.reserve(PyList_GET_SIZE(value));
|
||||
for (int i = 0; i < PyList_GET_SIZE(value); i++) {
|
||||
item = PyList_GET_ITEM(value, i);
|
||||
if (BPy_ViewEdge_Check(item)) {
|
||||
v.push_back(((BPy_ViewEdge *)item)->ve);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "argument must be list of ViewEdge objects");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
self->vs->setEdges(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewShape_name_doc,
|
||||
"The name of the ViewShape.\n"
|
||||
"\n"
|
||||
":type: str\n");
|
||||
static PyObject *ViewShape_name_get(BPy_ViewShape *self, void * /*closure*/)
|
||||
{
|
||||
return blender::PyC_UnicodeFromStdStr(self->vs->getName());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewShape_library_path_doc,
|
||||
"The library path of the ViewShape, or None if the ViewShape is not part of\n"
|
||||
"a library.\n"
|
||||
"\n"
|
||||
":type: str | None\n");
|
||||
static PyObject *ViewShape_library_path_get(BPy_ViewShape *self, void * /*closure*/)
|
||||
{
|
||||
return blender::PyC_UnicodeFromStdStr(self->vs->getLibraryPath());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewShape_id_doc,
|
||||
"The Id of this ViewShape.\n"
|
||||
"\n"
|
||||
":type: :class:`Id`\n");
|
||||
static PyObject *ViewShape_id_get(BPy_ViewShape *self, void * /*closure*/)
|
||||
{
|
||||
Id id(self->vs->getId());
|
||||
return BPy_Id_from_Id(id); // return a copy
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_ViewShape_getseters[] = {
|
||||
{"sshape",
|
||||
(getter)ViewShape_sshape_get,
|
||||
(setter)ViewShape_sshape_set,
|
||||
ViewShape_sshape_doc,
|
||||
nullptr},
|
||||
{"vertices",
|
||||
(getter)ViewShape_vertices_get,
|
||||
(setter)ViewShape_vertices_set,
|
||||
ViewShape_vertices_doc,
|
||||
nullptr},
|
||||
{"edges",
|
||||
(getter)ViewShape_edges_get,
|
||||
(setter)ViewShape_edges_set,
|
||||
ViewShape_edges_doc,
|
||||
nullptr},
|
||||
{"name", (getter)ViewShape_name_get, (setter) nullptr, ViewShape_name_doc, nullptr},
|
||||
{"library_path",
|
||||
(getter)ViewShape_library_path_get,
|
||||
(setter) nullptr,
|
||||
ViewShape_library_path_doc,
|
||||
nullptr},
|
||||
{"id", (getter)ViewShape_id_get, (setter) nullptr, ViewShape_id_doc, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_ViewShape type definition ------------------------------*/
|
||||
|
||||
PyTypeObject ViewShape_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "ViewShape",
|
||||
/*tp_basicsize*/ sizeof(BPy_ViewShape),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)ViewShape_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ (reprfunc)ViewShape_repr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ ViewShape_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_ViewShape_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_ViewShape_getseters,
|
||||
/*tp_base*/ nullptr,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)ViewShape_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ PyType_GenericNew,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,37 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern "C" {
|
||||
#include <Python.h>
|
||||
}
|
||||
|
||||
#include "../view_map/ViewMap.h"
|
||||
|
||||
#include "BPy_SShape.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject ViewShape_Type;
|
||||
|
||||
#define BPy_ViewShape_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ViewShape_Type))
|
||||
|
||||
/*---------------------------Python BPy_ViewShape structure definition----------*/
|
||||
struct BPy_ViewShape {
|
||||
PyObject_HEAD
|
||||
Freestyle::ViewShape *vs;
|
||||
bool borrowed; /* true if *vs a borrowed object */
|
||||
BPy_SShape *py_ss;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_ViewShape visible prototypes-----------*/
|
||||
|
||||
int ViewShape_Init(PyObject *module);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,86 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_FalseBP1D.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FalseBP1D___doc__,
|
||||
"Class hierarchy: :class:`freestyle.types.BinaryPredicate1D` > :class:`FalseBP1D`\n"
|
||||
"\n"
|
||||
".. method:: __call__(inter1, inter2)\n"
|
||||
"\n"
|
||||
" Always returns false.\n"
|
||||
"\n"
|
||||
" :param inter1: The first Interface1D object.\n"
|
||||
" :type inter1: :class:`freestyle.types.Interface1D`\n"
|
||||
" :param inter2: The second Interface1D object.\n"
|
||||
" :type inter2: :class:`freestyle.types.Interface1D`\n"
|
||||
" :return: False.\n"
|
||||
" :rtype: bool\n");
|
||||
static int FalseBP1D___init__(BPy_FalseBP1D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->py_bp1D.bp1D = new Predicates1D::FalseBP1D();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------BPy_FalseBP1D type definition ------------------------------*/
|
||||
|
||||
PyTypeObject FalseBP1D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "FalseBP1D",
|
||||
/*tp_basicsize*/ sizeof(BPy_FalseBP1D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ FalseBP1D___doc__,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ &BinaryPredicate1D_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)FalseBP1D___init__,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,24 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_BinaryPredicate1D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject FalseBP1D_Type;
|
||||
|
||||
#define BPy_FalseBP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&FalseBP1D_Type))
|
||||
|
||||
/*---------------------------Python BPy_FalseBP1D structure definition----------*/
|
||||
struct BPy_FalseBP1D {
|
||||
BPy_BinaryPredicate1D py_bp1D;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,87 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_Length2DBP1D.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Length2DBP1D___doc__,
|
||||
"Class hierarchy: :class:`freestyle.types.BinaryPredicate1D` > :class:`Length2DBP1D`\n"
|
||||
"\n"
|
||||
".. method:: __call__(inter1, inter2)\n"
|
||||
"\n"
|
||||
" Returns true if the 2D length of inter1 is less than the 2D length\n"
|
||||
" of inter2.\n"
|
||||
"\n"
|
||||
" :param inter1: The first Interface1D object.\n"
|
||||
" :type inter1: :class:`freestyle.types.Interface1D`\n"
|
||||
" :param inter2: The second Interface1D object.\n"
|
||||
" :type inter2: :class:`freestyle.types.Interface1D`\n"
|
||||
" :return: True or false.\n"
|
||||
" :rtype: bool\n");
|
||||
static int Length2DBP1D___init__(BPy_Length2DBP1D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->py_bp1D.bp1D = new Predicates1D::Length2DBP1D();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------BPy_Length2DBP1D type definition ------------------------------*/
|
||||
|
||||
PyTypeObject Length2DBP1D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Length2DBP1D",
|
||||
/*tp_basicsize*/ sizeof(BPy_Length2DBP1D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ Length2DBP1D___doc__,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ &BinaryPredicate1D_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)Length2DBP1D___init__,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,25 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_BinaryPredicate1D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject Length2DBP1D_Type;
|
||||
|
||||
#define BPy_Length2DBP1D_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&Length2DBP1D_Type))
|
||||
|
||||
/*---------------------------Python BPy_Length2DBP1D structure definition----------*/
|
||||
struct BPy_Length2DBP1D {
|
||||
BPy_BinaryPredicate1D py_bp1D;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,86 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_SameShapeIdBP1D.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SameShapeIdBP1D___doc__,
|
||||
"Class hierarchy: :class:`freestyle.types.BinaryPredicate1D` > :class:`SameShapeIdBP1D`\n"
|
||||
"\n"
|
||||
".. method:: __call__(inter1, inter2)\n"
|
||||
"\n"
|
||||
" Returns true if inter1 and inter2 belong to the same shape.\n"
|
||||
"\n"
|
||||
" :param inter1: The first Interface1D object.\n"
|
||||
" :type inter1: :class:`freestyle.types.Interface1D`\n"
|
||||
" :param inter2: The second Interface1D object.\n"
|
||||
" :type inter2: :class:`freestyle.types.Interface1D`\n"
|
||||
" :return: True or false.\n"
|
||||
" :rtype: bool\n");
|
||||
static int SameShapeIdBP1D___init__(BPy_SameShapeIdBP1D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->py_bp1D.bp1D = new Predicates1D::SameShapeIdBP1D();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------BPy_SameShapeIdBP1D type definition ------------------------------*/
|
||||
|
||||
PyTypeObject SameShapeIdBP1D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "SameShapeIdBP1D",
|
||||
/*tp_basicsize*/ sizeof(BPy_SameShapeIdBP1D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ SameShapeIdBP1D___doc__,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ &BinaryPredicate1D_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)SameShapeIdBP1D___init__,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,25 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_BinaryPredicate1D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject SameShapeIdBP1D_Type;
|
||||
|
||||
#define BPy_SameShapeIdBP1D_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&SameShapeIdBP1D_Type))
|
||||
|
||||
/*---------------------------Python BPy_SameShapeIdBP1D structure definition----------*/
|
||||
struct BPy_SameShapeIdBP1D {
|
||||
BPy_BinaryPredicate1D py_bp1D;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,86 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_TrueBP1D.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
TrueBP1D___doc__,
|
||||
"Class hierarchy: :class:`freestyle.types.BinaryPredicate1D` > :class:`TrueBP1D`\n"
|
||||
"\n"
|
||||
".. method:: __call__(inter1, inter2)\n"
|
||||
"\n"
|
||||
" Always returns true.\n"
|
||||
"\n"
|
||||
" :param inter1: The first Interface1D object.\n"
|
||||
" :type inter1: :class:`freestyle.types.Interface1D`\n"
|
||||
" :param inter2: The second Interface1D object.\n"
|
||||
" :type inter2: :class:`freestyle.types.Interface1D`\n"
|
||||
" :return: True.\n"
|
||||
" :rtype: bool\n");
|
||||
static int TrueBP1D___init__(BPy_TrueBP1D *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->py_bp1D.bp1D = new Predicates1D::TrueBP1D();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------BPy_TrueBP1D type definition ------------------------------*/
|
||||
|
||||
PyTypeObject TrueBP1D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "TrueBP1D",
|
||||
/*tp_basicsize*/ sizeof(BPy_TrueBP1D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ TrueBP1D___doc__,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ &BinaryPredicate1D_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)TrueBP1D___init__,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,24 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_BinaryPredicate1D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject TrueBP1D_Type;
|
||||
|
||||
#define BPy_TrueBP1D_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&TrueBP1D_Type))
|
||||
|
||||
/*---------------------------Python BPy_TrueBP1D structure definition----------*/
|
||||
struct BPy_TrueBP1D {
|
||||
BPy_BinaryPredicate1D py_bp1D;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,117 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_ViewMapGradientNormBP1D.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../BPy_IntegrationType.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
// ViewMapGradientNormBP1D(int level, IntegrationType iType=MEAN, float sampling=2.0)
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewMapGradientNormBP1D___doc__,
|
||||
"Class hierarchy: :class:`freestyle.types.BinaryPredicate1D` > "
|
||||
":class:`ViewMapGradientNormBP1D`\n"
|
||||
"\n"
|
||||
".. method:: __init__(level, integration_type=IntegrationType.MEAN, sampling=2.0)\n"
|
||||
"\n"
|
||||
" Builds a ViewMapGradientNormBP1D object.\n"
|
||||
"\n"
|
||||
" :param level: The level of the pyramid from which the pixel must be\n"
|
||||
" read.\n"
|
||||
" :type level: int\n"
|
||||
" :param integration_type: The integration method used to compute a single value\n"
|
||||
" from a set of values.\n"
|
||||
" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
|
||||
" :param sampling: The resolution used to sample the chain:\n"
|
||||
" GetViewMapGradientNormF0D is evaluated at each sample point and\n"
|
||||
" the result is obtained by combining the resulting values into a\n"
|
||||
" single one, following the method specified by integration_type.\n"
|
||||
" :type sampling: float\n"
|
||||
"\n"
|
||||
".. method:: __call__(inter1, inter2)\n"
|
||||
"\n"
|
||||
" Returns true if the evaluation of the Gradient norm Function is\n"
|
||||
" higher for inter1 than for inter2.\n"
|
||||
"\n"
|
||||
" :param inter1: The first Interface1D object.\n"
|
||||
" :type inter1: :class:`freestyle.types.Interface1D`\n"
|
||||
" :param inter2: The second Interface1D object.\n"
|
||||
" :type inter2: :class:`freestyle.types.Interface1D`\n"
|
||||
" :return: True or false.\n"
|
||||
" :rtype: bool\n");
|
||||
static int ViewMapGradientNormBP1D___init__(BPy_ViewMapGradientNormBP1D *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"level", "integration_type", "sampling", nullptr};
|
||||
PyObject *obj = nullptr;
|
||||
int i;
|
||||
float f = 2.0;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "i|O!f", (char **)kwlist, &i, &IntegrationType_Type, &obj, &f))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
IntegrationType t = (obj) ? IntegrationType_from_BPy_IntegrationType(obj) : MEAN;
|
||||
self->py_bp1D.bp1D = new Predicates1D::ViewMapGradientNormBP1D(i, t, f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------BPy_ViewMapGradientNormBP1D type definition ----------------------------*/
|
||||
|
||||
PyTypeObject ViewMapGradientNormBP1D_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "ViewMapGradientNormBP1D",
|
||||
/*tp_basicsize*/ sizeof(BPy_ViewMapGradientNormBP1D),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ ViewMapGradientNormBP1D___doc__,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ &BinaryPredicate1D_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)ViewMapGradientNormBP1D___init__,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,25 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_BinaryPredicate1D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject ViewMapGradientNormBP1D_Type;
|
||||
|
||||
#define BPy_ViewMapGradientNormBP1D_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&ViewMapGradientNormBP1D_Type))
|
||||
|
||||
/*---------------------------Python BPy_ViewMapGradientNormBP1D structure definition----------*/
|
||||
struct BPy_ViewMapGradientNormBP1D {
|
||||
BPy_BinaryPredicate1D py_bp1D;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,346 @@
|
||||
/* SPDX-FileCopyrightText: 2008-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "Director.h"
|
||||
|
||||
#include "BPy_Convert.h"
|
||||
|
||||
#include "BPy_BinaryPredicate0D.h"
|
||||
#include "BPy_BinaryPredicate1D.h"
|
||||
#include "BPy_FrsMaterial.h"
|
||||
#include "BPy_Id.h"
|
||||
#include "BPy_StrokeShader.h"
|
||||
#include "BPy_UnaryFunction0D.h"
|
||||
#include "BPy_UnaryFunction1D.h"
|
||||
#include "BPy_UnaryPredicate0D.h"
|
||||
#include "BPy_UnaryPredicate1D.h"
|
||||
#include "BPy_ViewShape.h"
|
||||
#include "Interface1D/BPy_Stroke.h"
|
||||
#include "Interface1D/BPy_ViewEdge.h"
|
||||
#include "Iterator/BPy_ChainingIterator.h"
|
||||
#include "Iterator/BPy_Interface0DIterator.h"
|
||||
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DDouble.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DEdgeNature.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DFloat.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DId.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DMaterial.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DUnsigned.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DVec2f.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DVec3f.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DVectorViewShape.h"
|
||||
#include "UnaryFunction0D/BPy_UnaryFunction0DViewShape.h"
|
||||
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DDouble.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DEdgeNature.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DFloat.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DUnsigned.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DVec2f.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DVec3f.h"
|
||||
#include "UnaryFunction1D/BPy_UnaryFunction1DVectorViewShape.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
// BinaryPredicate0D: __call__
|
||||
int Director_BPy_BinaryPredicate0D___call__(BinaryPredicate0D *bp0D,
|
||||
Interface0D &i1,
|
||||
Interface0D &i2)
|
||||
{
|
||||
if (!bp0D->py_bp0D) { // internal error
|
||||
PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_bp0D) not initialized");
|
||||
return -1;
|
||||
}
|
||||
PyObject *arg1 = Any_BPy_Interface0D_from_Interface0D(i1);
|
||||
PyObject *arg2 = Any_BPy_Interface0D_from_Interface0D(i2);
|
||||
if (!arg1 || !arg2) {
|
||||
Py_XDECREF(arg1);
|
||||
Py_XDECREF(arg2);
|
||||
return -1;
|
||||
}
|
||||
PyObject *result = PyObject_CallMethod((PyObject *)bp0D->py_bp0D, "__call__", "OO", arg1, arg2);
|
||||
Py_DECREF(arg1);
|
||||
Py_DECREF(arg2);
|
||||
if (!result) {
|
||||
return -1;
|
||||
}
|
||||
int ret = PyObject_IsTrue(result);
|
||||
Py_DECREF(result);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
bp0D->result = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// BinaryPredicate1D: __call__
|
||||
int Director_BPy_BinaryPredicate1D___call__(BinaryPredicate1D *bp1D,
|
||||
Interface1D &i1,
|
||||
Interface1D &i2)
|
||||
{
|
||||
if (!bp1D->py_bp1D) { // internal error
|
||||
PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_bp1D) not initialized");
|
||||
return -1;
|
||||
}
|
||||
PyObject *arg1 = Any_BPy_Interface1D_from_Interface1D(i1);
|
||||
PyObject *arg2 = Any_BPy_Interface1D_from_Interface1D(i2);
|
||||
if (!arg1 || !arg2) {
|
||||
Py_XDECREF(arg1);
|
||||
Py_XDECREF(arg2);
|
||||
return -1;
|
||||
}
|
||||
PyObject *result = PyObject_CallMethod((PyObject *)bp1D->py_bp1D, "__call__", "OO", arg1, arg2);
|
||||
Py_DECREF(arg1);
|
||||
Py_DECREF(arg2);
|
||||
if (!result) {
|
||||
return -1;
|
||||
}
|
||||
int ret = PyObject_IsTrue(result);
|
||||
Py_DECREF(result);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
bp1D->result = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// UnaryPredicate0D: __call__
|
||||
int Director_BPy_UnaryPredicate0D___call__(UnaryPredicate0D *up0D, Interface0DIterator &if0D_it)
|
||||
{
|
||||
if (!up0D->py_up0D) { // internal error
|
||||
PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_up0D) not initialized");
|
||||
return -1;
|
||||
}
|
||||
PyObject *arg = BPy_Interface0DIterator_from_Interface0DIterator(if0D_it, false);
|
||||
if (!arg) {
|
||||
return -1;
|
||||
}
|
||||
PyObject *result = PyObject_CallMethod((PyObject *)up0D->py_up0D, "__call__", "O", arg);
|
||||
Py_DECREF(arg);
|
||||
if (!result) {
|
||||
return -1;
|
||||
}
|
||||
int ret = PyObject_IsTrue(result);
|
||||
Py_DECREF(result);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
up0D->result = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// UnaryPredicate1D: __call__
|
||||
int Director_BPy_UnaryPredicate1D___call__(UnaryPredicate1D *up1D, Interface1D &if1D)
|
||||
{
|
||||
if (!up1D->py_up1D) { // internal error
|
||||
PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_up1D) not initialized");
|
||||
return -1;
|
||||
}
|
||||
PyObject *arg = Any_BPy_Interface1D_from_Interface1D(if1D);
|
||||
if (!arg) {
|
||||
return -1;
|
||||
}
|
||||
PyObject *result = PyObject_CallMethod((PyObject *)up1D->py_up1D, "__call__", "O", arg);
|
||||
Py_DECREF(arg);
|
||||
if (!result) {
|
||||
return -1;
|
||||
}
|
||||
int ret = PyObject_IsTrue(result);
|
||||
Py_DECREF(result);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
up1D->result = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// StrokeShader: shade
|
||||
int Director_BPy_StrokeShader_shade(StrokeShader *ss, Stroke &s)
|
||||
{
|
||||
if (!ss->py_ss) { // internal error
|
||||
PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_ss) not initialized");
|
||||
return -1;
|
||||
}
|
||||
PyObject *arg = BPy_Stroke_from_Stroke(s);
|
||||
if (!arg) {
|
||||
return -1;
|
||||
}
|
||||
PyObject *result = PyObject_CallMethod((PyObject *)ss->py_ss, "shade", "O", arg);
|
||||
Py_DECREF(arg);
|
||||
if (!result) {
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ChainingIterator: init, traverse
|
||||
int Director_BPy_ChainingIterator_init(ChainingIterator *c_it)
|
||||
{
|
||||
if (!c_it->py_c_it) { // internal error
|
||||
PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_c_it) not initialized");
|
||||
return -1;
|
||||
}
|
||||
PyObject *result = PyObject_CallMethod((PyObject *)c_it->py_c_it, "init", nullptr);
|
||||
if (!result) {
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Director_BPy_ChainingIterator_traverse(ChainingIterator *c_it, AdjacencyIterator &a_it)
|
||||
{
|
||||
if (!c_it->py_c_it) { // internal error
|
||||
PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_c_it) not initialized");
|
||||
return -1;
|
||||
}
|
||||
PyObject *arg = BPy_AdjacencyIterator_from_AdjacencyIterator(a_it);
|
||||
if (!arg) {
|
||||
return -1;
|
||||
}
|
||||
PyObject *result = PyObject_CallMethod((PyObject *)c_it->py_c_it, "traverse", "O", arg);
|
||||
Py_DECREF(arg);
|
||||
if (!result) {
|
||||
return -1;
|
||||
}
|
||||
if (BPy_ViewEdge_Check(result)) {
|
||||
c_it->result = ((BPy_ViewEdge *)result)->ve;
|
||||
}
|
||||
else if (result == Py_None) {
|
||||
c_it->result = nullptr;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_RuntimeError, "traverse method returned a wrong value");
|
||||
Py_DECREF(result);
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// BPy_UnaryFunction{0D,1D}: __call__
|
||||
int Director_BPy_UnaryFunction0D___call__(void *uf0D, void *py_uf0D, Interface0DIterator &if0D_it)
|
||||
{
|
||||
if (!py_uf0D) { // internal error
|
||||
PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_uf0D) not initialized");
|
||||
return -1;
|
||||
}
|
||||
PyObject *obj = (PyObject *)py_uf0D;
|
||||
PyObject *arg = BPy_Interface0DIterator_from_Interface0DIterator(if0D_it, false);
|
||||
if (!arg) {
|
||||
return -1;
|
||||
}
|
||||
PyObject *result = PyObject_CallMethod(obj, "__call__", "O", arg);
|
||||
Py_DECREF(arg);
|
||||
if (!result) {
|
||||
return -1;
|
||||
}
|
||||
if (BPy_UnaryFunction0DDouble_Check(obj)) {
|
||||
((UnaryFunction0D<double> *)uf0D)->result = PyFloat_AsDouble(result);
|
||||
}
|
||||
else if (BPy_UnaryFunction0DEdgeNature_Check(obj)) {
|
||||
((UnaryFunction0D<Nature::EdgeNature> *)uf0D)->result = EdgeNature_from_BPy_Nature(result);
|
||||
}
|
||||
else if (BPy_UnaryFunction0DFloat_Check(obj)) {
|
||||
((UnaryFunction0D<float> *)uf0D)->result = PyFloat_AsDouble(result);
|
||||
}
|
||||
else if (BPy_UnaryFunction0DId_Check(obj)) {
|
||||
((UnaryFunction0D<Id> *)uf0D)->result = *(((BPy_Id *)result)->id);
|
||||
}
|
||||
else if (BPy_UnaryFunction0DMaterial_Check(obj)) {
|
||||
((UnaryFunction0D<FrsMaterial> *)uf0D)->result = *(((BPy_FrsMaterial *)result)->m);
|
||||
}
|
||||
else if (BPy_UnaryFunction0DUnsigned_Check(obj)) {
|
||||
((UnaryFunction0D<uint> *)uf0D)->result = PyLong_AsLong(result);
|
||||
}
|
||||
else if (BPy_UnaryFunction0DVec2f_Check(obj)) {
|
||||
Vec2f vec;
|
||||
if (!Vec2f_ptr_from_Vector(result, vec)) {
|
||||
return -1;
|
||||
}
|
||||
((UnaryFunction0D<Vec2f> *)uf0D)->result = vec;
|
||||
}
|
||||
else if (BPy_UnaryFunction0DVec3f_Check(obj)) {
|
||||
Vec3f vec;
|
||||
if (!Vec3f_ptr_from_Vector(result, vec)) {
|
||||
return -1;
|
||||
}
|
||||
((UnaryFunction0D<Vec3f> *)uf0D)->result = vec;
|
||||
}
|
||||
else if (BPy_UnaryFunction0DVectorViewShape_Check(obj)) {
|
||||
vector<ViewShape *> vec;
|
||||
vec.reserve(PyList_Size(result));
|
||||
for (int i = 0; i < PyList_Size(result); i++) {
|
||||
ViewShape *b = ((BPy_ViewShape *)PyList_GET_ITEM(result, i))->vs;
|
||||
vec.push_back(b);
|
||||
}
|
||||
((UnaryFunction0D<vector<ViewShape *>> *)uf0D)->result = vec;
|
||||
}
|
||||
else if (BPy_UnaryFunction0DViewShape_Check(obj)) {
|
||||
((UnaryFunction0D<ViewShape *> *)uf0D)->result = ((BPy_ViewShape *)result)->vs;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Director_BPy_UnaryFunction1D___call__(void *uf1D, void *py_uf1D, Interface1D &if1D)
|
||||
{
|
||||
if (!py_uf1D) { // internal error
|
||||
PyErr_SetString(PyExc_RuntimeError, "Reference to Python object (py_uf1D) not initialized");
|
||||
return -1;
|
||||
}
|
||||
PyObject *obj = (PyObject *)py_uf1D;
|
||||
PyObject *arg = Any_BPy_Interface1D_from_Interface1D(if1D);
|
||||
if (!arg) {
|
||||
return -1;
|
||||
}
|
||||
PyObject *result = PyObject_CallMethod(obj, "__call__", "O", arg);
|
||||
Py_DECREF(arg);
|
||||
if (!result) {
|
||||
return -1;
|
||||
}
|
||||
if (BPy_UnaryFunction1DDouble_Check(obj)) {
|
||||
((UnaryFunction1D<double> *)uf1D)->result = PyFloat_AsDouble(result);
|
||||
}
|
||||
else if (BPy_UnaryFunction1DEdgeNature_Check(obj)) {
|
||||
((UnaryFunction1D<Nature::EdgeNature> *)uf1D)->result = EdgeNature_from_BPy_Nature(result);
|
||||
}
|
||||
else if (BPy_UnaryFunction1DFloat_Check(obj)) {
|
||||
((UnaryFunction1D<float> *)uf1D)->result = PyFloat_AsDouble(result);
|
||||
}
|
||||
else if (BPy_UnaryFunction1DUnsigned_Check(obj)) {
|
||||
((UnaryFunction1D<uint> *)uf1D)->result = PyLong_AsLong(result);
|
||||
}
|
||||
else if (BPy_UnaryFunction1DVec2f_Check(obj)) {
|
||||
Vec2f vec;
|
||||
if (!Vec2f_ptr_from_Vector(result, vec)) {
|
||||
return -1;
|
||||
}
|
||||
((UnaryFunction1D<Vec2f> *)uf1D)->result = vec;
|
||||
}
|
||||
else if (BPy_UnaryFunction1DVec3f_Check(obj)) {
|
||||
Vec3f vec;
|
||||
if (!Vec3f_ptr_from_Vector(result, vec)) {
|
||||
return -1;
|
||||
}
|
||||
((UnaryFunction1D<Vec3f> *)uf1D)->result = vec;
|
||||
}
|
||||
else if (BPy_UnaryFunction1DVectorViewShape_Check(obj)) {
|
||||
vector<ViewShape *> vec;
|
||||
vec.reserve(PyList_Size(result));
|
||||
for (int i = 1; i < PyList_Size(result); i++) {
|
||||
ViewShape *b = ((BPy_ViewShape *)PyList_GET_ITEM(result, i))->vs;
|
||||
vec.push_back(b);
|
||||
}
|
||||
((UnaryFunction1D<vector<ViewShape *>> *)uf1D)->result = vec;
|
||||
}
|
||||
Py_DECREF(result);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Freestyle {
|
||||
class UnaryPredicate0D;
|
||||
class UnaryPredicate1D;
|
||||
class BinaryPredicate0D;
|
||||
class BinaryPredicate1D;
|
||||
class ChainingIterator;
|
||||
class AdjacencyIterator;
|
||||
class Interface0D;
|
||||
class Interface1D;
|
||||
class Interface0DIterator;
|
||||
class Stroke;
|
||||
class StrokeShader;
|
||||
} // namespace Freestyle
|
||||
|
||||
// BinaryPredicate0D: __call__
|
||||
int Director_BPy_BinaryPredicate0D___call__(Freestyle::BinaryPredicate0D *bp0D,
|
||||
Freestyle::Interface0D &i1,
|
||||
Freestyle::Interface0D &i2);
|
||||
|
||||
// BinaryPredicate1D: __call__
|
||||
int Director_BPy_BinaryPredicate1D___call__(Freestyle::BinaryPredicate1D *bp1D,
|
||||
Freestyle::Interface1D &i1,
|
||||
Freestyle::Interface1D &i2);
|
||||
|
||||
// UnaryFunction{0D,1D}: __call__
|
||||
int Director_BPy_UnaryFunction0D___call__(void *uf0D,
|
||||
void *py_uf0D,
|
||||
Freestyle::Interface0DIterator &if0D_it);
|
||||
int Director_BPy_UnaryFunction1D___call__(void *uf1D, void *py_uf1D, Freestyle::Interface1D &if1D);
|
||||
|
||||
// UnaryPredicate0D: __call__
|
||||
int Director_BPy_UnaryPredicate0D___call__(Freestyle::UnaryPredicate0D *up0D,
|
||||
Freestyle::Interface0DIterator &if0D_it);
|
||||
|
||||
// UnaryPredicate1D: __call__
|
||||
int Director_BPy_UnaryPredicate1D___call__(Freestyle::UnaryPredicate1D *up1D,
|
||||
Freestyle::Interface1D &if1D);
|
||||
|
||||
// StrokeShader: shade
|
||||
int Director_BPy_StrokeShader_shade(Freestyle::StrokeShader *ss, Freestyle::Stroke &s);
|
||||
|
||||
// ChainingIterator: init, traverse
|
||||
int Director_BPy_ChainingIterator_init(Freestyle::ChainingIterator *c_it);
|
||||
int Director_BPy_ChainingIterator_traverse(Freestyle::ChainingIterator *c_it,
|
||||
Freestyle::AdjacencyIterator &a_it);
|
||||
@@ -0,0 +1,275 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_CurvePoint.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../Interface0D/BPy_SVertex.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*----------------------CurvePoint methods----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
CurvePoint_doc,
|
||||
"Class hierarchy: :class:`Interface0D` > :class:`CurvePoint`\n"
|
||||
"\n"
|
||||
"Class to represent a point of a curve. A CurvePoint can be any point\n"
|
||||
"of a 1D curve (it doesn't have to be a vertex of the curve). Any\n"
|
||||
":class:`Interface1D` is built upon ViewEdges, themselves built upon\n"
|
||||
"FEdges. Therefore, a curve is basically a polyline made of a list of\n"
|
||||
":class:`SVertex` objects. Thus, a CurvePoint is built by linearly\n"
|
||||
"interpolating two :class:`SVertex` instances. CurvePoint can be used\n"
|
||||
"as virtual points while querying 0D information along a curve at a\n"
|
||||
"given resolution.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(first_vertex, second_vertex, t2d)``\n"
|
||||
" - ``__init__(first_point, second_point, t2d)``\n"
|
||||
"\n"
|
||||
" Builds a CurvePoint using the default constructor, copy constructor,\n"
|
||||
" or one of the overloaded constructors. The over loaded constructors\n"
|
||||
" can either take two :class:`SVertex` or two :class:`CurvePoint`\n"
|
||||
" objects and an interpolation parameter\n"
|
||||
"\n"
|
||||
" :param brother: A CurvePoint object.\n"
|
||||
" :type brother: :class:`CurvePoint`\n"
|
||||
" :param first_vertex: The first SVertex.\n"
|
||||
" :type first_vertex: :class:`SVertex`\n"
|
||||
" :param second_vertex: The second SVertex.\n"
|
||||
" :type second_vertex: :class:`SVertex`\n"
|
||||
" :param first_point: The first CurvePoint.\n"
|
||||
" :type first_point: :class:`CurvePoint`\n"
|
||||
" :param second_point: The second CurvePoint.\n"
|
||||
" :type second_point: :class:`CurvePoint`\n"
|
||||
" :param t2d: A 2D interpolation parameter used to linearly interpolate\n"
|
||||
" first_vertex and second_vertex or first_point and second_point.\n"
|
||||
" :type t2d: float\n");
|
||||
static int CurvePoint_init(BPy_CurvePoint *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"first_vertex", "second_vertex", "t2d", nullptr};
|
||||
static const char *kwlist_3[] = {"first_point", "second_point", "t2d", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr;
|
||||
float t2d;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &CurvePoint_Type, &obj1)) {
|
||||
if (!obj1) {
|
||||
self->cp = new CurvePoint();
|
||||
}
|
||||
else {
|
||||
self->cp = new CurvePoint(*(((BPy_CurvePoint *)obj1)->cp));
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!O!f",
|
||||
(char **)kwlist_2,
|
||||
&SVertex_Type,
|
||||
&obj1,
|
||||
&SVertex_Type,
|
||||
&obj2,
|
||||
&t2d))
|
||||
{
|
||||
self->cp = new CurvePoint(((BPy_SVertex *)obj1)->sv, ((BPy_SVertex *)obj2)->sv, t2d);
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!O!f",
|
||||
(char **)kwlist_3,
|
||||
&CurvePoint_Type,
|
||||
&obj1,
|
||||
&CurvePoint_Type,
|
||||
&obj2,
|
||||
&t2d))
|
||||
{
|
||||
CurvePoint *cp1 = ((BPy_CurvePoint *)obj1)->cp;
|
||||
CurvePoint *cp2 = ((BPy_CurvePoint *)obj2)->cp;
|
||||
if (!cp1 || cp1->A() == nullptr || cp1->B() == nullptr) {
|
||||
PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid CurvePoint object");
|
||||
return -1;
|
||||
}
|
||||
if (!cp2 || cp2->A() == nullptr || cp2->B() == nullptr) {
|
||||
PyErr_SetString(PyExc_TypeError, "argument 2 is an invalid CurvePoint object");
|
||||
return -1;
|
||||
}
|
||||
self->cp = new CurvePoint(cp1, cp2, t2d);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_if0D.if0D = self->cp;
|
||||
self->py_if0D.borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// bool operator== (const CurvePoint &b)
|
||||
|
||||
/*----------------------CurvePoint get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
CurvePoint_first_svertex_doc,
|
||||
"The first SVertex upon which the CurvePoint is built.\n"
|
||||
"\n"
|
||||
":type: :class:`SVertex`\n");
|
||||
static PyObject *CurvePoint_first_svertex_get(BPy_CurvePoint *self, void * /*closure*/)
|
||||
{
|
||||
SVertex *A = self->cp->A();
|
||||
if (A) {
|
||||
return BPy_SVertex_from_SVertex(*A);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int CurvePoint_first_svertex_set(BPy_CurvePoint *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_SVertex_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
|
||||
return -1;
|
||||
}
|
||||
self->cp->setA(((BPy_SVertex *)value)->sv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
CurvePoint_second_svertex_doc,
|
||||
"The second SVertex upon which the CurvePoint is built.\n"
|
||||
"\n"
|
||||
":type: :class:`SVertex`\n");
|
||||
static PyObject *CurvePoint_second_svertex_get(BPy_CurvePoint *self, void * /*closure*/)
|
||||
{
|
||||
SVertex *B = self->cp->B();
|
||||
if (B) {
|
||||
return BPy_SVertex_from_SVertex(*B);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int CurvePoint_second_svertex_set(BPy_CurvePoint *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_SVertex_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
|
||||
return -1;
|
||||
}
|
||||
self->cp->setB(((BPy_SVertex *)value)->sv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
CurvePoint_fedge_doc,
|
||||
"Gets the FEdge for the two SVertices that given CurvePoints consists out of.\n"
|
||||
"A shortcut for CurvePoint.first_svertex.get_fedge(CurvePoint.second_svertex).\n"
|
||||
"\n"
|
||||
":type: :class:`FEdge`\n");
|
||||
static PyObject *CurvePoint_fedge_get(BPy_CurvePoint *self, void * /*closure*/)
|
||||
{
|
||||
SVertex *A = self->cp->A();
|
||||
Interface0D *B = (Interface0D *)self->cp->B();
|
||||
// B can be nullptr under certain circumstances
|
||||
if (B) {
|
||||
return Any_BPy_Interface1D_from_Interface1D(*(A->getFEdge(*B)));
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
CurvePoint_t2d_doc,
|
||||
"The 2D interpolation parameter.\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *CurvePoint_t2d_get(BPy_CurvePoint *self, void * /*closure*/)
|
||||
{
|
||||
return PyFloat_FromDouble(self->cp->t2d());
|
||||
}
|
||||
|
||||
static int CurvePoint_t2d_set(BPy_CurvePoint *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float scalar;
|
||||
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a number");
|
||||
return -1;
|
||||
}
|
||||
self->cp->setT2d(scalar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_CurvePoint_getseters[] = {
|
||||
{"first_svertex",
|
||||
(getter)CurvePoint_first_svertex_get,
|
||||
(setter)CurvePoint_first_svertex_set,
|
||||
CurvePoint_first_svertex_doc,
|
||||
nullptr},
|
||||
{"second_svertex",
|
||||
(getter)CurvePoint_second_svertex_get,
|
||||
(setter)CurvePoint_second_svertex_set,
|
||||
CurvePoint_second_svertex_doc,
|
||||
nullptr},
|
||||
{"fedge", (getter)CurvePoint_fedge_get, nullptr, CurvePoint_fedge_doc, nullptr},
|
||||
{"t2d", (getter)CurvePoint_t2d_get, (setter)CurvePoint_t2d_set, CurvePoint_t2d_doc, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_CurvePoint type definition ------------------------------*/
|
||||
|
||||
PyTypeObject CurvePoint_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "CurvePoint",
|
||||
/*tp_basicsize*/ sizeof(BPy_CurvePoint),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ CurvePoint_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_CurvePoint_getseters,
|
||||
/*tp_base*/ &Interface0D_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)CurvePoint_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,27 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_Interface0D.h"
|
||||
|
||||
#include "../../stroke/Curve.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject CurvePoint_Type;
|
||||
|
||||
#define BPy_CurvePoint_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&CurvePoint_Type))
|
||||
|
||||
/*---------------------------Python BPy_CurvePoint structure definition----------*/
|
||||
struct BPy_CurvePoint {
|
||||
BPy_Interface0D py_if0D;
|
||||
Freestyle::CurvePoint *cp;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,522 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_SVertex.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../BPy_Id.h"
|
||||
#include "../Interface1D/BPy_FEdge.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*----------------------SVertex methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SVertex_doc,
|
||||
"Class hierarchy: :class:`Interface0D` > :class:`SVertex`\n"
|
||||
"\n"
|
||||
"Class to define a vertex of the embedding.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(point_3d, id)``\n"
|
||||
"\n"
|
||||
" Builds a :class:`SVertex` using the default constructor,\n"
|
||||
" copy constructor or the overloaded constructor which builds"
|
||||
" a :class:`SVertex` from 3D coordinates and an Id.\n"
|
||||
"\n"
|
||||
" :param brother: A SVertex object.\n"
|
||||
" :type brother: :class:`SVertex`\n"
|
||||
" :param point_3d: A three-dimensional vector.\n"
|
||||
" :type point_3d: :class:`mathutils.Vector`\n"
|
||||
" :param id: An Id object.\n"
|
||||
" :type id: :class:`Id`\n");
|
||||
static int SVertex_init(BPy_SVertex *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"point_3d", "id", nullptr};
|
||||
PyObject *obj = nullptr;
|
||||
float v[3];
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &SVertex_Type, &obj)) {
|
||||
if (!obj) {
|
||||
self->sv = new SVertex();
|
||||
}
|
||||
else {
|
||||
self->sv = new SVertex(*(((BPy_SVertex *)obj)->sv));
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O&O!", (char **)kwlist_2, convert_v3, v, &Id_Type, &obj))
|
||||
{
|
||||
Vec3r point_3d(v[0], v[1], v[2]);
|
||||
self->sv = new SVertex(point_3d, *(((BPy_Id *)obj)->id));
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_if0D.if0D = self->sv;
|
||||
self->py_if0D.borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SVertex_add_normal_doc,
|
||||
".. method:: add_normal(normal)\n"
|
||||
"\n"
|
||||
" Adds a normal to the SVertex's set of normals. If the same normal\n"
|
||||
" is already in the set, nothing changes.\n"
|
||||
"\n"
|
||||
" :param normal: A three-dimensional vector.\n"
|
||||
" :type normal: :class:`mathutils.Vector` | tuple[float, float, float] | list[float]\n");
|
||||
static PyObject *SVertex_add_normal(BPy_SVertex *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"normal", nullptr};
|
||||
PyObject *py_normal;
|
||||
Vec3r n;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", (char **)kwlist, &py_normal)) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!Vec3r_ptr_from_PyObject(py_normal, n)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"argument 1 must be a 3D vector (either a list of 3 elements or Vector)");
|
||||
return nullptr;
|
||||
}
|
||||
self->sv->AddNormal(n);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SVertex_add_fedge_doc,
|
||||
".. method:: add_fedge(fedge)\n"
|
||||
"\n"
|
||||
" Add an FEdge to the list of edges emanating from this SVertex.\n"
|
||||
"\n"
|
||||
" :param fedge: An FEdge.\n"
|
||||
" :type fedge: :class:`FEdge`\n");
|
||||
static PyObject *SVertex_add_fedge(BPy_SVertex *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"fedge", nullptr};
|
||||
PyObject *py_fe;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &FEdge_Type, &py_fe)) {
|
||||
return nullptr;
|
||||
}
|
||||
self->sv->AddFEdge(((BPy_FEdge *)py_fe)->fe);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
// virtual bool operator== (const SVertex &brother)
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_SVertex_methods[] = {
|
||||
{"add_normal",
|
||||
(PyCFunction)SVertex_add_normal,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
SVertex_add_normal_doc},
|
||||
{"add_fedge",
|
||||
(PyCFunction)SVertex_add_fedge,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
SVertex_add_fedge_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------mathutils callbacks ----------------------------*/
|
||||
|
||||
/* subtype */
|
||||
#define MATHUTILS_SUBTYPE_POINT3D 1
|
||||
#define MATHUTILS_SUBTYPE_POINT2D 2
|
||||
|
||||
static int SVertex_mathutils_check(blender::BaseMathObject *bmo)
|
||||
{
|
||||
if (!BPy_SVertex_Check(bmo->cb_user)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SVertex_mathutils_get(blender::BaseMathObject *bmo, int subtype)
|
||||
{
|
||||
BPy_SVertex *self = (BPy_SVertex *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_POINT3D:
|
||||
bmo->data[0] = self->sv->getX();
|
||||
bmo->data[1] = self->sv->getY();
|
||||
bmo->data[2] = self->sv->getZ();
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_POINT2D:
|
||||
bmo->data[0] = self->sv->getProjectedX();
|
||||
bmo->data[1] = self->sv->getProjectedY();
|
||||
bmo->data[2] = self->sv->getProjectedZ();
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SVertex_mathutils_set(blender::BaseMathObject *bmo, int subtype)
|
||||
{
|
||||
BPy_SVertex *self = (BPy_SVertex *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_POINT3D: {
|
||||
Vec3r p(bmo->data[0], bmo->data[1], bmo->data[2]);
|
||||
self->sv->setPoint3D(p);
|
||||
break;
|
||||
}
|
||||
case MATHUTILS_SUBTYPE_POINT2D: {
|
||||
Vec3r p(bmo->data[0], bmo->data[1], bmo->data[2]);
|
||||
self->sv->setPoint2D(p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SVertex_mathutils_get_index(blender::BaseMathObject *bmo, int subtype, int index)
|
||||
{
|
||||
BPy_SVertex *self = (BPy_SVertex *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_POINT3D:
|
||||
switch (index) {
|
||||
case 0:
|
||||
bmo->data[0] = self->sv->getX();
|
||||
break;
|
||||
case 1:
|
||||
bmo->data[1] = self->sv->getY();
|
||||
break;
|
||||
case 2:
|
||||
bmo->data[2] = self->sv->getZ();
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case MATHUTILS_SUBTYPE_POINT2D:
|
||||
switch (index) {
|
||||
case 0:
|
||||
bmo->data[0] = self->sv->getProjectedX();
|
||||
break;
|
||||
case 1:
|
||||
bmo->data[1] = self->sv->getProjectedY();
|
||||
break;
|
||||
case 2:
|
||||
bmo->data[2] = self->sv->getProjectedZ();
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SVertex_mathutils_set_index(blender::BaseMathObject *bmo, int subtype, int index)
|
||||
{
|
||||
BPy_SVertex *self = (BPy_SVertex *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_POINT3D: {
|
||||
Vec3r p(self->sv->point3D());
|
||||
p[index] = bmo->data[index];
|
||||
self->sv->setPoint3D(p);
|
||||
break;
|
||||
}
|
||||
case MATHUTILS_SUBTYPE_POINT2D: {
|
||||
Vec3r p(self->sv->point2D());
|
||||
p[index] = bmo->data[index];
|
||||
self->sv->setPoint2D(p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static blender::Mathutils_Callback SVertex_mathutils_cb = {
|
||||
SVertex_mathutils_check,
|
||||
SVertex_mathutils_get,
|
||||
SVertex_mathutils_set,
|
||||
SVertex_mathutils_get_index,
|
||||
SVertex_mathutils_set_index,
|
||||
};
|
||||
|
||||
static uchar SVertex_mathutils_cb_index = -1;
|
||||
|
||||
void SVertex_mathutils_register_callback()
|
||||
{
|
||||
SVertex_mathutils_cb_index = Mathutils_RegisterCallback(&SVertex_mathutils_cb);
|
||||
}
|
||||
|
||||
/*----------------------SVertex get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SVertex_point_3d_doc,
|
||||
"The 3D coordinates of the SVertex.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Vector`\n");
|
||||
static PyObject *SVertex_point_3d_get(BPy_SVertex *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Vector_CreatePyObject_cb(
|
||||
(PyObject *)self, 3, SVertex_mathutils_cb_index, MATHUTILS_SUBTYPE_POINT3D);
|
||||
}
|
||||
|
||||
static int SVertex_point_3d_set(BPy_SVertex *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float v[3];
|
||||
if (blender::mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
Vec3r p(v[0], v[1], v[2]);
|
||||
self->sv->setPoint3D(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SVertex_point_2d_doc,
|
||||
"The projected 3D coordinates of the SVertex.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Vector`\n");
|
||||
static PyObject *SVertex_point_2d_get(BPy_SVertex *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Vector_CreatePyObject_cb(
|
||||
(PyObject *)self, 3, SVertex_mathutils_cb_index, MATHUTILS_SUBTYPE_POINT2D);
|
||||
}
|
||||
|
||||
static int SVertex_point_2d_set(BPy_SVertex *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float v[3];
|
||||
if (blender::mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
Vec3r p(v[0], v[1], v[2]);
|
||||
self->sv->setPoint2D(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SVertex_id_doc,
|
||||
"The Id of this SVertex.\n"
|
||||
"\n"
|
||||
":type: :class:`Id`\n");
|
||||
static PyObject *SVertex_id_get(BPy_SVertex *self, void * /*closure*/)
|
||||
{
|
||||
Id id(self->sv->getId());
|
||||
return BPy_Id_from_Id(id); // return a copy
|
||||
}
|
||||
|
||||
static int SVertex_id_set(BPy_SVertex *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_Id_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an Id");
|
||||
return -1;
|
||||
}
|
||||
self->sv->setId(*(((BPy_Id *)value)->id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SVertex_normals_doc,
|
||||
"The normals for this Vertex as a list. In a sharp surface, an SVertex\n"
|
||||
"has exactly one normal. In a smooth surface, an SVertex can have any\n"
|
||||
"number of normals.\n"
|
||||
"\n"
|
||||
":type: list[:class:`mathutils.Vector`]\n");
|
||||
static PyObject *SVertex_normals_get(BPy_SVertex *self, void * /*closure*/)
|
||||
{
|
||||
PyObject *py_normals;
|
||||
set<Vec3r> normals = self->sv->normals();
|
||||
set<Vec3r>::iterator it;
|
||||
py_normals = PyList_New(normals.size());
|
||||
uint i = 0;
|
||||
|
||||
for (it = normals.begin(); it != normals.end(); it++) {
|
||||
Vec3r v(*it);
|
||||
PyList_SET_ITEM(py_normals, i++, Vector_from_Vec3r(v));
|
||||
}
|
||||
return py_normals;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SVertex_normals_size_doc,
|
||||
"The number of different normals for this SVertex.\n"
|
||||
"\n"
|
||||
":type: int\n");
|
||||
static PyObject *SVertex_normals_size_get(BPy_SVertex *self, void * /*closure*/)
|
||||
{
|
||||
return PyLong_FromLong(self->sv->normalsSize());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SVertex_viewvertex_doc,
|
||||
"If this SVertex is also a ViewVertex, this property refers to the\n"
|
||||
"ViewVertex, and None otherwise.\n"
|
||||
"\n"
|
||||
":type: :class:`ViewVertex`\n");
|
||||
static PyObject *SVertex_viewvertex_get(BPy_SVertex *self, void * /*closure*/)
|
||||
{
|
||||
ViewVertex *vv = self->sv->viewvertex();
|
||||
if (vv) {
|
||||
return Any_BPy_ViewVertex_from_ViewVertex(*vv);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
SVertex_curvatures_doc,
|
||||
"Curvature information expressed in the form of a seven-element tuple\n"
|
||||
"(K1, e1, K2, e2, Kr, er, dKr), where K1 and K2 are scalar values\n"
|
||||
"representing the first (maximum) and second (minimum) principal\n"
|
||||
"curvatures at this SVertex, respectively; e1 and e2 are\n"
|
||||
"three-dimensional vectors representing the first and second principal\n"
|
||||
"directions, i.e. the directions of the normal plane where the\n"
|
||||
"curvature takes its maximum and minimum values, respectively; and Kr,\n"
|
||||
"er and dKr are the radial curvature, radial direction, and the\n"
|
||||
"derivative of the radial curvature at this SVertex, respectively.\n"
|
||||
"\n"
|
||||
":type: tuple\n");
|
||||
static PyObject *SVertex_curvatures_get(BPy_SVertex *self, void * /*closure*/)
|
||||
{
|
||||
const CurvatureInfo *info = self->sv->getCurvatureInfo();
|
||||
if (!info) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
Vec3r e1(info->e1.x(), info->e1.y(), info->e1.z());
|
||||
Vec3r e2(info->e2.x(), info->e2.y(), info->e2.z());
|
||||
Vec3r er(info->er.x(), info->er.y(), info->er.z());
|
||||
PyObject *retval = PyTuple_New(7);
|
||||
PyTuple_SET_ITEMS(retval,
|
||||
PyFloat_FromDouble(info->K1),
|
||||
PyFloat_FromDouble(info->K2),
|
||||
Vector_from_Vec3r(e1),
|
||||
Vector_from_Vec3r(e2),
|
||||
PyFloat_FromDouble(info->Kr),
|
||||
Vector_from_Vec3r(er),
|
||||
PyFloat_FromDouble(info->dKr));
|
||||
return retval;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_SVertex_getseters[] = {
|
||||
{"point_3d",
|
||||
(getter)SVertex_point_3d_get,
|
||||
(setter)SVertex_point_3d_set,
|
||||
SVertex_point_3d_doc,
|
||||
nullptr},
|
||||
{"point_2d",
|
||||
(getter)SVertex_point_2d_get,
|
||||
(setter)SVertex_point_2d_set,
|
||||
SVertex_point_2d_doc,
|
||||
nullptr},
|
||||
{"id", (getter)SVertex_id_get, (setter)SVertex_id_set, SVertex_id_doc, nullptr},
|
||||
{"normals", (getter)SVertex_normals_get, (setter) nullptr, SVertex_normals_doc, nullptr},
|
||||
{"normals_size",
|
||||
(getter)SVertex_normals_size_get,
|
||||
(setter) nullptr,
|
||||
SVertex_normals_size_doc,
|
||||
nullptr},
|
||||
{"viewvertex",
|
||||
(getter)SVertex_viewvertex_get,
|
||||
(setter) nullptr,
|
||||
SVertex_viewvertex_doc,
|
||||
nullptr},
|
||||
{"curvatures",
|
||||
(getter)SVertex_curvatures_get,
|
||||
(setter) nullptr,
|
||||
SVertex_curvatures_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_SVertex type definition ------------------------------*/
|
||||
|
||||
PyTypeObject SVertex_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "SVertex",
|
||||
/*tp_basicsize*/ sizeof(BPy_SVertex),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ SVertex_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_SVertex_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_SVertex_getseters,
|
||||
/*tp_base*/ &Interface0D_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)SVertex_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,31 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_Interface0D.h"
|
||||
|
||||
#include "../../view_map/Silhouette.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject SVertex_Type;
|
||||
|
||||
#define BPy_SVertex_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&SVertex_Type))
|
||||
|
||||
/*---------------------------Python BPy_SVertex structure definition----------*/
|
||||
struct BPy_SVertex {
|
||||
BPy_Interface0D py_if0D;
|
||||
Freestyle::SVertex *sv;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_SVertex visible prototypes-----------*/
|
||||
|
||||
void SVertex_mathutils_register_callback();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,213 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_ViewVertex.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../BPy_Nature.h"
|
||||
#include "../Interface1D/BPy_ViewEdge.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*----------------------ViewVertex methods----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewVertex_doc,
|
||||
"Class hierarchy: :class:`Interface0D` > :class:`ViewVertex`\n"
|
||||
"\n"
|
||||
"Class to define a view vertex. A view vertex is a feature vertex\n"
|
||||
"corresponding to a point of the image graph, where the characteristics\n"
|
||||
"of an edge (e.g., nature and visibility) might change. A\n"
|
||||
":class:`ViewVertex` can be of two kinds: A :class:`TVertex` when it\n"
|
||||
"corresponds to the intersection between two ViewEdges or a\n"
|
||||
":class:`NonTVertex` when it corresponds to a vertex of the initial\n"
|
||||
"input mesh (it is the case for vertices such as corners for example).\n"
|
||||
"Thus, this class can be specialized into two classes, the\n"
|
||||
":class:`TVertex` class and the :class:`NonTVertex` class.\n");
|
||||
static int ViewVertex_init(BPy_ViewVertex * /*self*/, PyObject * /*args*/, PyObject * /*kwds*/)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "cannot instantiate abstract class");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewVertex_edges_begin_doc,
|
||||
".. method:: edges_begin()\n"
|
||||
"\n"
|
||||
" Returns an iterator over the ViewEdges that goes to or comes from\n"
|
||||
" this ViewVertex pointing to the first ViewEdge of the list. The\n"
|
||||
" orientedViewEdgeIterator allows to iterate in CCW order over these\n"
|
||||
" ViewEdges and to get the orientation for each ViewEdge\n"
|
||||
" (incoming/outgoing).\n"
|
||||
"\n"
|
||||
" :return: An orientedViewEdgeIterator pointing to the first ViewEdge.\n"
|
||||
" :rtype: :class:`orientedViewEdgeIterator`\n");
|
||||
static PyObject *ViewVertex_edges_begin(BPy_ViewVertex *self)
|
||||
{
|
||||
ViewVertexInternal::orientedViewEdgeIterator ove_it(self->vv->edgesBegin());
|
||||
return BPy_orientedViewEdgeIterator_from_orientedViewEdgeIterator(ove_it, false);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewVertex_edges_end_doc,
|
||||
".. method:: edges_end()\n"
|
||||
"\n"
|
||||
" Returns an orientedViewEdgeIterator over the ViewEdges around this\n"
|
||||
" ViewVertex, pointing after the last ViewEdge.\n"
|
||||
"\n"
|
||||
" :return: An orientedViewEdgeIterator pointing after the last ViewEdge.\n"
|
||||
" :rtype: :class:`orientedViewEdgeIterator`\n");
|
||||
static PyObject *ViewVertex_edges_end(BPy_ViewVertex * /*self*/)
|
||||
{
|
||||
#if 0
|
||||
ViewVertexInternal::orientedViewEdgeIterator ove_it(self->vv->edgesEnd());
|
||||
return BPy_orientedViewEdgeIterator_from_orientedViewEdgeIterator(ove_it, 1);
|
||||
#else
|
||||
PyErr_SetString(PyExc_NotImplementedError, "edges_end method currently disabled");
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewVertex_edges_iterator_doc,
|
||||
".. method:: edges_iterator(edge)\n"
|
||||
"\n"
|
||||
" Returns an orientedViewEdgeIterator pointing to the ViewEdge given\n"
|
||||
" as argument.\n"
|
||||
"\n"
|
||||
" :param edge: A ViewEdge object.\n"
|
||||
" :type edge: :class:`ViewEdge`\n"
|
||||
" :return: An orientedViewEdgeIterator pointing to the given ViewEdge.\n"
|
||||
" :rtype: :class:`orientedViewEdgeIterator`\n");
|
||||
static PyObject *ViewVertex_edges_iterator(BPy_ViewVertex *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"edge", nullptr};
|
||||
PyObject *py_ve;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &ViewEdge_Type, &py_ve)) {
|
||||
return nullptr;
|
||||
}
|
||||
ViewEdge *ve = ((BPy_ViewEdge *)py_ve)->ve;
|
||||
ViewVertexInternal::orientedViewEdgeIterator ove_it(self->vv->edgesIterator(ve));
|
||||
return BPy_orientedViewEdgeIterator_from_orientedViewEdgeIterator(ove_it, false);
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_ViewVertex_methods[] = {
|
||||
{"edges_begin", (PyCFunction)ViewVertex_edges_begin, METH_NOARGS, ViewVertex_edges_begin_doc},
|
||||
{"edges_end", (PyCFunction)ViewVertex_edges_end, METH_NOARGS, ViewVertex_edges_end_doc},
|
||||
{"edges_iterator",
|
||||
(PyCFunction)ViewVertex_edges_iterator,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
ViewVertex_edges_iterator_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------ViewVertex get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewVertex_nature_doc,
|
||||
"The nature of this ViewVertex.\n"
|
||||
"\n"
|
||||
":type: :class:`Nature`\n");
|
||||
static PyObject *ViewVertex_nature_get(BPy_ViewVertex *self, void * /*closure*/)
|
||||
{
|
||||
Nature::VertexNature nature = self->vv->getNature();
|
||||
if (PyErr_Occurred()) {
|
||||
return nullptr;
|
||||
}
|
||||
return BPy_Nature_from_Nature(nature); // return a copy
|
||||
}
|
||||
|
||||
static int ViewVertex_nature_set(BPy_ViewVertex *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_Nature_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a Nature");
|
||||
return -1;
|
||||
}
|
||||
self->vv->setNature(PyLong_AsLong((PyObject *)&((BPy_Nature *)value)->i));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_ViewVertex_getseters[] = {
|
||||
{"nature",
|
||||
(getter)ViewVertex_nature_get,
|
||||
(setter)ViewVertex_nature_set,
|
||||
ViewVertex_nature_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_ViewVertex type definition ------------------------------*/
|
||||
|
||||
PyTypeObject ViewVertex_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "ViewVertex",
|
||||
/*tp_basicsize*/ sizeof(BPy_ViewVertex),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ ViewVertex_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_ViewVertex_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_ViewVertex_getseters,
|
||||
/*tp_base*/ &Interface0D_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)ViewVertex_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,27 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_Interface0D.h"
|
||||
|
||||
#include "../../view_map/ViewMap.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject ViewVertex_Type;
|
||||
|
||||
#define BPy_ViewVertex_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ViewVertex_Type))
|
||||
|
||||
/*---------------------------Python BPy_ViewVertex structure definition----------*/
|
||||
struct BPy_ViewVertex {
|
||||
BPy_Interface0D py_if0D;
|
||||
Freestyle::ViewVertex *vv;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,402 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_StrokeVertex.h"
|
||||
|
||||
#include "../../BPy_Convert.h"
|
||||
#include "../../BPy_Freestyle.h"
|
||||
#include "../../BPy_StrokeAttribute.h"
|
||||
#include "../../Interface0D/BPy_SVertex.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeVertex_doc,
|
||||
"Class hierarchy: :class:`Interface0D` > :class:`CurvePoint` > :class:`StrokeVertex`\n"
|
||||
"\n"
|
||||
"Class to define a stroke vertex.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(first_vertex, second_vertex, t3d)``\n"
|
||||
" - ``__init__(point)``\n"
|
||||
" - ``__init__(svertex)``\n"
|
||||
" - ``__init__(svertex, attribute)``\n"
|
||||
"\n"
|
||||
" Builds a :class:`StrokeVertex` using the default constructor,\n"
|
||||
" copy constructor, from 2 :class:`StrokeVertex` and an interpolation parameter,\n"
|
||||
" from a CurvePoint, from a SVertex, or a :class:`SVertex`"
|
||||
" and a :class:`StrokeAttribute` object.\n"
|
||||
"\n"
|
||||
" :param brother: A StrokeVertex object.\n"
|
||||
" :type brother: :class:`StrokeVertex`\n"
|
||||
" :param first_vertex: The first StrokeVertex.\n"
|
||||
" :type first_vertex: :class:`StrokeVertex`\n"
|
||||
" :param second_vertex: The second StrokeVertex.\n"
|
||||
" :type second_vertex: :class:`StrokeVertex`\n"
|
||||
" :param t3d: An interpolation parameter.\n"
|
||||
" :type t3d: float\n"
|
||||
" :param point: A CurvePoint object.\n"
|
||||
" :type point: :class:`CurvePoint`\n"
|
||||
" :param svertex: An SVertex object.\n"
|
||||
" :type svertex: :class:`SVertex`\n"
|
||||
" :param svertex: An SVertex object.\n"
|
||||
" :type svertex: :class:`SVertex`\n"
|
||||
" :param attribute: A StrokeAttribute object.\n"
|
||||
" :type attribute: :class:`StrokeAttribute`\n");
|
||||
static int StrokeVertex_init(BPy_StrokeVertex *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"first_vertex", "second_vertex", "t3d", nullptr};
|
||||
static const char *kwlist_3[] = {"point", nullptr};
|
||||
static const char *kwlist_4[] = {"svertex", "attribute", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr;
|
||||
float t3d;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &StrokeVertex_Type, &obj1))
|
||||
{
|
||||
if (!obj1) {
|
||||
self->sv = new StrokeVertex();
|
||||
}
|
||||
else {
|
||||
if (!((BPy_StrokeVertex *)obj1)->sv) {
|
||||
PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid StrokeVertex object");
|
||||
return -1;
|
||||
}
|
||||
self->sv = new StrokeVertex(*(((BPy_StrokeVertex *)obj1)->sv));
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!O!f",
|
||||
(char **)kwlist_2,
|
||||
&StrokeVertex_Type,
|
||||
&obj1,
|
||||
&StrokeVertex_Type,
|
||||
&obj2,
|
||||
&t3d))
|
||||
{
|
||||
StrokeVertex *sv1 = ((BPy_StrokeVertex *)obj1)->sv;
|
||||
StrokeVertex *sv2 = ((BPy_StrokeVertex *)obj2)->sv;
|
||||
if (!sv1 || (sv1->A() == nullptr && sv1->B() == nullptr)) {
|
||||
PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid StrokeVertex object");
|
||||
return -1;
|
||||
}
|
||||
if (!sv2 || (sv2->A() == nullptr && sv2->B() == nullptr)) {
|
||||
PyErr_SetString(PyExc_TypeError, "argument 2 is an invalid StrokeVertex object");
|
||||
return -1;
|
||||
}
|
||||
self->sv = new StrokeVertex(sv1, sv2, t3d);
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!", (char **)kwlist_3, &CurvePoint_Type, &obj1))
|
||||
{
|
||||
CurvePoint *cp = ((BPy_CurvePoint *)obj1)->cp;
|
||||
if (!cp || cp->A() == nullptr || cp->B() == nullptr) {
|
||||
PyErr_SetString(PyExc_TypeError, "argument 1 is an invalid CurvePoint object");
|
||||
return -1;
|
||||
}
|
||||
self->sv = new StrokeVertex(cp);
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
(void)(obj2 = nullptr),
|
||||
PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!|O!",
|
||||
(char **)kwlist_4,
|
||||
&SVertex_Type,
|
||||
&obj1,
|
||||
&StrokeAttribute_Type,
|
||||
&obj2))
|
||||
{
|
||||
if (!obj2) {
|
||||
self->sv = new StrokeVertex(((BPy_SVertex *)obj1)->sv);
|
||||
}
|
||||
else {
|
||||
self->sv = new StrokeVertex(((BPy_SVertex *)obj1)->sv, *(((BPy_StrokeAttribute *)obj2)->sa));
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_cp.cp = self->sv;
|
||||
self->py_cp.py_if0D.if0D = self->sv;
|
||||
self->py_cp.py_if0D.borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// real operator[] (const int i) const
|
||||
// real & operator[] (const int i)
|
||||
|
||||
/*----------------------mathutils callbacks ----------------------------*/
|
||||
|
||||
static int StrokeVertex_mathutils_check(blender::BaseMathObject *bmo)
|
||||
{
|
||||
if (!BPy_StrokeVertex_Check(bmo->cb_user)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int StrokeVertex_mathutils_get(blender::BaseMathObject *bmo, int /*subtype*/)
|
||||
{
|
||||
BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
|
||||
bmo->data[0] = float(self->sv->x());
|
||||
bmo->data[1] = float(self->sv->y());
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int StrokeVertex_mathutils_set(blender::BaseMathObject *bmo, int /*subtype*/)
|
||||
{
|
||||
BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
|
||||
self->sv->setX((real)bmo->data[0]);
|
||||
self->sv->setY((real)bmo->data[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int StrokeVertex_mathutils_get_index(blender::BaseMathObject *bmo,
|
||||
int /*subtype*/,
|
||||
int index)
|
||||
{
|
||||
BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
|
||||
switch (index) {
|
||||
case 0:
|
||||
bmo->data[0] = float(self->sv->x());
|
||||
break;
|
||||
case 1:
|
||||
bmo->data[1] = float(self->sv->y());
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int StrokeVertex_mathutils_set_index(blender::BaseMathObject *bmo,
|
||||
int /*subtype*/,
|
||||
int index)
|
||||
{
|
||||
BPy_StrokeVertex *self = (BPy_StrokeVertex *)bmo->cb_user;
|
||||
switch (index) {
|
||||
case 0:
|
||||
self->sv->setX((real)bmo->data[0]);
|
||||
break;
|
||||
case 1:
|
||||
self->sv->setY((real)bmo->data[1]);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static blender::Mathutils_Callback StrokeVertex_mathutils_cb = {
|
||||
StrokeVertex_mathutils_check,
|
||||
StrokeVertex_mathutils_get,
|
||||
StrokeVertex_mathutils_set,
|
||||
StrokeVertex_mathutils_get_index,
|
||||
StrokeVertex_mathutils_set_index,
|
||||
};
|
||||
|
||||
static uchar StrokeVertex_mathutils_cb_index = -1;
|
||||
|
||||
void StrokeVertex_mathutils_register_callback()
|
||||
{
|
||||
StrokeVertex_mathutils_cb_index = Mathutils_RegisterCallback(&StrokeVertex_mathutils_cb);
|
||||
}
|
||||
|
||||
/*----------------------StrokeVertex get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeVertex_attribute_doc,
|
||||
"StrokeAttribute for this StrokeVertex.\n"
|
||||
"\n"
|
||||
":type: :class:`StrokeAttribute`\n");
|
||||
static PyObject *StrokeVertex_attribute_get(BPy_StrokeVertex *self, void * /*closure*/)
|
||||
{
|
||||
return BPy_StrokeAttribute_from_StrokeAttribute(self->sv->attribute());
|
||||
}
|
||||
|
||||
static int StrokeVertex_attribute_set(BPy_StrokeVertex *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_StrokeAttribute_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a StrokeAttribute object");
|
||||
return -1;
|
||||
}
|
||||
self->sv->setAttribute(*(((BPy_StrokeAttribute *)value)->sa));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeVertex_curvilinear_abscissa_doc,
|
||||
"Curvilinear abscissa of this StrokeVertex in the Stroke.\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *StrokeVertex_curvilinear_abscissa_get(BPy_StrokeVertex *self, void * /*closure*/)
|
||||
{
|
||||
return PyFloat_FromDouble(self->sv->curvilinearAbscissa());
|
||||
}
|
||||
|
||||
static int StrokeVertex_curvilinear_abscissa_set(BPy_StrokeVertex *self,
|
||||
PyObject *value,
|
||||
void * /*closure*/)
|
||||
{
|
||||
float scalar;
|
||||
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
|
||||
/* parsed item not a number */
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a number");
|
||||
return -1;
|
||||
}
|
||||
self->sv->setCurvilinearAbscissa(scalar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeVertex_point_doc,
|
||||
"2D point coordinates.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Vector`\n");
|
||||
static PyObject *StrokeVertex_point_get(BPy_StrokeVertex *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Vector_CreatePyObject_cb(
|
||||
(PyObject *)self, 2, StrokeVertex_mathutils_cb_index, 0);
|
||||
}
|
||||
|
||||
static int StrokeVertex_point_set(BPy_StrokeVertex *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float v[2];
|
||||
if (blender::mathutils_array_parse(v, 2, 2, value, "value must be a 2-dimensional vector") == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
self->sv->setX(v[0]);
|
||||
self->sv->setY(v[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeVertex_stroke_length_doc,
|
||||
"Stroke length (it is only a value retained by the StrokeVertex,\n"
|
||||
"and it won't change the real stroke length).\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *StrokeVertex_stroke_length_get(BPy_StrokeVertex *self, void * /*closure*/)
|
||||
{
|
||||
return PyFloat_FromDouble(self->sv->strokeLength());
|
||||
}
|
||||
|
||||
static int StrokeVertex_stroke_length_set(BPy_StrokeVertex *self,
|
||||
PyObject *value,
|
||||
void * /*closure*/)
|
||||
{
|
||||
float scalar;
|
||||
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
|
||||
/* parsed item not a number */
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a number");
|
||||
return -1;
|
||||
}
|
||||
self->sv->setStrokeLength(scalar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
StrokeVertex_u_doc,
|
||||
"Curvilinear abscissa of this StrokeVertex in the Stroke.\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *StrokeVertex_u_get(BPy_StrokeVertex *self, void * /*closure*/)
|
||||
{
|
||||
return PyFloat_FromDouble(self->sv->u());
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_StrokeVertex_getseters[] = {
|
||||
{"attribute",
|
||||
(getter)StrokeVertex_attribute_get,
|
||||
(setter)StrokeVertex_attribute_set,
|
||||
StrokeVertex_attribute_doc,
|
||||
nullptr},
|
||||
{"curvilinear_abscissa",
|
||||
(getter)StrokeVertex_curvilinear_abscissa_get,
|
||||
(setter)StrokeVertex_curvilinear_abscissa_set,
|
||||
StrokeVertex_curvilinear_abscissa_doc,
|
||||
nullptr},
|
||||
{"point",
|
||||
(getter)StrokeVertex_point_get,
|
||||
(setter)StrokeVertex_point_set,
|
||||
StrokeVertex_point_doc,
|
||||
nullptr},
|
||||
{"stroke_length",
|
||||
(getter)StrokeVertex_stroke_length_get,
|
||||
(setter)StrokeVertex_stroke_length_set,
|
||||
StrokeVertex_stroke_length_doc,
|
||||
nullptr},
|
||||
{"u", (getter)StrokeVertex_u_get, (setter) nullptr, StrokeVertex_u_doc, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_StrokeVertex type definition ------------------------------*/
|
||||
|
||||
PyTypeObject StrokeVertex_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "StrokeVertex",
|
||||
/*tp_basicsize*/ sizeof(BPy_StrokeVertex),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ StrokeVertex_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_StrokeVertex_getseters,
|
||||
/*tp_base*/ &CurvePoint_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)StrokeVertex_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,32 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_CurvePoint.h"
|
||||
|
||||
#include "../../../stroke/Stroke.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject StrokeVertex_Type;
|
||||
|
||||
#define BPy_StrokeVertex_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&StrokeVertex_Type))
|
||||
|
||||
/*---------------------------Python BPy_StrokeVertex structure definition----------*/
|
||||
struct BPy_StrokeVertex {
|
||||
BPy_CurvePoint py_cp;
|
||||
Freestyle::StrokeVertex *sv;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_StrokeVertex visible prototypes-----------*/
|
||||
|
||||
void StrokeVertex_mathutils_register_callback();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,141 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_NonTVertex.h"
|
||||
|
||||
#include "../../BPy_Convert.h"
|
||||
#include "../BPy_SVertex.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*----------------------NonTVertex methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
NonTVertex_doc,
|
||||
"Class hierarchy: :class:`Interface0D` > :class:`ViewVertex` > :class:`NonTVertex`\n"
|
||||
"\n"
|
||||
"View vertex for corners, cusps, etc. associated to a single SVertex.\n"
|
||||
"Can be associated to 2 or more view edges.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(svertex)``\n"
|
||||
"\n"
|
||||
" Builds a :class:`NonTVertex` using the default constructor or a :class:`SVertex`.\n"
|
||||
"\n"
|
||||
" :param svertex: An SVertex object.\n"
|
||||
" :type svertex: :class:`SVertex`\n");
|
||||
|
||||
/* NOTE: No copy constructor in Python because the C++ copy constructor is 'protected'. */
|
||||
|
||||
static int NonTVertex_init(BPy_NonTVertex *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"svertex", nullptr};
|
||||
PyObject *obj = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist, &SVertex_Type, &obj)) {
|
||||
return -1;
|
||||
}
|
||||
if (!obj) {
|
||||
self->ntv = new NonTVertex();
|
||||
}
|
||||
else {
|
||||
self->ntv = new NonTVertex(((BPy_SVertex *)obj)->sv);
|
||||
}
|
||||
self->py_vv.vv = self->ntv;
|
||||
self->py_vv.py_if0D.if0D = self->ntv;
|
||||
self->py_vv.py_if0D.borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------NonTVertex get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
NonTVertex_svertex_doc,
|
||||
"The SVertex on top of which this NonTVertex is built.\n"
|
||||
"\n"
|
||||
":type: :class:`SVertex`\n");
|
||||
static PyObject *NonTVertex_svertex_get(BPy_NonTVertex *self, void * /*closure*/)
|
||||
{
|
||||
SVertex *v = self->ntv->svertex();
|
||||
if (v) {
|
||||
return BPy_SVertex_from_SVertex(*v);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int NonTVertex_svertex_set(BPy_NonTVertex *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_SVertex_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
|
||||
return -1;
|
||||
}
|
||||
self->ntv->setSVertex(((BPy_SVertex *)value)->sv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_NonTVertex_getseters[] = {
|
||||
{"svertex",
|
||||
(getter)NonTVertex_svertex_get,
|
||||
(setter)NonTVertex_svertex_set,
|
||||
NonTVertex_svertex_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_NonTVertex type definition ------------------------------*/
|
||||
|
||||
PyTypeObject NonTVertex_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "NonTVertex",
|
||||
/*tp_basicsize*/ sizeof(BPy_NonTVertex),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ NonTVertex_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_NonTVertex_getseters,
|
||||
/*tp_base*/ &ViewVertex_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)NonTVertex_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,27 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_ViewVertex.h"
|
||||
|
||||
#include "../../../view_map/ViewMap.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject NonTVertex_Type;
|
||||
|
||||
#define BPy_NonTVertex_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&NonTVertex_Type))
|
||||
|
||||
/*---------------------------Python BPy_NonTVertex structure definition----------*/
|
||||
struct BPy_NonTVertex {
|
||||
BPy_ViewVertex py_vv;
|
||||
Freestyle::NonTVertex *ntv;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,270 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_TVertex.h"
|
||||
|
||||
#include "../../BPy_Convert.h"
|
||||
#include "../../BPy_Id.h"
|
||||
#include "../../Interface1D/BPy_FEdge.h"
|
||||
#include "../../Interface1D/BPy_ViewEdge.h"
|
||||
#include "../BPy_SVertex.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*----------------------TVertex methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
TVertex_doc,
|
||||
"Class hierarchy: :class:`Interface0D` > :class:`ViewVertex` > :class:`TVertex`\n"
|
||||
"\n"
|
||||
"Class to define a T vertex, i.e. an intersection between two edges.\n"
|
||||
"It points towards two SVertex and four ViewEdges. Among the\n"
|
||||
"ViewEdges, two are front and the other two are back. Basically a\n"
|
||||
"front edge hides part of a back edge. So, among the back edges, one\n"
|
||||
"is of invisibility N and the other of invisibility N+1.\n"
|
||||
"\n"
|
||||
".. method:: __init__()\n"
|
||||
"\n"
|
||||
" Default constructor.\n");
|
||||
|
||||
/* NOTE: No copy constructor in Python because the C++ copy constructor is 'protected'. */
|
||||
|
||||
static int TVertex_init(BPy_TVertex *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {nullptr};
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "", (char **)kwlist)) {
|
||||
return -1;
|
||||
}
|
||||
self->tv = new TVertex();
|
||||
self->py_vv.vv = self->tv;
|
||||
self->py_vv.py_if0D.if0D = self->tv;
|
||||
self->py_vv.py_if0D.borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
TVertex_get_svertex_doc,
|
||||
".. method:: get_svertex(fedge)\n"
|
||||
"\n"
|
||||
" Returns the SVertex (among the 2) belonging to the given FEdge.\n"
|
||||
"\n"
|
||||
" :param fedge: An FEdge object.\n"
|
||||
" :type fedge: :class:`FEdge`\n"
|
||||
" :return: The SVertex belonging to the given FEdge.\n"
|
||||
" :rtype: :class:`SVertex`\n");
|
||||
static PyObject *TVertex_get_svertex(BPy_TVertex *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"fedge", nullptr};
|
||||
PyObject *py_fe;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &FEdge_Type, &py_fe)) {
|
||||
return nullptr;
|
||||
}
|
||||
SVertex *sv = self->tv->getSVertex(((BPy_FEdge *)py_fe)->fe);
|
||||
if (sv) {
|
||||
return BPy_SVertex_from_SVertex(*sv);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
TVertex_get_mate_doc,
|
||||
".. method:: get_mate(viewedge)\n"
|
||||
"\n"
|
||||
" Returns the mate edge of the ViewEdge given as argument. If the\n"
|
||||
" ViewEdge is frontEdgeA, frontEdgeB is returned. If the ViewEdge is\n"
|
||||
" frontEdgeB, frontEdgeA is returned. Same for back edges.\n"
|
||||
"\n"
|
||||
" :param viewedge: A ViewEdge object.\n"
|
||||
" :type viewedge: :class:`ViewEdge`\n"
|
||||
" :return: The mate edge of the given ViewEdge.\n"
|
||||
" :rtype: :class:`ViewEdge`\n");
|
||||
static PyObject *TVertex_get_mate(BPy_TVertex *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"viewedge", nullptr};
|
||||
PyObject *py_ve;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &ViewEdge_Type, &py_ve)) {
|
||||
return nullptr;
|
||||
}
|
||||
ViewEdge *ve = self->tv->mate(((BPy_ViewEdge *)py_ve)->ve);
|
||||
if (ve) {
|
||||
return BPy_ViewEdge_from_ViewEdge(*ve);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_TVertex_methods[] = {
|
||||
{"get_svertex",
|
||||
(PyCFunction)TVertex_get_svertex,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
TVertex_get_svertex_doc},
|
||||
{"get_mate",
|
||||
(PyCFunction)TVertex_get_mate,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
TVertex_get_mate_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------TVertex get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
TVertex_front_svertex_doc,
|
||||
"The SVertex that is closer to the viewpoint.\n"
|
||||
"\n"
|
||||
":type: :class:`SVertex`\n");
|
||||
static PyObject *TVertex_front_svertex_get(BPy_TVertex *self, void * /*closure*/)
|
||||
{
|
||||
SVertex *v = self->tv->frontSVertex();
|
||||
if (v) {
|
||||
return BPy_SVertex_from_SVertex(*v);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int TVertex_front_svertex_set(BPy_TVertex *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_SVertex_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
|
||||
return -1;
|
||||
}
|
||||
self->tv->setFrontSVertex(((BPy_SVertex *)value)->sv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
TVertex_back_svertex_doc,
|
||||
"The SVertex that is further away from the viewpoint.\n"
|
||||
"\n"
|
||||
":type: :class:`SVertex`\n");
|
||||
static PyObject *TVertex_back_svertex_get(BPy_TVertex *self, void * /*closure*/)
|
||||
{
|
||||
SVertex *v = self->tv->backSVertex();
|
||||
if (v) {
|
||||
return BPy_SVertex_from_SVertex(*v);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int TVertex_back_svertex_set(BPy_TVertex *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_SVertex_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
|
||||
return -1;
|
||||
}
|
||||
self->tv->setBackSVertex(((BPy_SVertex *)value)->sv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
TVertex_id_doc,
|
||||
"The Id of this TVertex.\n"
|
||||
"\n"
|
||||
":type: :class:`Id`\n");
|
||||
static PyObject *TVertex_id_get(BPy_TVertex *self, void * /*closure*/)
|
||||
{
|
||||
Id id(self->tv->getId());
|
||||
return BPy_Id_from_Id(id); // return a copy
|
||||
}
|
||||
|
||||
static int TVertex_id_set(BPy_TVertex *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_Id_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an Id");
|
||||
return -1;
|
||||
}
|
||||
self->tv->setId(*(((BPy_Id *)value)->id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_TVertex_getseters[] = {
|
||||
{"front_svertex",
|
||||
(getter)TVertex_front_svertex_get,
|
||||
(setter)TVertex_front_svertex_set,
|
||||
TVertex_front_svertex_doc,
|
||||
nullptr},
|
||||
{"back_svertex",
|
||||
(getter)TVertex_back_svertex_get,
|
||||
(setter)TVertex_back_svertex_set,
|
||||
TVertex_back_svertex_doc,
|
||||
nullptr},
|
||||
{"id", (getter)TVertex_id_get, (setter)TVertex_id_set, TVertex_id_doc, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_TVertex type definition ------------------------------*/
|
||||
|
||||
PyTypeObject TVertex_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "TVertex",
|
||||
/*tp_basicsize*/ sizeof(BPy_TVertex),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ TVertex_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_TVertex_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_TVertex_getseters,
|
||||
/*tp_base*/ &ViewVertex_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)TVertex_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,27 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_ViewVertex.h"
|
||||
|
||||
#include "../../../view_map/ViewMap.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject TVertex_Type;
|
||||
|
||||
#define BPy_TVertex_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&TVertex_Type))
|
||||
|
||||
/*---------------------------Python BPy_TVertex structure definition----------*/
|
||||
struct BPy_TVertex {
|
||||
BPy_ViewVertex py_vv;
|
||||
Freestyle::TVertex *tv;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,391 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_FEdge.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../BPy_Id.h"
|
||||
#include "../BPy_Nature.h"
|
||||
#include "../Interface0D/BPy_SVertex.h"
|
||||
#include "../Interface1D/BPy_ViewEdge.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*----------------------FEdge methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdge_doc,
|
||||
"Class hierarchy: :class:`Interface1D` > :class:`FEdge`\n"
|
||||
"\n"
|
||||
"Base Class for feature edges. This FEdge can represent a silhouette,\n"
|
||||
"a crease, a ridge/valley, a border or a suggestive contour. For\n"
|
||||
"silhouettes, the FEdge is oriented so that the visible face lies on\n"
|
||||
"the left of the edge. For borders, the FEdge is oriented so that the\n"
|
||||
"face lies on the left of the edge. An FEdge can represent an initial\n"
|
||||
"edge of the mesh or runs across a face of the initial mesh depending\n"
|
||||
"on the smoothness or sharpness of the mesh. This class is specialized\n"
|
||||
"into a smooth and a sharp version since their properties slightly vary\n"
|
||||
"from one to the other.\n"
|
||||
"\n"
|
||||
".. method:: FEdge(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``FEdge()``\n"
|
||||
" - ``FEdge(brother)``\n"
|
||||
"\n"
|
||||
" Builds an :class:`FEdge` using the default constructor,\n"
|
||||
" copy constructor, or between two :class:`SVertex` objects.\n"
|
||||
"\n"
|
||||
" :param brother: An FEdge object.\n"
|
||||
" :type brother: :class:`FEdge`\n"
|
||||
" :param first_vertex: The first SVertex.\n"
|
||||
" :type first_vertex: :class:`SVertex`\n"
|
||||
" :param second_vertex: The second SVertex.\n"
|
||||
" :type second_vertex: :class:`SVertex`\n");
|
||||
static int FEdge_init(BPy_FEdge *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"first_vertex", "second_vertex", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &FEdge_Type, &obj1)) {
|
||||
if (!obj1) {
|
||||
self->fe = new FEdge();
|
||||
}
|
||||
else {
|
||||
self->fe = new FEdge(*(((BPy_FEdge *)obj1)->fe));
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!O!", (char **)kwlist_2, &SVertex_Type, &obj1, &SVertex_Type, &obj2))
|
||||
{
|
||||
self->fe = new FEdge(((BPy_SVertex *)obj1)->sv, ((BPy_SVertex *)obj2)->sv);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_if1D.if1D = self->fe;
|
||||
self->py_if1D.borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------FEdge sequence protocol ----------------------------*/
|
||||
|
||||
static Py_ssize_t FEdge_sq_length(BPy_FEdge * /*self*/)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static PyObject *FEdge_sq_item(BPy_FEdge *self, Py_ssize_t keynum)
|
||||
{
|
||||
if (keynum < 0) {
|
||||
keynum += FEdge_sq_length(self);
|
||||
}
|
||||
if (ELEM(keynum, 0, 1)) {
|
||||
SVertex *v = self->fe->operator[](keynum);
|
||||
if (v) {
|
||||
return BPy_SVertex_from_SVertex(*v);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
PyErr_Format(PyExc_IndexError, "FEdge[index]: index %d out of range", keynum);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static PySequenceMethods BPy_FEdge_as_sequence = {
|
||||
/*sq_length*/ (lenfunc)FEdge_sq_length,
|
||||
/*sq_concat*/ nullptr,
|
||||
/*sq_repeat*/ nullptr,
|
||||
/*sq_item*/ (ssizeargfunc)FEdge_sq_item,
|
||||
/*was_sq_slice*/ nullptr, /* DEPRECATED. */
|
||||
/*sq_ass_item*/ nullptr,
|
||||
/*was_sq_ass_slice*/ nullptr, /* DEPRECATED. */
|
||||
/*sq_contains*/ nullptr,
|
||||
/*sq_inplace_concat*/ nullptr,
|
||||
/*sq_inplace_repeat*/ nullptr,
|
||||
};
|
||||
|
||||
/*----------------------FEdge get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdge_first_svertex_doc,
|
||||
"The first SVertex constituting this FEdge.\n"
|
||||
"\n"
|
||||
":type: :class:`SVertex`\n");
|
||||
static PyObject *FEdge_first_svertex_get(BPy_FEdge *self, void * /*closure*/)
|
||||
{
|
||||
SVertex *A = self->fe->vertexA();
|
||||
if (A) {
|
||||
return BPy_SVertex_from_SVertex(*A);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int FEdge_first_svertex_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_SVertex_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
|
||||
return -1;
|
||||
}
|
||||
self->fe->setVertexA(((BPy_SVertex *)value)->sv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdge_second_svertex_doc,
|
||||
"The second SVertex constituting this FEdge.\n"
|
||||
"\n"
|
||||
":type: :class:`SVertex`\n");
|
||||
static PyObject *FEdge_second_svertex_get(BPy_FEdge *self, void * /*closure*/)
|
||||
{
|
||||
SVertex *B = self->fe->vertexB();
|
||||
if (B) {
|
||||
return BPy_SVertex_from_SVertex(*B);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int FEdge_second_svertex_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_SVertex_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an SVertex");
|
||||
return -1;
|
||||
}
|
||||
self->fe->setVertexB(((BPy_SVertex *)value)->sv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdge_next_fedge_doc,
|
||||
"The FEdge following this one in the ViewEdge. The value is None if\n"
|
||||
"this FEdge is the last of the ViewEdge.\n"
|
||||
"\n"
|
||||
":type: :class:`FEdge`\n");
|
||||
static PyObject *FEdge_next_fedge_get(BPy_FEdge *self, void * /*closure*/)
|
||||
{
|
||||
FEdge *fe = self->fe->nextEdge();
|
||||
if (fe) {
|
||||
return Any_BPy_FEdge_from_FEdge(*fe);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int FEdge_next_fedge_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_FEdge_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an FEdge");
|
||||
return -1;
|
||||
}
|
||||
self->fe->setNextEdge(((BPy_FEdge *)value)->fe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdge_previous_fedge_doc,
|
||||
"The FEdge preceding this one in the ViewEdge. The value is None if\n"
|
||||
"this FEdge is the first one of the ViewEdge.\n"
|
||||
"\n"
|
||||
":type: :class:`FEdge`\n");
|
||||
static PyObject *FEdge_previous_fedge_get(BPy_FEdge *self, void * /*closure*/)
|
||||
{
|
||||
FEdge *fe = self->fe->previousEdge();
|
||||
if (fe) {
|
||||
return Any_BPy_FEdge_from_FEdge(*fe);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int FEdge_previous_fedge_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_FEdge_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an FEdge");
|
||||
return -1;
|
||||
}
|
||||
self->fe->setPreviousEdge(((BPy_FEdge *)value)->fe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdge_viewedge_doc,
|
||||
"The ViewEdge to which this FEdge belongs to.\n"
|
||||
"\n"
|
||||
":type: :class:`ViewEdge`\n");
|
||||
static PyObject *FEdge_viewedge_get(BPy_FEdge *self, void * /*closure*/)
|
||||
{
|
||||
ViewEdge *ve = self->fe->viewedge();
|
||||
if (ve) {
|
||||
return BPy_ViewEdge_from_ViewEdge(*ve);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int FEdge_viewedge_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_ViewEdge_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an ViewEdge");
|
||||
return -1;
|
||||
}
|
||||
self->fe->setViewEdge(((BPy_ViewEdge *)value)->ve);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdge_is_smooth_doc,
|
||||
"True if this FEdge is a smooth FEdge.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *FEdge_is_smooth_get(BPy_FEdge *self, void * /*closure*/)
|
||||
{
|
||||
return PyBool_from_bool(self->fe->isSmooth());
|
||||
}
|
||||
|
||||
static int FEdge_is_smooth_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!PyBool_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be boolean");
|
||||
return -1;
|
||||
}
|
||||
self->fe->setSmooth(bool_from_PyBool(value));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdge_id_doc,
|
||||
"The Id of this FEdge.\n"
|
||||
"\n"
|
||||
":type: :class:`Id`\n");
|
||||
static PyObject *FEdge_id_get(BPy_FEdge *self, void * /*closure*/)
|
||||
{
|
||||
Id id(self->fe->getId());
|
||||
return BPy_Id_from_Id(id); // return a copy
|
||||
}
|
||||
|
||||
static int FEdge_id_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_Id_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an Id");
|
||||
return -1;
|
||||
}
|
||||
self->fe->setId(*(((BPy_Id *)value)->id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdge_nature_doc,
|
||||
"The nature of this FEdge.\n"
|
||||
"\n"
|
||||
":type: :class:`Nature`\n");
|
||||
static PyObject *FEdge_nature_get(BPy_FEdge *self, void * /*closure*/)
|
||||
{
|
||||
return BPy_Nature_from_Nature(self->fe->getNature());
|
||||
}
|
||||
|
||||
static int FEdge_nature_set(BPy_FEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_Nature_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a Nature");
|
||||
return -1;
|
||||
}
|
||||
self->fe->setNature(PyLong_AsLong((PyObject *)&((BPy_Nature *)value)->i));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_FEdge_getseters[] = {
|
||||
{"first_svertex",
|
||||
(getter)FEdge_first_svertex_get,
|
||||
(setter)FEdge_first_svertex_set,
|
||||
FEdge_first_svertex_doc,
|
||||
nullptr},
|
||||
{"second_svertex",
|
||||
(getter)FEdge_second_svertex_get,
|
||||
(setter)FEdge_second_svertex_set,
|
||||
FEdge_second_svertex_doc,
|
||||
nullptr},
|
||||
{"next_fedge",
|
||||
(getter)FEdge_next_fedge_get,
|
||||
(setter)FEdge_next_fedge_set,
|
||||
FEdge_next_fedge_doc,
|
||||
nullptr},
|
||||
{"previous_fedge",
|
||||
(getter)FEdge_previous_fedge_get,
|
||||
(setter)FEdge_previous_fedge_set,
|
||||
FEdge_previous_fedge_doc,
|
||||
nullptr},
|
||||
{"viewedge",
|
||||
(getter)FEdge_viewedge_get,
|
||||
(setter)FEdge_viewedge_set,
|
||||
FEdge_viewedge_doc,
|
||||
nullptr},
|
||||
{"is_smooth",
|
||||
(getter)FEdge_is_smooth_get,
|
||||
(setter)FEdge_is_smooth_set,
|
||||
FEdge_is_smooth_doc,
|
||||
nullptr},
|
||||
{"id", (getter)FEdge_id_get, (setter)FEdge_id_set, FEdge_id_doc, nullptr},
|
||||
{"nature", (getter)FEdge_nature_get, (setter)FEdge_nature_set, FEdge_nature_doc, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_FEdge type definition ------------------------------*/
|
||||
|
||||
PyTypeObject FEdge_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "FEdge",
|
||||
/*tp_basicsize*/ sizeof(BPy_FEdge),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ &BPy_FEdge_as_sequence,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ FEdge_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_FEdge_getseters,
|
||||
/*tp_base*/ &Interface1D_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)FEdge_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,27 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_Interface1D.h"
|
||||
|
||||
#include "../../view_map/Silhouette.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject FEdge_Type;
|
||||
|
||||
#define BPy_FEdge_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&FEdge_Type))
|
||||
|
||||
/*---------------------------Python BPy_FEdge structure definition----------*/
|
||||
struct BPy_FEdge {
|
||||
BPy_Interface1D py_if1D;
|
||||
Freestyle::FEdge *fe;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,243 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_FrsCurve.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../BPy_Id.h"
|
||||
#include "../Interface0D/BPy_CurvePoint.h"
|
||||
#include "../Interface0D/BPy_SVertex.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*----------------------CurvePoint methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsCurve_doc,
|
||||
"Class hierarchy: :class:`Interface1D` > :class:`Curve`\n"
|
||||
"\n"
|
||||
"Base class for curves made of CurvePoints. :class:`SVertex` is the\n"
|
||||
"type of the initial curve vertices. A :class:`Chain` is a\n"
|
||||
"specialization of a Curve.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(id)``\n"
|
||||
"\n"
|
||||
" Builds a :class:`FrsCurve` using a default constructor,\n"
|
||||
" copy constructor or from an :class:`Id`.\n"
|
||||
"\n"
|
||||
" :param brother: A Curve object.\n"
|
||||
" :type brother: :class:`Curve`\n"
|
||||
" :param id: An Id object.\n"
|
||||
" :type id: :class:`Id`\n");
|
||||
static int FrsCurve_init(BPy_FrsCurve *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"id", nullptr};
|
||||
PyObject *obj = nullptr;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &FrsCurve_Type, &obj)) {
|
||||
if (!obj) {
|
||||
self->c = new Curve();
|
||||
}
|
||||
else {
|
||||
self->c = new Curve(*(((BPy_FrsCurve *)obj)->c));
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_2, &Id_Type, &obj))
|
||||
{
|
||||
self->c = new Curve(*(((BPy_Id *)obj)->id));
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_if1D.if1D = self->c;
|
||||
self->py_if1D.borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsCurve_push_vertex_back_doc,
|
||||
".. method:: push_vertex_back(vertex)\n"
|
||||
"\n"
|
||||
" Adds a single vertex at the end of the Curve.\n"
|
||||
"\n"
|
||||
" :param vertex: A vertex object.\n"
|
||||
" :type vertex: :class:`SVertex` | :class:`CurvePoint`\n");
|
||||
static PyObject *FrsCurve_push_vertex_back(BPy_FrsCurve *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"vertex", nullptr};
|
||||
PyObject *obj = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", (char **)kwlist, &obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (BPy_CurvePoint_Check(obj)) {
|
||||
self->c->push_vertex_back(((BPy_CurvePoint *)obj)->cp);
|
||||
}
|
||||
else if (BPy_SVertex_Check(obj)) {
|
||||
self->c->push_vertex_back(((BPy_SVertex *)obj)->sv);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument");
|
||||
return nullptr;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsCurve_push_vertex_front_doc,
|
||||
".. method:: push_vertex_front(vertex)\n"
|
||||
"\n"
|
||||
" Adds a single vertex at the front of the Curve.\n"
|
||||
"\n"
|
||||
" :param vertex: A vertex object.\n"
|
||||
" :type vertex: :class:`SVertex` | :class:`CurvePoint`\n");
|
||||
static PyObject *FrsCurve_push_vertex_front(BPy_FrsCurve *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"vertex", nullptr};
|
||||
PyObject *obj = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", (char **)kwlist, &obj)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (BPy_CurvePoint_Check(obj)) {
|
||||
self->c->push_vertex_front(((BPy_CurvePoint *)obj)->cp);
|
||||
}
|
||||
else if (BPy_SVertex_Check(obj)) {
|
||||
self->c->push_vertex_front(((BPy_SVertex *)obj)->sv);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument");
|
||||
return nullptr;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_FrsCurve_methods[] = {
|
||||
{"push_vertex_back",
|
||||
(PyCFunction)FrsCurve_push_vertex_back,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
FrsCurve_push_vertex_back_doc},
|
||||
{"push_vertex_front",
|
||||
(PyCFunction)FrsCurve_push_vertex_front,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
FrsCurve_push_vertex_front_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------CurvePoint get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsCurve_is_empty_doc,
|
||||
"True if the Curve doesn't have any Vertex yet.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *FrsCurve_is_empty_get(BPy_FrsCurve *self, void * /*closure*/)
|
||||
{
|
||||
return PyBool_from_bool(self->c->empty());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FrsCurve_segments_size_doc,
|
||||
"The number of segments in the polyline constituting the Curve.\n"
|
||||
"\n"
|
||||
":type: int\n");
|
||||
static PyObject *FrsCurve_segments_size_get(BPy_FrsCurve *self, void * /*closure*/)
|
||||
{
|
||||
return PyLong_FromLong(self->c->nSegments());
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_FrsCurve_getseters[] = {
|
||||
{"is_empty", (getter)FrsCurve_is_empty_get, (setter) nullptr, FrsCurve_is_empty_doc, nullptr},
|
||||
{"segments_size",
|
||||
(getter)FrsCurve_segments_size_get,
|
||||
(setter) nullptr,
|
||||
FrsCurve_segments_size_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_FrsCurve type definition ------------------------------*/
|
||||
|
||||
PyTypeObject FrsCurve_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Curve",
|
||||
/*tp_basicsize*/ sizeof(BPy_FrsCurve),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ FrsCurve_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_FrsCurve_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_FrsCurve_getseters,
|
||||
/*tp_base*/ &Interface1D_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)FrsCurve_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,27 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_Interface1D.h"
|
||||
|
||||
#include "../../stroke/Curve.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject FrsCurve_Type;
|
||||
|
||||
#define BPy_FrsCurve_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&FrsCurve_Type))
|
||||
|
||||
/*---------------------------Python BPy_FrsCurve structure definition----------*/
|
||||
struct BPy_FrsCurve {
|
||||
BPy_Interface1D py_if1D;
|
||||
Freestyle::Curve *c;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,572 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_Stroke.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../BPy_Id.h"
|
||||
#include "../BPy_MediumType.h"
|
||||
#include "../Interface0D/BPy_SVertex.h"
|
||||
#include "../Interface0D/CurvePoint/BPy_StrokeVertex.h"
|
||||
#include "../Iterator/BPy_StrokeVertexIterator.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*----------------------Stroke methods ----------------------------*/
|
||||
|
||||
// Stroke ()
|
||||
// template<class InputVertexIterator> Stroke (InputVertexIterator begin, InputVertexIterator end)
|
||||
//
|
||||
// pb: - need to be able to switch representation: InputVertexIterator <=> position
|
||||
// - is it even used ? not even in SWIG version
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_doc,
|
||||
"Class hierarchy: :class:`Interface1D` > :class:`Stroke`\n"
|
||||
"\n"
|
||||
"Class to define a stroke. A stroke is made of a set of 2D vertices\n"
|
||||
"(:class:`StrokeVertex`), regularly spaced out. This set of vertices\n"
|
||||
"defines the stroke's backbone geometry. Each of these stroke vertices\n"
|
||||
"defines the stroke's shape and appearance at this vertex position.\n"
|
||||
"\n"
|
||||
".. method:: Stroke(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``Stroke()``\n"
|
||||
" - ``Stroke(brother)``\n"
|
||||
"\n"
|
||||
" Creates a :class:`Stroke` using the default constructor or copy constructor\n");
|
||||
static int Stroke_init(BPy_Stroke *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"brother", nullptr};
|
||||
PyObject *brother = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist, &Stroke_Type, &brother)) {
|
||||
return -1;
|
||||
}
|
||||
if (!brother) {
|
||||
self->s = new Stroke();
|
||||
}
|
||||
else {
|
||||
self->s = new Stroke(*(((BPy_Stroke *)brother)->s));
|
||||
}
|
||||
self->py_if1D.if1D = self->s;
|
||||
self->py_if1D.borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *Stroke_iter(PyObject *self)
|
||||
{
|
||||
StrokeInternal::StrokeVertexIterator sv_it(((BPy_Stroke *)self)->s->strokeVerticesBegin());
|
||||
return BPy_StrokeVertexIterator_from_StrokeVertexIterator(sv_it, false);
|
||||
}
|
||||
|
||||
static Py_ssize_t Stroke_sq_length(BPy_Stroke *self)
|
||||
{
|
||||
return self->s->strokeVerticesSize();
|
||||
}
|
||||
|
||||
static PyObject *Stroke_sq_item(BPy_Stroke *self, Py_ssize_t keynum)
|
||||
{
|
||||
if (keynum < 0) {
|
||||
keynum += Stroke_sq_length(self);
|
||||
}
|
||||
if (keynum < 0 || keynum >= Stroke_sq_length(self)) {
|
||||
PyErr_Format(PyExc_IndexError, "Stroke[index]: index %d out of range", keynum);
|
||||
return nullptr;
|
||||
}
|
||||
return BPy_StrokeVertex_from_StrokeVertex(self->s->strokeVerticeAt(keynum));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_compute_sampling_doc,
|
||||
".. method:: compute_sampling(n)\n"
|
||||
"\n"
|
||||
" Compute the sampling needed to get N vertices. If the\n"
|
||||
" specified number of vertices is less than the actual number of\n"
|
||||
" vertices, the actual sampling value is returned. (To remove Vertices,\n"
|
||||
" use the RemoveVertex() method of this class.)\n"
|
||||
"\n"
|
||||
" :param n: The number of stroke vertices we eventually want\n"
|
||||
" in our Stroke.\n"
|
||||
" :type n: int\n"
|
||||
" :return: The sampling that must be used in the Resample(float)\n"
|
||||
" method.\n"
|
||||
" :rtype: float\n");
|
||||
static PyObject *Stroke_compute_sampling(BPy_Stroke *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"n", nullptr};
|
||||
int i;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "i", (char **)kwlist, &i)) {
|
||||
return nullptr;
|
||||
}
|
||||
return PyFloat_FromDouble(self->s->ComputeSampling(i));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_resample_doc,
|
||||
".. method:: resample(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``resample(n)``\n"
|
||||
" - ``resample(sampling)``\n"
|
||||
"\n"
|
||||
" Resamples the stroke so using one of two methods with the goal\n"
|
||||
" of creating a stroke with fewer points and the same shape.\n"
|
||||
"\n"
|
||||
" :param n: Resamples the stroke so that it eventually has N points. That means\n"
|
||||
" it is going to add N-vertices_size, where vertices_size is the\n"
|
||||
" number of points we already have. If vertices_size >= N, no\n"
|
||||
" resampling is done.\n"
|
||||
" :type n: int\n"
|
||||
" :param sampling: Resamples the stroke with a given sampling value. If the\n"
|
||||
" sampling is smaller than the actual sampling value, no resampling is done.\n"
|
||||
" :type sampling: float\n");
|
||||
static PyObject *Stroke_resample(BPy_Stroke *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"n", nullptr};
|
||||
static const char *kwlist_2[] = {"sampling", nullptr};
|
||||
int i;
|
||||
float f;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "i", (char **)kwlist_1, &i)) {
|
||||
if (self->s->Resample(i) < 0) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Stroke resampling (by vertex count) failed");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &f))
|
||||
{
|
||||
if (self->s->Resample(f) < 0) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Stroke resampling (by vertex interval) failed");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument");
|
||||
return nullptr;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_insert_vertex_doc,
|
||||
".. method:: insert_vertex(vertex, next)\n"
|
||||
"\n"
|
||||
" Inserts the StrokeVertex given as argument into the Stroke before the\n"
|
||||
" point specified by next. The length and curvilinear abscissa are\n"
|
||||
" updated consequently.\n"
|
||||
"\n"
|
||||
" :param vertex: The StrokeVertex to insert in the Stroke.\n"
|
||||
" :type vertex: :class:`StrokeVertex`\n"
|
||||
" :param next: A StrokeVertexIterator pointing to the StrokeVertex\n"
|
||||
" before which vertex must be inserted.\n"
|
||||
" :type next: :class:`StrokeVertexIterator`\n");
|
||||
static PyObject *Stroke_insert_vertex(BPy_Stroke *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"vertex", "next", nullptr};
|
||||
PyObject *py_sv = nullptr, *py_sv_it = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!O!",
|
||||
(char **)kwlist,
|
||||
&StrokeVertex_Type,
|
||||
&py_sv,
|
||||
&StrokeVertexIterator_Type,
|
||||
&py_sv_it))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Make the wrapped StrokeVertex internal. */
|
||||
((BPy_StrokeVertex *)py_sv)->py_cp.py_if0D.borrowed = true;
|
||||
|
||||
StrokeVertex *sv = ((BPy_StrokeVertex *)py_sv)->sv;
|
||||
StrokeInternal::StrokeVertexIterator sv_it(*(((BPy_StrokeVertexIterator *)py_sv_it)->sv_it));
|
||||
self->s->InsertVertex(sv, sv_it);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_remove_vertex_doc,
|
||||
".. method:: remove_vertex(vertex)\n"
|
||||
"\n"
|
||||
" Removes the StrokeVertex given as argument from the Stroke. The length\n"
|
||||
" and curvilinear abscissa are updated consequently.\n"
|
||||
"\n"
|
||||
" :param vertex: the StrokeVertex to remove from the Stroke.\n"
|
||||
" :type vertex: :class:`StrokeVertex`\n");
|
||||
static PyObject *Stroke_remove_vertex(BPy_Stroke *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"vertex", nullptr};
|
||||
PyObject *py_sv = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist, &StrokeVertex_Type, &py_sv))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (((BPy_StrokeVertex *)py_sv)->sv) {
|
||||
self->s->RemoveVertex(((BPy_StrokeVertex *)py_sv)->sv);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument");
|
||||
return nullptr;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_remove_all_vertices_doc,
|
||||
".. method:: remove_all_vertices()\n"
|
||||
"\n"
|
||||
" Removes all vertices from the Stroke.\n");
|
||||
static PyObject *Stroke_remove_all_vertices(BPy_Stroke *self)
|
||||
{
|
||||
self->s->RemoveAllVertices();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_update_length_doc,
|
||||
".. method:: update_length()\n"
|
||||
"\n"
|
||||
" Updates the 2D length of the Stroke.\n");
|
||||
static PyObject *Stroke_update_length(BPy_Stroke *self)
|
||||
{
|
||||
self->s->UpdateLength();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_stroke_vertices_begin_doc,
|
||||
".. method:: stroke_vertices_begin(t=0.0)\n"
|
||||
"\n"
|
||||
" Returns a StrokeVertexIterator pointing on the first StrokeVertex of\n"
|
||||
" the Stroke. One can specify a sampling value to re-sample the Stroke\n"
|
||||
" on the fly if needed.\n"
|
||||
"\n"
|
||||
" :param t: The resampling value with which we want our Stroke to be\n"
|
||||
" resampled. If 0 is specified, no resampling is done.\n"
|
||||
" :type t: float\n"
|
||||
" :return: A StrokeVertexIterator pointing on the first StrokeVertex.\n"
|
||||
" :rtype: :class:`StrokeVertexIterator`\n");
|
||||
static PyObject *Stroke_stroke_vertices_begin(BPy_Stroke *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"t", nullptr};
|
||||
float f = 0.0f;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|f", (char **)kwlist, &f)) {
|
||||
return nullptr;
|
||||
}
|
||||
StrokeInternal::StrokeVertexIterator sv_it(self->s->strokeVerticesBegin(f));
|
||||
return BPy_StrokeVertexIterator_from_StrokeVertexIterator(sv_it, false);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_stroke_vertices_end_doc,
|
||||
".. method:: stroke_vertices_end()\n"
|
||||
"\n"
|
||||
" Returns a StrokeVertexIterator pointing after the last StrokeVertex\n"
|
||||
" of the Stroke.\n"
|
||||
"\n"
|
||||
" :return: A StrokeVertexIterator pointing after the last StrokeVertex.\n"
|
||||
" :rtype: :class:`StrokeVertexIterator`\n");
|
||||
static PyObject *Stroke_stroke_vertices_end(BPy_Stroke *self)
|
||||
{
|
||||
StrokeInternal::StrokeVertexIterator sv_it(self->s->strokeVerticesEnd());
|
||||
return BPy_StrokeVertexIterator_from_StrokeVertexIterator(sv_it, true);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_reversed_doc,
|
||||
".. method:: __reversed__()\n"
|
||||
"\n"
|
||||
" Returns a StrokeVertexIterator iterating over the vertices of the Stroke\n"
|
||||
" in the reversed order (from the last to the first).\n"
|
||||
"\n"
|
||||
" :return: A StrokeVertexIterator pointing after the last StrokeVertex.\n"
|
||||
" :rtype: :class:`StrokeVertexIterator`\n");
|
||||
static PyObject *Stroke_reversed(BPy_Stroke *self)
|
||||
{
|
||||
StrokeInternal::StrokeVertexIterator sv_it(self->s->strokeVerticesEnd());
|
||||
return BPy_StrokeVertexIterator_from_StrokeVertexIterator(sv_it, true);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_stroke_vertices_size_doc,
|
||||
".. method:: stroke_vertices_size()\n"
|
||||
"\n"
|
||||
" Returns the number of StrokeVertex constituting the Stroke.\n"
|
||||
"\n"
|
||||
" :return: The number of stroke vertices.\n"
|
||||
" :rtype: int\n");
|
||||
static PyObject *Stroke_stroke_vertices_size(BPy_Stroke *self)
|
||||
{
|
||||
return PyLong_FromLong(self->s->strokeVerticesSize());
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_Stroke_methods[] = {
|
||||
{"compute_sampling",
|
||||
(PyCFunction)Stroke_compute_sampling,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
Stroke_compute_sampling_doc},
|
||||
{"resample", (PyCFunction)Stroke_resample, METH_VARARGS | METH_KEYWORDS, Stroke_resample_doc},
|
||||
{"remove_all_vertices",
|
||||
(PyCFunction)Stroke_remove_all_vertices,
|
||||
METH_NOARGS,
|
||||
Stroke_remove_all_vertices_doc},
|
||||
{"remove_vertex",
|
||||
(PyCFunction)Stroke_remove_vertex,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
Stroke_remove_vertex_doc},
|
||||
{"insert_vertex",
|
||||
(PyCFunction)Stroke_insert_vertex,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
Stroke_insert_vertex_doc},
|
||||
{"update_length", (PyCFunction)Stroke_update_length, METH_NOARGS, Stroke_update_length_doc},
|
||||
{"stroke_vertices_begin",
|
||||
(PyCFunction)Stroke_stroke_vertices_begin,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
Stroke_stroke_vertices_begin_doc},
|
||||
{"stroke_vertices_end",
|
||||
(PyCFunction)Stroke_stroke_vertices_end,
|
||||
METH_NOARGS,
|
||||
Stroke_stroke_vertices_end_doc},
|
||||
{"__reversed__", (PyCFunction)Stroke_reversed, METH_NOARGS, Stroke_reversed_doc},
|
||||
{"stroke_vertices_size",
|
||||
(PyCFunction)Stroke_stroke_vertices_size,
|
||||
METH_NOARGS,
|
||||
Stroke_stroke_vertices_size_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------Stroke get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_medium_type_doc,
|
||||
"The MediumType used for this Stroke.\n"
|
||||
"\n"
|
||||
":type: :class:`MediumType`\n");
|
||||
static PyObject *Stroke_medium_type_get(BPy_Stroke *self, void * /*closure*/)
|
||||
{
|
||||
return BPy_MediumType_from_MediumType(self->s->getMediumType());
|
||||
}
|
||||
|
||||
static int Stroke_medium_type_set(BPy_Stroke *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_MediumType_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a MediumType");
|
||||
return -1;
|
||||
}
|
||||
self->s->setMediumType(MediumType_from_BPy_MediumType(value));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_texture_id_doc,
|
||||
"The ID of the texture used to simulate th marks system for this Stroke.\n"
|
||||
"\n"
|
||||
":type: int\n");
|
||||
static PyObject *Stroke_texture_id_get(BPy_Stroke *self, void * /*closure*/)
|
||||
{
|
||||
return PyLong_FromLong(self->s->getTextureId());
|
||||
}
|
||||
|
||||
static int Stroke_texture_id_set(BPy_Stroke *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
uint i = PyLong_AsUnsignedLong(value);
|
||||
if (PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
self->s->setTextureId(i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_tips_doc,
|
||||
"True if this Stroke uses a texture with tips, and false otherwise.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *Stroke_tips_get(BPy_Stroke *self, void * /*closure*/)
|
||||
{
|
||||
return PyBool_from_bool(self->s->hasTips());
|
||||
}
|
||||
|
||||
static int Stroke_tips_set(BPy_Stroke *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!PyBool_Check(value)) {
|
||||
return -1;
|
||||
}
|
||||
self->s->setTips(bool_from_PyBool(value));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_length_2d_doc,
|
||||
"The 2D length of the Stroke.\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *Stroke_length_2d_get(BPy_Stroke *self, void * /*closure*/)
|
||||
{
|
||||
return PyFloat_FromDouble(self->s->getLength2D());
|
||||
}
|
||||
|
||||
static int Stroke_length_2d_set(BPy_Stroke *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float scalar;
|
||||
if ((scalar = PyFloat_AsDouble(value)) == -1.0f && PyErr_Occurred()) {
|
||||
/* parsed item not a number */
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a number");
|
||||
return -1;
|
||||
}
|
||||
self->s->setLength(scalar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Stroke_id_doc,
|
||||
"The Id of this Stroke.\n"
|
||||
"\n"
|
||||
":type: :class:`Id`\n");
|
||||
static PyObject *Stroke_id_get(BPy_Stroke *self, void * /*closure*/)
|
||||
{
|
||||
Id id(self->s->getId());
|
||||
return BPy_Id_from_Id(id); // return a copy
|
||||
}
|
||||
|
||||
static int Stroke_id_set(BPy_Stroke *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_Id_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an Id");
|
||||
return -1;
|
||||
}
|
||||
self->s->setId(*(((BPy_Id *)value)->id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_Stroke_getseters[] = {
|
||||
{"medium_type",
|
||||
(getter)Stroke_medium_type_get,
|
||||
(setter)Stroke_medium_type_set,
|
||||
Stroke_medium_type_doc,
|
||||
nullptr},
|
||||
{"texture_id",
|
||||
(getter)Stroke_texture_id_get,
|
||||
(setter)Stroke_texture_id_set,
|
||||
Stroke_texture_id_doc,
|
||||
nullptr},
|
||||
{"tips", (getter)Stroke_tips_get, (setter)Stroke_tips_set, Stroke_tips_doc, nullptr},
|
||||
{"length_2d",
|
||||
(getter)Stroke_length_2d_get,
|
||||
(setter)Stroke_length_2d_set,
|
||||
Stroke_length_2d_doc,
|
||||
nullptr},
|
||||
{"id", (getter)Stroke_id_get, (setter)Stroke_id_set, Stroke_id_doc, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_Stroke type definition ------------------------------*/
|
||||
|
||||
static PySequenceMethods BPy_Stroke_as_sequence = {
|
||||
/*sq_length*/ (lenfunc)Stroke_sq_length,
|
||||
/*sq_concat*/ nullptr,
|
||||
/*sq_repeat*/ nullptr,
|
||||
/*sq_item*/ (ssizeargfunc)Stroke_sq_item,
|
||||
/*was_sq_slice*/ nullptr, /* DEPRECATED. */
|
||||
/*sq_ass_item*/ nullptr,
|
||||
/*was_sq_ass_slice*/ nullptr, /* DEPRECATED. */
|
||||
/*sq_contains*/ nullptr,
|
||||
/*sq_inplace_concat*/ nullptr,
|
||||
/*sq_inplace_repeat*/ nullptr,
|
||||
};
|
||||
|
||||
PyTypeObject Stroke_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Stroke",
|
||||
/*tp_basicsize*/ sizeof(BPy_Stroke),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ &BPy_Stroke_as_sequence,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ Stroke_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ (getiterfunc)Stroke_iter,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_Stroke_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_Stroke_getseters,
|
||||
/*tp_base*/ &Interface1D_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)Stroke_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,27 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_Interface1D.h"
|
||||
|
||||
#include "../../stroke/Stroke.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject Stroke_Type;
|
||||
|
||||
#define BPy_Stroke_Check(v) (((PyObject *)v)->ob_type == &Stroke_Type)
|
||||
|
||||
/*---------------------------Python BPy_Stroke structure definition----------*/
|
||||
struct BPy_Stroke {
|
||||
BPy_Interface1D py_if1D;
|
||||
Freestyle::Stroke *s;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,443 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_ViewEdge.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../BPy_Id.h"
|
||||
#include "../BPy_Nature.h"
|
||||
#include "../BPy_ViewShape.h"
|
||||
#include "../Interface0D/BPy_ViewVertex.h"
|
||||
#include "../Interface1D/BPy_FEdge.h"
|
||||
#include "../Interface1D/BPy_ViewEdge.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*----------------------ViewEdge methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_doc,
|
||||
"Class hierarchy: :class:`Interface1D` > :class:`ViewEdge`\n"
|
||||
"\n"
|
||||
"Class defining a ViewEdge. A ViewEdge in an edge of the image graph.\n"
|
||||
"it connects two :class:`ViewVertex` objects. It is made by connecting\n"
|
||||
"a set of FEdges.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
"\n"
|
||||
" Builds a :class:`ViewEdge` using the default constructor or the copy constructor.\n"
|
||||
"\n"
|
||||
" :param brother: A ViewEdge object.\n"
|
||||
" :type brother: :class:`ViewEdge`\n");
|
||||
static int ViewEdge_init(BPy_ViewEdge *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"brother", nullptr};
|
||||
PyObject *brother = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist, &ViewEdge_Type, &brother)) {
|
||||
return -1;
|
||||
}
|
||||
if (!brother) {
|
||||
self->ve = new ViewEdge();
|
||||
}
|
||||
else {
|
||||
self->ve = new ViewEdge(*(((BPy_ViewEdge *)brother)->ve));
|
||||
}
|
||||
self->py_if1D.if1D = self->ve;
|
||||
self->py_if1D.borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_update_fedges_doc,
|
||||
".. method:: update_fedges()\n"
|
||||
"\n"
|
||||
" Sets Viewedge to this for all embedded fedges.\n");
|
||||
static PyObject *ViewEdge_update_fedges(BPy_ViewEdge *self)
|
||||
{
|
||||
self->ve->UpdateFEdges();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_ViewEdge_methods[] = {
|
||||
{"update_fedges",
|
||||
(PyCFunction)ViewEdge_update_fedges,
|
||||
METH_NOARGS,
|
||||
ViewEdge_update_fedges_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------ViewEdge get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_first_viewvertex_doc,
|
||||
"The first ViewVertex.\n"
|
||||
"\n"
|
||||
":type: :class:`ViewVertex`\n");
|
||||
static PyObject *ViewEdge_first_viewvertex_get(BPy_ViewEdge *self, void * /*closure*/)
|
||||
{
|
||||
ViewVertex *v = self->ve->A();
|
||||
if (v) {
|
||||
return Any_BPy_ViewVertex_from_ViewVertex(*v);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int ViewEdge_first_viewvertex_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_ViewVertex_Check(value)) {
|
||||
return -1;
|
||||
}
|
||||
self->ve->setA(((BPy_ViewVertex *)value)->vv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_last_viewvertex_doc,
|
||||
"The second ViewVertex.\n"
|
||||
"\n"
|
||||
":type: :class:`ViewVertex`\n");
|
||||
static PyObject *ViewEdge_last_viewvertex_get(BPy_ViewEdge *self, void * /*closure*/)
|
||||
{
|
||||
ViewVertex *v = self->ve->B();
|
||||
if (v) {
|
||||
return Any_BPy_ViewVertex_from_ViewVertex(*v);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int ViewEdge_last_viewvertex_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_ViewVertex_Check(value)) {
|
||||
return -1;
|
||||
}
|
||||
self->ve->setB(((BPy_ViewVertex *)value)->vv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_first_fedge_doc,
|
||||
"The first FEdge that constitutes this ViewEdge.\n"
|
||||
"\n"
|
||||
":type: :class:`FEdge`\n");
|
||||
static PyObject *ViewEdge_first_fedge_get(BPy_ViewEdge *self, void * /*closure*/)
|
||||
{
|
||||
FEdge *fe = self->ve->fedgeA();
|
||||
if (fe) {
|
||||
return Any_BPy_FEdge_from_FEdge(*fe);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int ViewEdge_first_fedge_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_FEdge_Check(value)) {
|
||||
return -1;
|
||||
}
|
||||
self->ve->setFEdgeA(((BPy_FEdge *)value)->fe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_last_fedge_doc,
|
||||
"The last FEdge that constitutes this ViewEdge.\n"
|
||||
"\n"
|
||||
":type: :class:`FEdge`\n");
|
||||
static PyObject *ViewEdge_last_fedge_get(BPy_ViewEdge *self, void * /*closure*/)
|
||||
{
|
||||
FEdge *fe = self->ve->fedgeB();
|
||||
if (fe) {
|
||||
return Any_BPy_FEdge_from_FEdge(*fe);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int ViewEdge_last_fedge_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_FEdge_Check(value)) {
|
||||
return -1;
|
||||
}
|
||||
self->ve->setFEdgeB(((BPy_FEdge *)value)->fe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_viewshape_doc,
|
||||
"The ViewShape to which this ViewEdge belongs to.\n"
|
||||
"\n"
|
||||
":type: :class:`ViewShape`\n");
|
||||
static PyObject *ViewEdge_viewshape_get(BPy_ViewEdge *self, void * /*closure*/)
|
||||
{
|
||||
ViewShape *vs = self->ve->viewShape();
|
||||
if (vs) {
|
||||
return BPy_ViewShape_from_ViewShape(*vs);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int ViewEdge_viewshape_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_ViewShape_Check(value)) {
|
||||
return -1;
|
||||
}
|
||||
self->ve->setShape(((BPy_ViewShape *)value)->vs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_occludee_doc,
|
||||
"The shape that is occluded by the ViewShape to which this ViewEdge\n"
|
||||
"belongs to. If no object is occluded, this property is set to None.\n"
|
||||
"\n"
|
||||
":type: :class:`ViewShape`\n");
|
||||
static PyObject *ViewEdge_occludee_get(BPy_ViewEdge *self, void * /*closure*/)
|
||||
{
|
||||
ViewShape *vs = self->ve->aShape();
|
||||
if (vs) {
|
||||
return BPy_ViewShape_from_ViewShape(*vs);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int ViewEdge_occludee_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_ViewShape_Check(value)) {
|
||||
return -1;
|
||||
}
|
||||
self->ve->setaShape(((BPy_ViewShape *)value)->vs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_is_closed_doc,
|
||||
"True if this ViewEdge forms a closed loop.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *ViewEdge_is_closed_get(BPy_ViewEdge *self, void * /*closure*/)
|
||||
{
|
||||
return PyBool_from_bool(self->ve->isClosed());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_id_doc,
|
||||
"The Id of this ViewEdge.\n"
|
||||
"\n"
|
||||
":type: :class:`Id`\n");
|
||||
static PyObject *ViewEdge_id_get(BPy_ViewEdge *self, void * /*closure*/)
|
||||
{
|
||||
Id id(self->ve->getId());
|
||||
return BPy_Id_from_Id(id); // return a copy
|
||||
}
|
||||
|
||||
static int ViewEdge_id_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_Id_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be an Id");
|
||||
return -1;
|
||||
}
|
||||
self->ve->setId(*(((BPy_Id *)value)->id));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_nature_doc,
|
||||
"The nature of this ViewEdge.\n"
|
||||
"\n"
|
||||
":type: :class:`Nature`\n");
|
||||
static PyObject *ViewEdge_nature_get(BPy_ViewEdge *self, void * /*closure*/)
|
||||
{
|
||||
return BPy_Nature_from_Nature(self->ve->getNature());
|
||||
}
|
||||
|
||||
static int ViewEdge_nature_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!BPy_Nature_Check(value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "value must be a Nature");
|
||||
return -1;
|
||||
}
|
||||
self->ve->setNature(PyLong_AsLong((PyObject *)&((BPy_Nature *)value)->i));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_qi_doc,
|
||||
"The quantitative invisibility.\n"
|
||||
"\n"
|
||||
":type: int\n");
|
||||
static PyObject *ViewEdge_qi_get(BPy_ViewEdge *self, void * /*closure*/)
|
||||
{
|
||||
return PyLong_FromLong(self->ve->qi());
|
||||
}
|
||||
|
||||
static int ViewEdge_qi_set(BPy_ViewEdge *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
int qi;
|
||||
|
||||
if ((qi = PyLong_AsLong(value)) == -1 && PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
self->ve->setQI(qi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ViewEdge_chaining_time_stamp_doc,
|
||||
"The time stamp of this ViewEdge.\n"
|
||||
"\n"
|
||||
":type: int\n");
|
||||
static PyObject *ViewEdge_chaining_time_stamp_get(BPy_ViewEdge *self, void * /*closure*/)
|
||||
{
|
||||
return PyLong_FromLong(self->ve->getChainingTimeStamp());
|
||||
}
|
||||
|
||||
static int ViewEdge_chaining_time_stamp_set(BPy_ViewEdge *self,
|
||||
PyObject *value,
|
||||
void * /*closure*/)
|
||||
{
|
||||
int timestamp;
|
||||
|
||||
if ((timestamp = PyLong_AsLong(value)) == -1 && PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
self->ve->setChainingTimeStamp(timestamp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_ViewEdge_getseters[] = {
|
||||
{"first_viewvertex",
|
||||
(getter)ViewEdge_first_viewvertex_get,
|
||||
(setter)ViewEdge_first_viewvertex_set,
|
||||
ViewEdge_first_viewvertex_doc,
|
||||
nullptr},
|
||||
{"last_viewvertex",
|
||||
(getter)ViewEdge_last_viewvertex_get,
|
||||
(setter)ViewEdge_last_viewvertex_set,
|
||||
ViewEdge_last_viewvertex_doc,
|
||||
nullptr},
|
||||
{"first_fedge",
|
||||
(getter)ViewEdge_first_fedge_get,
|
||||
(setter)ViewEdge_first_fedge_set,
|
||||
ViewEdge_first_fedge_doc,
|
||||
nullptr},
|
||||
{"last_fedge",
|
||||
(getter)ViewEdge_last_fedge_get,
|
||||
(setter)ViewEdge_last_fedge_set,
|
||||
ViewEdge_last_fedge_doc,
|
||||
nullptr},
|
||||
{"viewshape",
|
||||
(getter)ViewEdge_viewshape_get,
|
||||
(setter)ViewEdge_viewshape_set,
|
||||
ViewEdge_viewshape_doc,
|
||||
nullptr},
|
||||
{"occludee",
|
||||
(getter)ViewEdge_occludee_get,
|
||||
(setter)ViewEdge_occludee_set,
|
||||
ViewEdge_occludee_doc,
|
||||
nullptr},
|
||||
{"is_closed",
|
||||
(getter)ViewEdge_is_closed_get,
|
||||
(setter) nullptr,
|
||||
ViewEdge_is_closed_doc,
|
||||
nullptr},
|
||||
{"id", (getter)ViewEdge_id_get, (setter)ViewEdge_id_set, ViewEdge_id_doc, nullptr},
|
||||
{"nature",
|
||||
(getter)ViewEdge_nature_get,
|
||||
(setter)ViewEdge_nature_set,
|
||||
ViewEdge_nature_doc,
|
||||
nullptr},
|
||||
{"qi", (getter)ViewEdge_qi_get, (setter)ViewEdge_qi_set, ViewEdge_qi_doc, nullptr},
|
||||
{"chaining_time_stamp",
|
||||
(getter)ViewEdge_chaining_time_stamp_get,
|
||||
(setter)ViewEdge_chaining_time_stamp_set,
|
||||
ViewEdge_chaining_time_stamp_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_ViewEdge type definition ------------------------------*/
|
||||
|
||||
PyTypeObject ViewEdge_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "ViewEdge",
|
||||
/*tp_basicsize*/ sizeof(BPy_ViewEdge),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ ViewEdge_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_ViewEdge_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_ViewEdge_getseters,
|
||||
/*tp_base*/ &Interface1D_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)ViewEdge_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,27 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_Interface1D.h"
|
||||
|
||||
#include "../../view_map/ViewMap.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject ViewEdge_Type;
|
||||
|
||||
#define BPy_ViewEdge_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&ViewEdge_Type))
|
||||
|
||||
/*---------------------------Python BPy_ViewEdge structure definition----------*/
|
||||
struct BPy_ViewEdge {
|
||||
BPy_Interface1D py_if1D;
|
||||
Freestyle::ViewEdge *ve;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,202 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_Chain.h"
|
||||
|
||||
#include "../../BPy_Convert.h"
|
||||
#include "../../BPy_Id.h"
|
||||
#include "../BPy_ViewEdge.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*----------------------Chain methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Chain_doc,
|
||||
"Class hierarchy: :class:`Interface1D` > :class:`Curve` > :class:`Chain`\n"
|
||||
"\n"
|
||||
"Class to represent a 1D elements issued from the chaining process. A\n"
|
||||
"Chain is the last step before the :class:`Stroke` and is used in the\n"
|
||||
"Splitting and Creation processes.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(id)``\n"
|
||||
"\n"
|
||||
" Builds a :class:`Chain` using the default constructor,\n"
|
||||
" copy constructor or from an :class:`Id`.\n"
|
||||
"\n"
|
||||
" :param brother: A Chain object.\n"
|
||||
" :type brother: :class:`Chain`\n"
|
||||
" :param id: An Id object.\n"
|
||||
" :type id: :class:`Id`\n");
|
||||
static int Chain_init(BPy_Chain *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"id", nullptr};
|
||||
PyObject *obj = nullptr;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &Chain_Type, &obj)) {
|
||||
if (!obj) {
|
||||
self->c = new Chain();
|
||||
}
|
||||
else {
|
||||
self->c = new Chain(*(((BPy_Chain *)obj)->c));
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_2, &Id_Type, &obj))
|
||||
{
|
||||
self->c = new Chain(*(((BPy_Id *)obj)->id));
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_c.c = self->c;
|
||||
self->py_c.py_if1D.if1D = self->c;
|
||||
self->py_c.py_if1D.borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Chain_push_viewedge_back_doc,
|
||||
".. method:: push_viewedge_back(viewedge, orientation)\n"
|
||||
"\n"
|
||||
" Adds a ViewEdge at the end of the Chain.\n"
|
||||
"\n"
|
||||
" :param viewedge: The ViewEdge that must be added.\n"
|
||||
" :type viewedge: :class:`ViewEdge`\n"
|
||||
" :param orientation: The orientation with which the ViewEdge must be processed.\n"
|
||||
" :type orientation: bool\n");
|
||||
static PyObject *Chain_push_viewedge_back(BPy_Chain *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"viewedge", "orientation", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!O!", (char **)kwlist, &ViewEdge_Type, &obj1, &PyBool_Type, &obj2))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
ViewEdge *ve = ((BPy_ViewEdge *)obj1)->ve;
|
||||
bool orientation = bool_from_PyBool(obj2);
|
||||
self->c->push_viewedge_back(ve, orientation);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Chain_push_viewedge_front_doc,
|
||||
".. method:: push_viewedge_front(viewedge, orientation)\n"
|
||||
"\n"
|
||||
" Adds a ViewEdge at the beginning of the Chain.\n"
|
||||
"\n"
|
||||
" :param viewedge: The ViewEdge that must be added.\n"
|
||||
" :type viewedge: :class:`ViewEdge`\n"
|
||||
" :param orientation: The orientation with which the ViewEdge must be\n"
|
||||
" processed.\n"
|
||||
" :type orientation: bool\n");
|
||||
static PyObject *Chain_push_viewedge_front(BPy_Chain *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"viewedge", "orientation", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!O!", (char **)kwlist, &ViewEdge_Type, &obj1, &PyBool_Type, &obj2))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
ViewEdge *ve = ((BPy_ViewEdge *)obj1)->ve;
|
||||
bool orientation = bool_from_PyBool(obj2);
|
||||
self->c->push_viewedge_front(ve, orientation);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_Chain_methods[] = {
|
||||
{"push_viewedge_back",
|
||||
(PyCFunction)Chain_push_viewedge_back,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
Chain_push_viewedge_back_doc},
|
||||
{"push_viewedge_front",
|
||||
(PyCFunction)Chain_push_viewedge_front,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
Chain_push_viewedge_front_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*-----------------------BPy_Chain type definition ------------------------------*/
|
||||
|
||||
PyTypeObject Chain_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Chain",
|
||||
/*tp_basicsize*/ sizeof(BPy_Chain),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ Chain_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_Chain_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ &FrsCurve_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)Chain_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,27 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_FrsCurve.h"
|
||||
|
||||
#include "../../../stroke/Chain.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject Chain_Type;
|
||||
|
||||
#define BPy_Chain_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&Chain_Type))
|
||||
|
||||
/*---------------------------Python BPy_Chain structure definition----------*/
|
||||
struct BPy_Chain {
|
||||
BPy_FrsCurve py_c;
|
||||
Freestyle::Chain *c;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,449 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_FEdgeSharp.h"
|
||||
|
||||
#include "../../BPy_Convert.h"
|
||||
#include "../../Interface0D/BPy_SVertex.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*----------------------FEdgeSharp methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSharp_doc,
|
||||
"Class hierarchy: :class:`Interface1D` > :class:`FEdge` > :class:`FEdgeSharp`\n"
|
||||
"\n"
|
||||
"Class defining a sharp FEdge. A Sharp FEdge corresponds to an initial\n"
|
||||
"edge of the input mesh. It can be a silhouette, a crease or a border.\n"
|
||||
"If it is a crease edge, then it is bordered by two faces of the mesh.\n"
|
||||
"Face a lies on its right whereas Face b lies on its left. If it is a\n"
|
||||
"border edge, then it doesn't have any face on its right, and thus Face\n"
|
||||
"a is None.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(first_vertex, second_vertex)``\n"
|
||||
"\n"
|
||||
" Builds an :class:`FEdgeSharp` using the default constructor,\n"
|
||||
" copy constructor, or between two :class:`SVertex` objects.\n"
|
||||
"\n"
|
||||
" :param brother: An FEdgeSharp object.\n"
|
||||
" :type brother: :class:`FEdgeSharp`\n"
|
||||
" :param first_vertex: The first SVertex object.\n"
|
||||
" :type first_vertex: :class:`SVertex`\n"
|
||||
" :param second_vertex: The second SVertex object.\n"
|
||||
" :type second_vertex: :class:`SVertex`\n");
|
||||
static int FEdgeSharp_init(BPy_FEdgeSharp *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"first_vertex", "second_vertex", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &FEdgeSharp_Type, &obj1)) {
|
||||
if (!obj1) {
|
||||
self->fes = new FEdgeSharp();
|
||||
}
|
||||
else {
|
||||
self->fes = new FEdgeSharp(*(((BPy_FEdgeSharp *)obj1)->fes));
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!O!", (char **)kwlist_2, &SVertex_Type, &obj1, &SVertex_Type, &obj2))
|
||||
{
|
||||
self->fes = new FEdgeSharp(((BPy_SVertex *)obj1)->sv, ((BPy_SVertex *)obj2)->sv);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_fe.fe = self->fes;
|
||||
self->py_fe.py_if1D.if1D = self->fes;
|
||||
self->py_fe.py_if1D.borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------mathutils callbacks ----------------------------*/
|
||||
|
||||
/* subtype */
|
||||
#define MATHUTILS_SUBTYPE_NORMAL_A 1
|
||||
#define MATHUTILS_SUBTYPE_NORMAL_B 2
|
||||
|
||||
static int FEdgeSharp_mathutils_check(blender::BaseMathObject *bmo)
|
||||
{
|
||||
if (!BPy_FEdgeSharp_Check(bmo->cb_user)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FEdgeSharp_mathutils_get(blender::BaseMathObject *bmo, int subtype)
|
||||
{
|
||||
BPy_FEdgeSharp *self = (BPy_FEdgeSharp *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_NORMAL_A: {
|
||||
Vec3r p(self->fes->normalA());
|
||||
bmo->data[0] = p[0];
|
||||
bmo->data[1] = p[1];
|
||||
bmo->data[2] = p[2];
|
||||
break;
|
||||
}
|
||||
case MATHUTILS_SUBTYPE_NORMAL_B: {
|
||||
Vec3r p(self->fes->normalB());
|
||||
bmo->data[0] = p[0];
|
||||
bmo->data[1] = p[1];
|
||||
bmo->data[2] = p[2];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FEdgeSharp_mathutils_set(blender::BaseMathObject *bmo, int subtype)
|
||||
{
|
||||
BPy_FEdgeSharp *self = (BPy_FEdgeSharp *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_NORMAL_A: {
|
||||
Vec3r p(bmo->data[0], bmo->data[1], bmo->data[2]);
|
||||
self->fes->setNormalA(p);
|
||||
break;
|
||||
}
|
||||
case MATHUTILS_SUBTYPE_NORMAL_B: {
|
||||
Vec3r p(bmo->data[0], bmo->data[1], bmo->data[2]);
|
||||
self->fes->setNormalB(p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FEdgeSharp_mathutils_get_index(blender::BaseMathObject *bmo, int subtype, int index)
|
||||
{
|
||||
BPy_FEdgeSharp *self = (BPy_FEdgeSharp *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_NORMAL_A: {
|
||||
Vec3r p(self->fes->normalA());
|
||||
bmo->data[index] = p[index];
|
||||
break;
|
||||
}
|
||||
case MATHUTILS_SUBTYPE_NORMAL_B: {
|
||||
Vec3r p(self->fes->normalB());
|
||||
bmo->data[index] = p[index];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FEdgeSharp_mathutils_set_index(blender::BaseMathObject *bmo, int subtype, int index)
|
||||
{
|
||||
BPy_FEdgeSharp *self = (BPy_FEdgeSharp *)bmo->cb_user;
|
||||
switch (subtype) {
|
||||
case MATHUTILS_SUBTYPE_NORMAL_A: {
|
||||
Vec3r p(self->fes->normalA());
|
||||
p[index] = bmo->data[index];
|
||||
self->fes->setNormalA(p);
|
||||
break;
|
||||
}
|
||||
case MATHUTILS_SUBTYPE_NORMAL_B: {
|
||||
Vec3r p(self->fes->normalB());
|
||||
p[index] = bmo->data[index];
|
||||
self->fes->setNormalB(p);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static blender::Mathutils_Callback FEdgeSharp_mathutils_cb = {
|
||||
FEdgeSharp_mathutils_check,
|
||||
FEdgeSharp_mathutils_get,
|
||||
FEdgeSharp_mathutils_set,
|
||||
FEdgeSharp_mathutils_get_index,
|
||||
FEdgeSharp_mathutils_set_index,
|
||||
};
|
||||
|
||||
static uchar FEdgeSharp_mathutils_cb_index = -1;
|
||||
|
||||
void FEdgeSharp_mathutils_register_callback()
|
||||
{
|
||||
FEdgeSharp_mathutils_cb_index = Mathutils_RegisterCallback(&FEdgeSharp_mathutils_cb);
|
||||
}
|
||||
|
||||
/*----------------------FEdgeSharp get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSharp_normal_right_doc,
|
||||
"The normal to the face lying on the right of the FEdge. If this FEdge\n"
|
||||
"is a border, it has no Face on its right and therefore no normal.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Vector`\n");
|
||||
static PyObject *FEdgeSharp_normal_right_get(BPy_FEdgeSharp *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Vector_CreatePyObject_cb(
|
||||
(PyObject *)self, 3, FEdgeSharp_mathutils_cb_index, MATHUTILS_SUBTYPE_NORMAL_A);
|
||||
}
|
||||
|
||||
static int FEdgeSharp_normal_right_set(BPy_FEdgeSharp *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float v[3];
|
||||
if (blender::mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
Vec3r p(v[0], v[1], v[2]);
|
||||
self->fes->setNormalA(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSharp_normal_left_doc,
|
||||
"The normal to the face lying on the left of the FEdge.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Vector`\n");
|
||||
static PyObject *FEdgeSharp_normal_left_get(BPy_FEdgeSharp *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Vector_CreatePyObject_cb(
|
||||
(PyObject *)self, 3, FEdgeSharp_mathutils_cb_index, MATHUTILS_SUBTYPE_NORMAL_B);
|
||||
}
|
||||
|
||||
static int FEdgeSharp_normal_left_set(BPy_FEdgeSharp *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float v[3];
|
||||
if (blender::mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
Vec3r p(v[0], v[1], v[2]);
|
||||
self->fes->setNormalB(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSharp_material_index_right_doc,
|
||||
"The index of the material of the face lying on the right of the FEdge.\n"
|
||||
"If this FEdge is a border, it has no Face on its right and therefore\n"
|
||||
"no material.\n"
|
||||
"\n"
|
||||
":type: int\n");
|
||||
static PyObject *FEdgeSharp_material_index_right_get(BPy_FEdgeSharp *self, void * /*closure*/)
|
||||
{
|
||||
return PyLong_FromLong(self->fes->aFrsMaterialIndex());
|
||||
}
|
||||
|
||||
static int FEdgeSharp_material_index_right_set(BPy_FEdgeSharp *self,
|
||||
PyObject *value,
|
||||
void * /*closure*/)
|
||||
{
|
||||
uint i = PyLong_AsUnsignedLong(value);
|
||||
if (PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
self->fes->setaFrsMaterialIndex(i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSharp_material_index_left_doc,
|
||||
"The index of the material of the face lying on the left of the FEdge.\n"
|
||||
"\n"
|
||||
":type: int\n");
|
||||
static PyObject *FEdgeSharp_material_index_left_get(BPy_FEdgeSharp *self, void * /*closure*/)
|
||||
{
|
||||
return PyLong_FromLong(self->fes->bFrsMaterialIndex());
|
||||
}
|
||||
|
||||
static int FEdgeSharp_material_index_left_set(BPy_FEdgeSharp *self,
|
||||
PyObject *value,
|
||||
void * /*closure*/)
|
||||
{
|
||||
uint i = PyLong_AsUnsignedLong(value);
|
||||
if (PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
self->fes->setbFrsMaterialIndex(i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSharp_material_right_doc,
|
||||
"The material of the face lying on the right of the FEdge. If this FEdge\n"
|
||||
"is a border, it has no Face on its right and therefore no material.\n"
|
||||
"\n"
|
||||
":type: :class:`Material`\n");
|
||||
static PyObject *FEdgeSharp_material_right_get(BPy_FEdgeSharp *self, void * /*closure*/)
|
||||
{
|
||||
return BPy_FrsMaterial_from_FrsMaterial(self->fes->aFrsMaterial());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSharp_material_left_doc,
|
||||
"The material of the face lying on the left of the FEdge.\n"
|
||||
"\n"
|
||||
":type: :class:`Material`\n");
|
||||
static PyObject *FEdgeSharp_material_left_get(BPy_FEdgeSharp *self, void * /*closure*/)
|
||||
{
|
||||
return BPy_FrsMaterial_from_FrsMaterial(self->fes->bFrsMaterial());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSharp_face_mark_right_doc,
|
||||
"The face mark of the face lying on the right of the FEdge. If this FEdge\n"
|
||||
"is a border, it has no face on the right and thus this property is set to\n"
|
||||
"false.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *FEdgeSharp_face_mark_right_get(BPy_FEdgeSharp *self, void * /*closure*/)
|
||||
{
|
||||
return PyBool_from_bool(self->fes->aFaceMark());
|
||||
}
|
||||
|
||||
static int FEdgeSharp_face_mark_right_set(BPy_FEdgeSharp *self,
|
||||
PyObject *value,
|
||||
void * /*closure*/)
|
||||
{
|
||||
if (!PyBool_Check(value)) {
|
||||
return -1;
|
||||
}
|
||||
self->fes->setaFaceMark(bool_from_PyBool(value));
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSharp_face_mark_left_doc,
|
||||
"The face mark of the face lying on the left of the FEdge.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *FEdgeSharp_face_mark_left_get(BPy_FEdgeSharp *self, void * /*closure*/)
|
||||
{
|
||||
return PyBool_from_bool(self->fes->bFaceMark());
|
||||
}
|
||||
|
||||
static int FEdgeSharp_face_mark_left_set(BPy_FEdgeSharp *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!PyBool_Check(value)) {
|
||||
return -1;
|
||||
}
|
||||
self->fes->setbFaceMark(bool_from_PyBool(value));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_FEdgeSharp_getseters[] = {
|
||||
{"normal_right",
|
||||
(getter)FEdgeSharp_normal_right_get,
|
||||
(setter)FEdgeSharp_normal_right_set,
|
||||
FEdgeSharp_normal_right_doc,
|
||||
nullptr},
|
||||
{"normal_left",
|
||||
(getter)FEdgeSharp_normal_left_get,
|
||||
(setter)FEdgeSharp_normal_left_set,
|
||||
FEdgeSharp_normal_left_doc,
|
||||
nullptr},
|
||||
{"material_index_right",
|
||||
(getter)FEdgeSharp_material_index_right_get,
|
||||
(setter)FEdgeSharp_material_index_right_set,
|
||||
FEdgeSharp_material_index_right_doc,
|
||||
nullptr},
|
||||
{"material_index_left",
|
||||
(getter)FEdgeSharp_material_index_left_get,
|
||||
(setter)FEdgeSharp_material_index_left_set,
|
||||
FEdgeSharp_material_index_left_doc,
|
||||
nullptr},
|
||||
{"material_right",
|
||||
(getter)FEdgeSharp_material_right_get,
|
||||
(setter) nullptr,
|
||||
FEdgeSharp_material_right_doc,
|
||||
nullptr},
|
||||
{"material_left",
|
||||
(getter)FEdgeSharp_material_left_get,
|
||||
(setter) nullptr,
|
||||
FEdgeSharp_material_left_doc,
|
||||
nullptr},
|
||||
{"face_mark_right",
|
||||
(getter)FEdgeSharp_face_mark_right_get,
|
||||
(setter)FEdgeSharp_face_mark_right_set,
|
||||
FEdgeSharp_face_mark_right_doc,
|
||||
nullptr},
|
||||
{"face_mark_left",
|
||||
(getter)FEdgeSharp_face_mark_left_get,
|
||||
(setter)FEdgeSharp_face_mark_left_set,
|
||||
FEdgeSharp_face_mark_left_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_FEdgeSharp type definition ------------------------------*/
|
||||
|
||||
PyTypeObject FEdgeSharp_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "FEdgeSharp",
|
||||
/*tp_basicsize*/ sizeof(BPy_FEdgeSharp),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ FEdgeSharp_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_FEdgeSharp_getseters,
|
||||
/*tp_base*/ &FEdge_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)FEdgeSharp_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,31 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_FEdge.h"
|
||||
|
||||
#include "../../../view_map/Silhouette.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject FEdgeSharp_Type;
|
||||
|
||||
#define BPy_FEdgeSharp_Check(v) (PyObject_IsInstance((PyObject *)v, (PyObject *)&FEdgeSharp_Type))
|
||||
|
||||
/*---------------------------Python BPy_FEdgeSharp structure definition----------*/
|
||||
struct BPy_FEdgeSharp {
|
||||
BPy_FEdge py_fe;
|
||||
Freestyle::FEdgeSharp *fes;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_FEdgeSharp visible prototypes-----------*/
|
||||
|
||||
void FEdgeSharp_mathutils_register_callback();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,289 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_FEdgeSmooth.h"
|
||||
|
||||
#include "../../BPy_Convert.h"
|
||||
#include "../../Interface0D/BPy_SVertex.h"
|
||||
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*----------------------FEdgeSmooth methods ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSmooth_doc,
|
||||
"Class hierarchy: :class:`Interface1D` > :class:`FEdge` > :class:`FEdgeSmooth`\n"
|
||||
"\n"
|
||||
"Class defining a smooth edge. This kind of edge typically runs across\n"
|
||||
"a face of the input mesh. It can be a silhouette, a ridge or valley,\n"
|
||||
"a suggestive contour.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(first_vertex, second_vertex)``\n"
|
||||
"\n"
|
||||
" Builds an :class:`FEdgeSmooth` using the default constructor,\n"
|
||||
" copy constructor, or between two :class:`SVertex`.\n"
|
||||
"\n"
|
||||
" :param brother: An FEdgeSmooth object.\n"
|
||||
" :type brother: :class:`FEdgeSmooth`\n"
|
||||
" :param first_vertex: The first SVertex object.\n"
|
||||
" :type first_vertex: :class:`SVertex`\n"
|
||||
" :param second_vertex: The second SVertex object.\n"
|
||||
" :type second_vertex: :class:`SVertex`\n");
|
||||
static int FEdgeSmooth_init(BPy_FEdgeSmooth *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"first_vertex", "second_vertex", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist_1, &FEdgeSmooth_Type, &obj1))
|
||||
{
|
||||
if (!obj1) {
|
||||
self->fes = new FEdgeSmooth();
|
||||
}
|
||||
else {
|
||||
self->fes = new FEdgeSmooth(*(((BPy_FEdgeSmooth *)obj1)->fes));
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!O!", (char **)kwlist_2, &SVertex_Type, &obj1, &SVertex_Type, &obj2))
|
||||
{
|
||||
self->fes = new FEdgeSmooth(((BPy_SVertex *)obj1)->sv, ((BPy_SVertex *)obj2)->sv);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_fe.fe = self->fes;
|
||||
self->py_fe.py_if1D.if1D = self->fes;
|
||||
self->py_fe.py_if1D.borrowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------mathutils callbacks ----------------------------*/
|
||||
|
||||
static int FEdgeSmooth_mathutils_check(blender::BaseMathObject *bmo)
|
||||
{
|
||||
if (!BPy_FEdgeSmooth_Check(bmo->cb_user)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FEdgeSmooth_mathutils_get(blender::BaseMathObject *bmo, int /*subtype*/)
|
||||
{
|
||||
BPy_FEdgeSmooth *self = (BPy_FEdgeSmooth *)bmo->cb_user;
|
||||
Vec3r p(self->fes->normal());
|
||||
bmo->data[0] = p[0];
|
||||
bmo->data[1] = p[1];
|
||||
bmo->data[2] = p[2];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FEdgeSmooth_mathutils_set(blender::BaseMathObject *bmo, int /*subtype*/)
|
||||
{
|
||||
BPy_FEdgeSmooth *self = (BPy_FEdgeSmooth *)bmo->cb_user;
|
||||
Vec3r p(bmo->data[0], bmo->data[1], bmo->data[2]);
|
||||
self->fes->setNormal(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FEdgeSmooth_mathutils_get_index(blender::BaseMathObject *bmo,
|
||||
int /*subtype*/,
|
||||
int index)
|
||||
{
|
||||
BPy_FEdgeSmooth *self = (BPy_FEdgeSmooth *)bmo->cb_user;
|
||||
Vec3r p(self->fes->normal());
|
||||
bmo->data[index] = p[index];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FEdgeSmooth_mathutils_set_index(blender::BaseMathObject *bmo,
|
||||
int /*subtype*/,
|
||||
int index)
|
||||
{
|
||||
BPy_FEdgeSmooth *self = (BPy_FEdgeSmooth *)bmo->cb_user;
|
||||
Vec3r p(self->fes->normal());
|
||||
p[index] = bmo->data[index];
|
||||
self->fes->setNormal(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static blender::Mathutils_Callback FEdgeSmooth_mathutils_cb = {
|
||||
FEdgeSmooth_mathutils_check,
|
||||
FEdgeSmooth_mathutils_get,
|
||||
FEdgeSmooth_mathutils_set,
|
||||
FEdgeSmooth_mathutils_get_index,
|
||||
FEdgeSmooth_mathutils_set_index,
|
||||
};
|
||||
|
||||
static uchar FEdgeSmooth_mathutils_cb_index = -1;
|
||||
|
||||
void FEdgeSmooth_mathutils_register_callback()
|
||||
{
|
||||
FEdgeSmooth_mathutils_cb_index = Mathutils_RegisterCallback(&FEdgeSmooth_mathutils_cb);
|
||||
}
|
||||
|
||||
/*----------------------FEdgeSmooth get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSmooth_normal_doc,
|
||||
"The normal of the face that this FEdge is running across.\n"
|
||||
"\n"
|
||||
":type: :class:`mathutils.Vector`\n");
|
||||
static PyObject *FEdgeSmooth_normal_get(BPy_FEdgeSmooth *self, void * /*closure*/)
|
||||
{
|
||||
return blender::Vector_CreatePyObject_cb((PyObject *)self, 3, FEdgeSmooth_mathutils_cb_index, 0);
|
||||
}
|
||||
|
||||
static int FEdgeSmooth_normal_set(BPy_FEdgeSmooth *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
float v[3];
|
||||
if (blender::mathutils_array_parse(v, 3, 3, value, "value must be a 3-dimensional vector") == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
Vec3r p(v[0], v[1], v[2]);
|
||||
self->fes->setNormal(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSmooth_material_index_doc,
|
||||
"The index of the material of the face that this FEdge is running across.\n"
|
||||
"\n"
|
||||
":type: int\n");
|
||||
static PyObject *FEdgeSmooth_material_index_get(BPy_FEdgeSmooth *self, void * /*closure*/)
|
||||
{
|
||||
return PyLong_FromLong(self->fes->frs_materialIndex());
|
||||
}
|
||||
|
||||
static int FEdgeSmooth_material_index_set(BPy_FEdgeSmooth *self,
|
||||
PyObject *value,
|
||||
void * /*closure*/)
|
||||
{
|
||||
uint i = PyLong_AsUnsignedLong(value);
|
||||
if (PyErr_Occurred()) {
|
||||
return -1;
|
||||
}
|
||||
self->fes->setFrsMaterialIndex(i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSmooth_material_doc,
|
||||
"The material of the face that this FEdge is running across.\n"
|
||||
"\n"
|
||||
":type: :class:`Material`\n");
|
||||
static PyObject *FEdgeSmooth_material_get(BPy_FEdgeSmooth *self, void * /*closure*/)
|
||||
{
|
||||
return BPy_FrsMaterial_from_FrsMaterial(self->fes->frs_material());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
FEdgeSmooth_face_mark_doc,
|
||||
"The face mark of the face that this FEdge is running across.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *FEdgeSmooth_face_mark_get(BPy_FEdgeSmooth *self, void * /*closure*/)
|
||||
{
|
||||
return PyBool_from_bool(self->fes->faceMark());
|
||||
}
|
||||
|
||||
static int FEdgeSmooth_face_mark_set(BPy_FEdgeSmooth *self, PyObject *value, void * /*closure*/)
|
||||
{
|
||||
if (!PyBool_Check(value)) {
|
||||
return -1;
|
||||
}
|
||||
self->fes->setFaceMark(bool_from_PyBool(value));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_FEdgeSmooth_getseters[] = {
|
||||
{"normal",
|
||||
(getter)FEdgeSmooth_normal_get,
|
||||
(setter)FEdgeSmooth_normal_set,
|
||||
FEdgeSmooth_normal_doc,
|
||||
nullptr},
|
||||
{"material_index",
|
||||
(getter)FEdgeSmooth_material_index_get,
|
||||
(setter)FEdgeSmooth_material_index_set,
|
||||
FEdgeSmooth_material_index_doc,
|
||||
nullptr},
|
||||
{"material",
|
||||
(getter)FEdgeSmooth_material_get,
|
||||
(setter) nullptr,
|
||||
FEdgeSmooth_material_doc,
|
||||
nullptr},
|
||||
{"face_mark",
|
||||
(getter)FEdgeSmooth_face_mark_get,
|
||||
(setter)FEdgeSmooth_face_mark_set,
|
||||
FEdgeSmooth_face_mark_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_FEdgeSmooth type definition ------------------------------*/
|
||||
|
||||
PyTypeObject FEdgeSmooth_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "FEdgeSmooth",
|
||||
/*tp_basicsize*/ sizeof(BPy_FEdgeSmooth),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ FEdgeSmooth_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_FEdgeSmooth_getseters,
|
||||
/*tp_base*/ &FEdge_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)FEdgeSmooth_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,32 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_FEdge.h"
|
||||
|
||||
#include "../../../view_map/Silhouette.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject FEdgeSmooth_Type;
|
||||
|
||||
#define BPy_FEdgeSmooth_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&FEdgeSmooth_Type))
|
||||
|
||||
/*---------------------------Python BPy_FEdgeSmooth structure definition----------*/
|
||||
struct BPy_FEdgeSmooth {
|
||||
BPy_FEdge py_fe;
|
||||
Freestyle::FEdgeSmooth *fes;
|
||||
};
|
||||
|
||||
/*---------------------------Python BPy_FEdgeSmooth visible prototypes-----------*/
|
||||
|
||||
void FEdgeSmooth_mathutils_register_callback();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,218 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_AdjacencyIterator.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../Interface0D/BPy_ViewVertex.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
AdjacencyIterator_doc,
|
||||
"Class hierarchy: :class:`Iterator` > :class:`AdjacencyIterator`\n"
|
||||
"\n"
|
||||
"Class for representing adjacency iterators used in the chaining\n"
|
||||
"process. An AdjacencyIterator is created in the increment() and\n"
|
||||
"decrement() methods of a :class:`ChainingIterator` and passed to the\n"
|
||||
"traverse() method of the ChainingIterator.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args, **kwargs)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(vertex, restrict_to_selection=True, restrict_to_unvisited=True)``\n"
|
||||
"\n"
|
||||
" Builds an :class:`AdjacencyIterator` using the default constructor,\n"
|
||||
" copy constructor or the overloaded constructor.\n"
|
||||
"\n"
|
||||
" :param brother: An AdjacencyIterator object.\n"
|
||||
" :type brother: :class:`AdjacencyIterator`\n"
|
||||
" :param vertex: The vertex which is the next crossing.\n"
|
||||
" :type vertex: :class:`ViewVertex`\n"
|
||||
" :param restrict_to_selection: Indicates whether to force the chaining\n"
|
||||
" to stay within the set of selected ViewEdges or not.\n"
|
||||
" :type restrict_to_selection: bool\n"
|
||||
" :param restrict_to_unvisited: Indicates whether a ViewEdge that has\n"
|
||||
" already been chained must be ignored ot not.\n"
|
||||
" :type restrict_to_unvisited: bool\n");
|
||||
static int AdjacencyIterator_init(BPy_AdjacencyIterator *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {
|
||||
"vertex", "restrict_to_selection", "restrict_to_unvisited", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr, *obj3 = nullptr;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "|O!", (char **)kwlist_1, &AdjacencyIterator_Type, &obj1))
|
||||
{
|
||||
if (!obj1) {
|
||||
self->a_it = new AdjacencyIterator();
|
||||
self->at_start = true;
|
||||
}
|
||||
else {
|
||||
self->a_it = new AdjacencyIterator(*(((BPy_AdjacencyIterator *)obj1)->a_it));
|
||||
self->at_start = ((BPy_AdjacencyIterator *)obj1)->at_start;
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
(void)(obj2 = obj3 = nullptr),
|
||||
PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!|O!O!",
|
||||
(char **)kwlist_2,
|
||||
&ViewVertex_Type,
|
||||
&obj1,
|
||||
&PyBool_Type,
|
||||
&obj2,
|
||||
&PyBool_Type,
|
||||
&obj3))
|
||||
{
|
||||
bool restrictToSelection = (!obj2) ? true : bool_from_PyBool(obj2);
|
||||
bool restrictToUnvisited = (!obj3) ? true : bool_from_PyBool(obj3);
|
||||
self->a_it = new AdjacencyIterator(
|
||||
((BPy_ViewVertex *)obj1)->vv, restrictToSelection, restrictToUnvisited);
|
||||
self->at_start = ((BPy_AdjacencyIterator *)obj1)->at_start;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_it.it = self->a_it;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *AdjacencyIterator_iter(BPy_AdjacencyIterator *self)
|
||||
{
|
||||
Py_INCREF(self);
|
||||
self->at_start = true;
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
static PyObject *AdjacencyIterator_iternext(BPy_AdjacencyIterator *self)
|
||||
{
|
||||
if (self->a_it->isEnd()) {
|
||||
PyErr_SetNone(PyExc_StopIteration);
|
||||
return nullptr;
|
||||
}
|
||||
if (self->at_start) {
|
||||
self->at_start = false;
|
||||
}
|
||||
else {
|
||||
self->a_it->increment();
|
||||
if (self->a_it->isEnd()) {
|
||||
PyErr_SetNone(PyExc_StopIteration);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
ViewEdge *ve = self->a_it->operator->();
|
||||
return BPy_ViewEdge_from_ViewEdge(*ve);
|
||||
}
|
||||
|
||||
/*----------------------AdjacencyIterator get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
AdjacencyIterator_object_doc,
|
||||
"The ViewEdge object currently pointed to by this iterator.\n"
|
||||
"\n"
|
||||
":type: :class:`ViewEdge`\n");
|
||||
static PyObject *AdjacencyIterator_object_get(BPy_AdjacencyIterator *self, void * /*closure*/)
|
||||
{
|
||||
if (self->a_it->isEnd()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
|
||||
return nullptr;
|
||||
}
|
||||
ViewEdge *ve = self->a_it->operator*();
|
||||
if (ve) {
|
||||
return BPy_ViewEdge_from_ViewEdge(*ve);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
AdjacencyIterator_is_incoming_doc,
|
||||
"True if the current ViewEdge is coming towards the iteration vertex, and\n"
|
||||
"False otherwise.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *AdjacencyIterator_is_incoming_get(BPy_AdjacencyIterator *self, void * /*closure*/)
|
||||
{
|
||||
if (self->a_it->isEnd()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
|
||||
return nullptr;
|
||||
}
|
||||
return PyBool_from_bool(self->a_it->isIncoming());
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_AdjacencyIterator_getseters[] = {
|
||||
{"is_incoming",
|
||||
(getter)AdjacencyIterator_is_incoming_get,
|
||||
(setter) nullptr,
|
||||
AdjacencyIterator_is_incoming_doc,
|
||||
nullptr},
|
||||
{"object",
|
||||
(getter)AdjacencyIterator_object_get,
|
||||
(setter) nullptr,
|
||||
AdjacencyIterator_object_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_AdjacencyIterator type definition ------------------------------*/
|
||||
|
||||
PyTypeObject AdjacencyIterator_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "AdjacencyIterator",
|
||||
/*tp_basicsize*/ sizeof(BPy_AdjacencyIterator),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ AdjacencyIterator_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ (getiterfunc)AdjacencyIterator_iter,
|
||||
/*tp_iternext*/ (iternextfunc)AdjacencyIterator_iternext,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_AdjacencyIterator_getseters,
|
||||
/*tp_base*/ &Iterator_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)AdjacencyIterator_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,29 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_Iterator.h"
|
||||
|
||||
#include "../../stroke/ChainingIterators.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject AdjacencyIterator_Type;
|
||||
|
||||
#define BPy_AdjacencyIterator_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&AdjacencyIterator_Type))
|
||||
|
||||
/*---------------------------Python BPy_AdjacencyIterator structure definition----------*/
|
||||
struct BPy_AdjacencyIterator {
|
||||
BPy_Iterator py_it;
|
||||
Freestyle::AdjacencyIterator *a_it;
|
||||
bool at_start;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,197 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_ChainPredicateIterator.h"
|
||||
|
||||
#include "../BPy_BinaryPredicate1D.h"
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../BPy_UnaryPredicate1D.h"
|
||||
#include "../Interface1D/BPy_ViewEdge.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ChainPredicateIterator_doc,
|
||||
|
||||
"Class hierarchy: :class:`freestyle.types.Iterator` >\n"
|
||||
":class:`freestyle.types.ViewEdgeIterator` >\n"
|
||||
":class:`freestyle.types.ChainingIterator` >\n"
|
||||
":class:`ChainPredicateIterator`\n"
|
||||
"\n"
|
||||
"A \"generic\" user-controlled ViewEdge iterator. This iterator is in\n"
|
||||
"particular built from a unary predicate and a binary predicate.\n"
|
||||
"First, the unary predicate is evaluated for all potential next\n"
|
||||
"ViewEdges in order to only keep the ones respecting a certain\n"
|
||||
"constraint. Then, the binary predicate is evaluated on the current\n"
|
||||
"ViewEdge together with each ViewEdge of the previous selection. The\n"
|
||||
"first ViewEdge respecting both the unary predicate and the binary\n"
|
||||
"predicate is kept as the next one. If none of the potential next\n"
|
||||
"ViewEdge respects these two predicates, None is returned.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__(upred, bpred, restrict_to_selection=True, restrict_to_unvisited=True, "
|
||||
"begin=None, orientation=True)``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
"\n"
|
||||
" Builds a ChainPredicateIterator from a unary predicate, a binary\n"
|
||||
" predicate, a starting ViewEdge and its orientation or using the copy constructor.\n"
|
||||
"\n"
|
||||
" :param upred: The unary predicate that the next ViewEdge must satisfy.\n"
|
||||
" :type upred: :class:`freestyle.types.UnaryPredicate1D`\n"
|
||||
" :param bpred: The binary predicate that the next ViewEdge must\n"
|
||||
" satisfy together with the actual pointed ViewEdge.\n"
|
||||
" :type bpred: :class:`freestyle.types.BinaryPredicate1D`\n"
|
||||
" :param restrict_to_selection: Indicates whether to force the chaining\n"
|
||||
" to stay within the set of selected ViewEdges or not.\n"
|
||||
" :type restrict_to_selection: bool\n"
|
||||
" :param restrict_to_unvisited: Indicates whether a ViewEdge that has\n"
|
||||
" already been chained must be ignored ot not.\n"
|
||||
" :type restrict_to_unvisited: bool\n"
|
||||
" :param begin: The ViewEdge from where to start the iteration.\n"
|
||||
" :type begin: :class:`freestyle.types.ViewEdge` | None\n"
|
||||
" :param orientation: If true, we'll look for the next ViewEdge among\n"
|
||||
" the ViewEdges that surround the ending ViewVertex of begin. If\n"
|
||||
" false, we'll search over the ViewEdges surrounding the ending\n"
|
||||
" ViewVertex of begin.\n"
|
||||
" :type orientation: bool\n"
|
||||
" :param brother: A ChainPredicateIterator object.\n"
|
||||
" :type brother: :class:`ChainPredicateIterator`\n");
|
||||
static int check_begin(PyObject *obj, void *v)
|
||||
{
|
||||
if (obj != nullptr && obj != Py_None && !BPy_ViewEdge_Check(obj)) {
|
||||
return 0;
|
||||
}
|
||||
*((PyObject **)v) = obj;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ChainPredicateIterator_init(BPy_ChainPredicateIterator *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"upred",
|
||||
"bpred",
|
||||
"restrict_to_selection",
|
||||
"restrict_to_unvisited",
|
||||
"begin",
|
||||
"orientation",
|
||||
nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr, *obj3 = nullptr, *obj4 = nullptr, *obj5 = nullptr,
|
||||
*obj6 = nullptr;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!", (char **)kwlist_1, &ChainPredicateIterator_Type, &obj1))
|
||||
{
|
||||
self->cp_it = new ChainPredicateIterator(*(((BPy_ChainPredicateIterator *)obj1)->cp_it));
|
||||
self->upred = ((BPy_ChainPredicateIterator *)obj1)->upred;
|
||||
self->bpred = ((BPy_ChainPredicateIterator *)obj1)->bpred;
|
||||
Py_INCREF(self->upred);
|
||||
Py_INCREF(self->bpred);
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
(void)(obj3 = obj4 = obj5 = obj6 = nullptr),
|
||||
PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"O!O!|O!O!O&O!",
|
||||
(char **)kwlist_2,
|
||||
&UnaryPredicate1D_Type,
|
||||
&obj1,
|
||||
&BinaryPredicate1D_Type,
|
||||
&obj2,
|
||||
&PyBool_Type,
|
||||
&obj3,
|
||||
&PyBool_Type,
|
||||
&obj4,
|
||||
check_begin,
|
||||
&obj5,
|
||||
&PyBool_Type,
|
||||
&obj6))
|
||||
{
|
||||
UnaryPredicate1D *up1D = ((BPy_UnaryPredicate1D *)obj1)->up1D;
|
||||
BinaryPredicate1D *bp1D = ((BPy_BinaryPredicate1D *)obj2)->bp1D;
|
||||
bool restrict_to_selection = (!obj3) ? true : bool_from_PyBool(obj3);
|
||||
bool restrict_to_unvisited = (!obj4) ? true : bool_from_PyBool(obj4);
|
||||
ViewEdge *begin = (!obj5 || obj5 == Py_None) ? nullptr : ((BPy_ViewEdge *)obj5)->ve;
|
||||
bool orientation = (!obj6) ? true : bool_from_PyBool(obj6);
|
||||
self->cp_it = new ChainPredicateIterator(
|
||||
*up1D, *bp1D, restrict_to_selection, restrict_to_unvisited, begin, orientation);
|
||||
self->upred = obj1;
|
||||
self->bpred = obj2;
|
||||
Py_INCREF(self->upred);
|
||||
Py_INCREF(self->bpred);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_c_it.c_it = self->cp_it;
|
||||
self->py_c_it.py_ve_it.ve_it = self->cp_it;
|
||||
self->py_c_it.py_ve_it.py_it.it = self->cp_it;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ChainPredicateIterator_dealloc(BPy_ChainPredicateIterator *self)
|
||||
{
|
||||
Py_XDECREF(self->upred);
|
||||
Py_XDECREF(self->bpred);
|
||||
ChainingIterator_Type.tp_dealloc((PyObject *)self);
|
||||
}
|
||||
|
||||
/*-----------------------BPy_ChainPredicateIterator type definition ----------------------------*/
|
||||
|
||||
PyTypeObject ChainPredicateIterator_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "ChainPredicateIterator",
|
||||
/*tp_basicsize*/ sizeof(BPy_ChainPredicateIterator),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ (destructor)ChainPredicateIterator_dealloc,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ ChainPredicateIterator_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ &ChainingIterator_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)ChainPredicateIterator_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,30 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BPy_ChainingIterator.h"
|
||||
|
||||
#include "../../stroke/ChainingIterators.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject ChainPredicateIterator_Type;
|
||||
|
||||
#define BPy_ChainPredicateIterator_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&ChainPredicateIterator_Type))
|
||||
|
||||
/*---------------------------Python BPy_ChainPredicateIterator structure definition----------*/
|
||||
struct BPy_ChainPredicateIterator {
|
||||
BPy_ChainingIterator py_c_it;
|
||||
Freestyle::ChainPredicateIterator *cp_it;
|
||||
PyObject *upred;
|
||||
PyObject *bpred;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,153 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_ChainSilhouetteIterator.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../Interface1D/BPy_ViewEdge.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
// ChainSilhouetteIterator (bool restrict_to_selection=true, ViewEdge *begin=nullptr, bool
|
||||
// orientation=true) ChainSilhouetteIterator (const ChainSilhouetteIterator &brother)
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ChainSilhouetteIterator_doc,
|
||||
"Class hierarchy: :class:`freestyle.types.Iterator` >\n"
|
||||
":class:`freestyle.types.ViewEdgeIterator` >\n"
|
||||
":class:`freestyle.types.ChainingIterator` >\n"
|
||||
":class:`ChainSilhouetteIterator`\n"
|
||||
"\n"
|
||||
"A ViewEdge Iterator used to follow ViewEdges the most naturally. For\n"
|
||||
"example, it will follow visible ViewEdges of same nature. As soon, as\n"
|
||||
"the nature or the visibility changes, the iteration stops (by setting\n"
|
||||
"the pointed ViewEdge to 0). In the case of an iteration over a set of\n"
|
||||
"ViewEdge that are both Silhouette and Crease, there will be a\n"
|
||||
"precedence of the silhouette over the crease criterion.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__(restrict_to_selection=True, begin=None, orientation=True)``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
"\n"
|
||||
" Builds a ChainSilhouetteIterator from the first ViewEdge used for\n"
|
||||
" iteration and its orientation or the copy constructor.\n"
|
||||
"\n"
|
||||
" :param restrict_to_selection: Indicates whether to force the chaining\n"
|
||||
" to stay within the set of selected ViewEdges or not.\n"
|
||||
" :type restrict_to_selection: bool\n"
|
||||
" :param begin: The ViewEdge from where to start the iteration.\n"
|
||||
" :type begin: :class:`freestyle.types.ViewEdge` | None\n"
|
||||
" :param orientation: If true, we'll look for the next ViewEdge among\n"
|
||||
" the ViewEdges that surround the ending ViewVertex of begin. If\n"
|
||||
" false, we'll search over the ViewEdges surrounding the ending\n"
|
||||
" ViewVertex of begin.\n"
|
||||
" :type orientation: bool\n"
|
||||
" :param brother: A ChainSilhouetteIterator object.\n"
|
||||
" :type brother: :class:`ChainSilhouetteIterator`\n");
|
||||
static int check_begin(PyObject *obj, void *v)
|
||||
{
|
||||
if (obj != nullptr && obj != Py_None && !BPy_ViewEdge_Check(obj)) {
|
||||
return 0;
|
||||
}
|
||||
*((PyObject **)v) = obj;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ChainSilhouetteIterator_init(BPy_ChainSilhouetteIterator *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"restrict_to_selection", "begin", "orientation", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr, *obj3 = nullptr;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!", (char **)kwlist_1, &ChainSilhouetteIterator_Type, &obj1))
|
||||
{
|
||||
self->cs_it = new ChainSilhouetteIterator(*(((BPy_ChainSilhouetteIterator *)obj1)->cs_it));
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
(void)(obj1 = obj2 = obj3 = nullptr),
|
||||
PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"|O!O&O!",
|
||||
(char **)kwlist_2,
|
||||
&PyBool_Type,
|
||||
&obj1,
|
||||
check_begin,
|
||||
&obj2,
|
||||
&PyBool_Type,
|
||||
&obj3))
|
||||
{
|
||||
bool restrict_to_selection = (!obj1) ? true : bool_from_PyBool(obj1);
|
||||
ViewEdge *begin = (!obj2 || obj2 == Py_None) ? nullptr : ((BPy_ViewEdge *)obj2)->ve;
|
||||
bool orientation = (!obj3) ? true : bool_from_PyBool(obj3);
|
||||
self->cs_it = new ChainSilhouetteIterator(restrict_to_selection, begin, orientation);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_c_it.c_it = self->cs_it;
|
||||
self->py_c_it.py_ve_it.ve_it = self->cs_it;
|
||||
self->py_c_it.py_ve_it.py_it.it = self->cs_it;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-----------------------BPy_ChainSilhouetteIterator type definition ----------------------------*/
|
||||
|
||||
PyTypeObject ChainSilhouetteIterator_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "ChainSilhouetteIterator",
|
||||
/*tp_basicsize*/ sizeof(BPy_ChainSilhouetteIterator),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ ChainSilhouetteIterator_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ nullptr,
|
||||
/*tp_base*/ &ChainingIterator_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)ChainSilhouetteIterator_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,28 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BPy_ChainingIterator.h"
|
||||
|
||||
#include "../../stroke/ChainingIterators.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject ChainSilhouetteIterator_Type;
|
||||
|
||||
#define BPy_ChainSilhouetteIterator_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&ChainSilhouetteIterator_Type))
|
||||
|
||||
/*---------------------------Python BPy_ChainSilhouetteIterator structure definition----------*/
|
||||
struct BPy_ChainSilhouetteIterator {
|
||||
BPy_ChainingIterator py_c_it;
|
||||
Freestyle::ChainSilhouetteIterator *cs_it;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,309 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_ChainingIterator.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../Interface0D/BPy_ViewVertex.h"
|
||||
#include "../Interface1D/BPy_ViewEdge.h"
|
||||
#include "BPy_AdjacencyIterator.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ChainingIterator_doc,
|
||||
"Class hierarchy: :class:`Iterator` > :class:`ViewEdgeIterator` > :class:`ChainingIterator`\n"
|
||||
"\n"
|
||||
"Base class for chaining iterators. This class is designed to be\n"
|
||||
"overloaded in order to describe chaining rules. It makes the\n"
|
||||
"description of chaining rules easier. The two main methods that need\n"
|
||||
"to overloaded are traverse() and init(). traverse() tells which\n"
|
||||
":class:`ViewEdge` to follow, among the adjacent ones. If you specify\n"
|
||||
"restriction rules (such as \"Chain only ViewEdges of the selection\"),\n"
|
||||
"they will be included in the adjacency iterator (i.e, the adjacent\n"
|
||||
"iterator will only stop on \"valid\" edges).\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__(restrict_to_selection=True, restrict_to_unvisited=True, begin=None, "
|
||||
"orientation=True)``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
"\n"
|
||||
" Builds a Chaining Iterator from the first ViewEdge used for\n"
|
||||
" iteration and its orientation or by using the copy constructor.\n"
|
||||
"\n"
|
||||
" :param restrict_to_selection: Indicates whether to force the chaining\n"
|
||||
" to stay within the set of selected ViewEdges or not.\n"
|
||||
" :type restrict_to_selection: bool\n"
|
||||
" :param restrict_to_unvisited: Indicates whether a ViewEdge that has\n"
|
||||
" already been chained must be ignored ot not.\n"
|
||||
" :type restrict_to_unvisited: bool\n"
|
||||
" :param begin: The ViewEdge from which to start the chain.\n"
|
||||
" :type begin: :class:`ViewEdge` | None\n"
|
||||
" :param orientation: The direction to follow to explore the graph. If\n"
|
||||
" true, the direction indicated by the first ViewEdge is used.\n"
|
||||
" :type orientation: bool\n"
|
||||
" :param brother: \n"
|
||||
" :type brother: ChainingIterator\n");
|
||||
static int check_begin(PyObject *obj, void *v)
|
||||
{
|
||||
if (obj != nullptr && obj != Py_None && !BPy_ViewEdge_Check(obj)) {
|
||||
return 0;
|
||||
}
|
||||
*((PyObject **)v) = obj;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ChainingIterator___init__(BPy_ChainingIterator *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {
|
||||
"restrict_to_selection", "restrict_to_unvisited", "begin", "orientation", nullptr};
|
||||
PyObject *obj1 = nullptr, *obj2 = nullptr, *obj3 = nullptr, *obj4 = nullptr;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!", (char **)kwlist_1, &ChainingIterator_Type, &obj1))
|
||||
{
|
||||
self->c_it = new ChainingIterator(*(((BPy_ChainingIterator *)obj1)->c_it));
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
(void)(obj1 = obj2 = obj3 = obj4 = nullptr),
|
||||
PyArg_ParseTupleAndKeywords(args,
|
||||
kwds,
|
||||
"|O!O!O&O!",
|
||||
(char **)kwlist_2,
|
||||
&PyBool_Type,
|
||||
&obj1,
|
||||
&PyBool_Type,
|
||||
&obj2,
|
||||
check_begin,
|
||||
&obj3,
|
||||
&PyBool_Type,
|
||||
&obj4))
|
||||
{
|
||||
bool restrict_to_selection = (!obj1) ? true : bool_from_PyBool(obj1);
|
||||
bool restrict_to_unvisited = (!obj2) ? true : bool_from_PyBool(obj2);
|
||||
ViewEdge *begin = (!obj3 || obj3 == Py_None) ? nullptr : ((BPy_ViewEdge *)obj3)->ve;
|
||||
bool orientation = (!obj4) ? true : bool_from_PyBool(obj4);
|
||||
self->c_it = new ChainingIterator(
|
||||
restrict_to_selection, restrict_to_unvisited, begin, orientation);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_ve_it.ve_it = self->c_it;
|
||||
self->py_ve_it.py_it.it = self->c_it;
|
||||
|
||||
self->c_it->py_c_it = (PyObject *)self;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ChainingIterator_init_doc,
|
||||
".. method:: init()\n"
|
||||
"\n"
|
||||
" Initializes the iterator context. This method is called each\n"
|
||||
" time a new chain is started. It can be used to reset some\n"
|
||||
" history information that you might want to keep.\n");
|
||||
static PyObject *ChainingIterator_init(BPy_ChainingIterator *self)
|
||||
{
|
||||
if (typeid(*(self->c_it)) == typeid(ChainingIterator)) {
|
||||
PyErr_SetString(PyExc_TypeError, "init() method not properly overridden");
|
||||
return nullptr;
|
||||
}
|
||||
self->c_it->init();
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ChainingIterator_traverse_doc,
|
||||
".. method:: traverse(it)\n"
|
||||
"\n"
|
||||
" This method iterates over the potential next ViewEdges and returns\n"
|
||||
" the one that will be followed next. Returns the next ViewEdge to\n"
|
||||
" follow or None when the end of the chain is reached.\n"
|
||||
"\n"
|
||||
" :param it: The iterator over the ViewEdges adjacent to the end vertex\n"
|
||||
" of the current ViewEdge. The adjacency iterator reflects the\n"
|
||||
" restriction rules by only iterating over the valid ViewEdges.\n"
|
||||
" :type it: :class:`AdjacencyIterator`\n"
|
||||
" :return: Returns the next ViewEdge to follow, or None if chaining ends.\n"
|
||||
" :rtype: :class:`ViewEdge` | None\n");
|
||||
static PyObject *ChainingIterator_traverse(BPy_ChainingIterator *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist[] = {"it", nullptr};
|
||||
PyObject *py_a_it;
|
||||
|
||||
if (typeid(*(self->c_it)) == typeid(ChainingIterator)) {
|
||||
PyErr_SetString(PyExc_TypeError, "traverse() method not properly overridden");
|
||||
return nullptr;
|
||||
}
|
||||
if (!PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!", (char **)kwlist, &AdjacencyIterator_Type, &py_a_it))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (((BPy_AdjacencyIterator *)py_a_it)->a_it) {
|
||||
self->c_it->traverse(*(((BPy_AdjacencyIterator *)py_a_it)->a_it));
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
# else
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static PyMethodDef BPy_ChainingIterator_methods[] = {
|
||||
{"init", (PyCFunction)ChainingIterator_init, METH_NOARGS, ChainingIterator_init_doc},
|
||||
{"traverse",
|
||||
(PyCFunction)ChainingIterator_traverse,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
ChainingIterator_traverse_doc},
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifdef __clang__
|
||||
# pragma clang diagnostic pop
|
||||
# else
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*----------------------ChainingIterator get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ChainingIterator_object_doc,
|
||||
"The ViewEdge object currently pointed by this iterator.\n"
|
||||
"\n"
|
||||
":type: :class:`ViewEdge`\n");
|
||||
static PyObject *ChainingIterator_object_get(BPy_ChainingIterator *self, void * /*closure*/)
|
||||
{
|
||||
if (self->c_it->isEnd()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
|
||||
return nullptr;
|
||||
}
|
||||
ViewEdge *ve = self->c_it->operator*();
|
||||
if (ve) {
|
||||
return BPy_ViewEdge_from_ViewEdge(*ve);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ChainingIterator_next_vertex_doc,
|
||||
"The ViewVertex that is the next crossing.\n"
|
||||
"\n"
|
||||
":type: :class:`ViewVertex`\n");
|
||||
static PyObject *ChainingIterator_next_vertex_get(BPy_ChainingIterator *self, void * /*closure*/)
|
||||
{
|
||||
ViewVertex *v = self->c_it->getVertex();
|
||||
if (v) {
|
||||
return Any_BPy_ViewVertex_from_ViewVertex(*v);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
ChainingIterator_is_incrementing_doc,
|
||||
"True if the current iteration is an incrementation.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *ChainingIterator_is_incrementing_get(BPy_ChainingIterator *self,
|
||||
void * /*closure*/)
|
||||
{
|
||||
return PyBool_from_bool(self->c_it->isIncrementing());
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_ChainingIterator_getseters[] = {
|
||||
{"object",
|
||||
(getter)ChainingIterator_object_get,
|
||||
(setter) nullptr,
|
||||
ChainingIterator_object_doc,
|
||||
nullptr},
|
||||
{"next_vertex",
|
||||
(getter)ChainingIterator_next_vertex_get,
|
||||
(setter) nullptr,
|
||||
ChainingIterator_next_vertex_doc,
|
||||
nullptr},
|
||||
{"is_incrementing",
|
||||
(getter)ChainingIterator_is_incrementing_get,
|
||||
(setter) nullptr,
|
||||
ChainingIterator_is_incrementing_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_ChainingIterator type definition ------------------------------*/
|
||||
|
||||
PyTypeObject ChainingIterator_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "ChainingIterator",
|
||||
/*tp_basicsize*/ sizeof(BPy_ChainingIterator),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ ChainingIterator_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ BPy_ChainingIterator_methods,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_ChainingIterator_getseters,
|
||||
/*tp_base*/ &ViewEdgeIterator_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)ChainingIterator___init__,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,28 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BPy_ViewEdgeIterator.h"
|
||||
|
||||
#include "../../stroke/ChainingIterators.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject ChainingIterator_Type;
|
||||
|
||||
#define BPy_ChainingIterator_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&ChainingIterator_Type))
|
||||
|
||||
/*---------------------------Python BPy_ChainingIterator structure definition----------*/
|
||||
struct BPy_ChainingIterator {
|
||||
BPy_ViewEdgeIterator py_ve_it;
|
||||
Freestyle::ChainingIterator *c_it;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,170 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_CurvePointIterator.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "BPy_Interface0DIterator.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
CurvePointIterator_doc,
|
||||
"Class hierarchy: :class:`Iterator` > :class:`CurvePointIterator`\n"
|
||||
"\n"
|
||||
"Class representing an iterator on a curve. Allows an iterating\n"
|
||||
"outside initial vertices. A CurvePoint is instantiated and returned\n"
|
||||
"through the .object attribute.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args, **kwargs)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__()``\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(step=0.0)``\n"
|
||||
"\n"
|
||||
" Builds a CurvePointIterator object using either the default constructor,\n"
|
||||
" copy constructor, or the overloaded constructor.\n"
|
||||
"\n"
|
||||
" :param brother: A CurvePointIterator object.\n"
|
||||
" :type brother: :class:`CurvePointIterator`\n"
|
||||
" :param step: A resampling resolution with which the curve is resampled.\n"
|
||||
" If zero, no resampling is done (i.e., the iterator iterates over\n"
|
||||
" initial vertices).\n"
|
||||
" :type step: float\n");
|
||||
static int CurvePointIterator_init(BPy_CurvePointIterator *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"brother", nullptr};
|
||||
static const char *kwlist_2[] = {"step", nullptr};
|
||||
PyObject *brother = nullptr;
|
||||
float step;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "|O!", (char **)kwlist_1, &CurvePointIterator_Type, &brother))
|
||||
{
|
||||
if (!brother) {
|
||||
self->cp_it = new CurveInternal::CurvePointIterator();
|
||||
}
|
||||
else {
|
||||
self->cp_it = new CurveInternal::CurvePointIterator(
|
||||
*(((BPy_CurvePointIterator *)brother)->cp_it));
|
||||
}
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &step))
|
||||
{
|
||||
self->cp_it = new CurveInternal::CurvePointIterator(step);
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_it.it = self->cp_it;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------CurvePointIterator get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
CurvePointIterator_object_doc,
|
||||
"The CurvePoint object currently pointed by this iterator.\n"
|
||||
"\n"
|
||||
":type: :class:`CurvePoint`\n");
|
||||
static PyObject *CurvePointIterator_object_get(BPy_CurvePointIterator *self, void * /*closure*/)
|
||||
{
|
||||
if (self->cp_it->isEnd()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
|
||||
return nullptr;
|
||||
}
|
||||
return BPy_CurvePoint_from_CurvePoint(self->cp_it->operator*());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
CurvePointIterator_t_doc,
|
||||
"The curvilinear abscissa of the current point.\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *CurvePointIterator_t_get(BPy_CurvePointIterator *self, void * /*closure*/)
|
||||
{
|
||||
return PyFloat_FromDouble(self->cp_it->t());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
CurvePointIterator_u_doc,
|
||||
"The point parameter at the current point in the stroke (0 <= u <= 1).\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *CurvePointIterator_u_get(BPy_CurvePointIterator *self, void * /*closure*/)
|
||||
{
|
||||
return PyFloat_FromDouble(self->cp_it->u());
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_CurvePointIterator_getseters[] = {
|
||||
{"object",
|
||||
(getter)CurvePointIterator_object_get,
|
||||
(setter) nullptr,
|
||||
CurvePointIterator_object_doc,
|
||||
nullptr},
|
||||
{"t", (getter)CurvePointIterator_t_get, (setter) nullptr, CurvePointIterator_t_doc, nullptr},
|
||||
{"u", (getter)CurvePointIterator_u_get, (setter) nullptr, CurvePointIterator_u_doc, nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_CurvePointIterator type definition ------------------------------*/
|
||||
|
||||
PyTypeObject CurvePointIterator_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "CurvePointIterator",
|
||||
/*tp_basicsize*/ sizeof(BPy_CurvePointIterator),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ CurvePointIterator_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ nullptr,
|
||||
/*tp_iternext*/ nullptr,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_CurvePointIterator_getseters,
|
||||
/*tp_base*/ &Iterator_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)CurvePointIterator_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,28 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_Iterator.h"
|
||||
|
||||
#include "../../stroke/CurveIterators.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject CurvePointIterator_Type;
|
||||
|
||||
#define BPy_CurvePointIterator_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&CurvePointIterator_Type))
|
||||
|
||||
/*---------------------------Python BPy_CurvePointIterator structure definition----------*/
|
||||
struct BPy_CurvePointIterator {
|
||||
BPy_Iterator py_it;
|
||||
Freestyle::CurveInternal::CurvePointIterator *cp_it;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,246 @@
|
||||
/* SPDX-FileCopyrightText: 2004-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#include "BPy_Interface0DIterator.h"
|
||||
|
||||
#include "../BPy_Convert.h"
|
||||
#include "../BPy_Interface1D.h"
|
||||
|
||||
using namespace Freestyle;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//------------------------INSTANCE METHODS ----------------------------------
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0DIterator_doc,
|
||||
"Class hierarchy: :class:`Iterator` > :class:`Interface0DIterator`\n"
|
||||
"\n"
|
||||
"Class defining an iterator over Interface0D elements. An instance of\n"
|
||||
"this iterator is always obtained from a 1D element.\n"
|
||||
"\n"
|
||||
".. method:: __init__(*args)\n"
|
||||
"\n"
|
||||
" Accepted call signatures:\n"
|
||||
"\n"
|
||||
" - ``__init__(brother)``\n"
|
||||
" - ``__init__(it)``\n"
|
||||
"\n"
|
||||
" Construct a nested Interface0DIterator using either the copy constructor\n"
|
||||
" or the constructor that takes an argument of a Function0D.\n"
|
||||
"\n"
|
||||
" :param brother: An Interface0DIterator object.\n"
|
||||
" :type brother: :class:`Interface0DIterator`\n"
|
||||
" :param it: An iterator object to be nested.\n"
|
||||
" :type it: :class:`SVertexIterator` | :class:`CurvePointIterator` | "
|
||||
":class:`StrokeVertexIterator`\n");
|
||||
static int convert_nested_it(PyObject *obj, void *v)
|
||||
{
|
||||
if (!obj || !BPy_Iterator_Check(obj)) {
|
||||
return 0;
|
||||
}
|
||||
Interface0DIteratorNested *nested_it = dynamic_cast<Interface0DIteratorNested *>(
|
||||
((BPy_Iterator *)obj)->it);
|
||||
if (!nested_it) {
|
||||
return 0;
|
||||
}
|
||||
*((Interface0DIteratorNested **)v) = nested_it;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int Interface0DIterator_init(BPy_Interface0DIterator *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static const char *kwlist_1[] = {"it", nullptr};
|
||||
static const char *kwlist_2[] = {"inter", nullptr};
|
||||
static const char *kwlist_3[] = {"brother", nullptr};
|
||||
Interface0DIteratorNested *nested_it;
|
||||
PyObject *brother, *inter;
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O&", (char **)kwlist_1, convert_nested_it, &nested_it))
|
||||
{
|
||||
self->if0D_it = new Interface0DIterator(nested_it->copy());
|
||||
self->at_start = true;
|
||||
self->reversed = false;
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!", (char **)kwlist_2, &Interface1D_Type, &inter))
|
||||
{
|
||||
self->if0D_it = new Interface0DIterator(((BPy_Interface1D *)inter)->if1D->verticesBegin());
|
||||
self->at_start = true;
|
||||
self->reversed = false;
|
||||
}
|
||||
else if ((void)PyErr_Clear(),
|
||||
PyArg_ParseTupleAndKeywords(
|
||||
args, kwds, "O!", (char **)kwlist_3, &Interface0DIterator_Type, &brother))
|
||||
{
|
||||
self->if0D_it = new Interface0DIterator(*(((BPy_Interface0DIterator *)brother)->if0D_it));
|
||||
self->at_start = ((BPy_Interface0DIterator *)brother)->at_start;
|
||||
self->reversed = ((BPy_Interface0DIterator *)brother)->reversed;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid argument(s)");
|
||||
return -1;
|
||||
}
|
||||
self->py_it.it = self->if0D_it;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *Interface0DIterator_iter(BPy_Interface0DIterator *self)
|
||||
{
|
||||
Py_INCREF(self);
|
||||
self->at_start = true;
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
||||
static PyObject *Interface0DIterator_iternext(BPy_Interface0DIterator *self)
|
||||
{
|
||||
if (self->reversed) {
|
||||
if (self->if0D_it->isBegin()) {
|
||||
PyErr_SetNone(PyExc_StopIteration);
|
||||
return nullptr;
|
||||
}
|
||||
self->if0D_it->decrement();
|
||||
}
|
||||
else {
|
||||
if (self->if0D_it->isEnd()) {
|
||||
PyErr_SetNone(PyExc_StopIteration);
|
||||
return nullptr;
|
||||
}
|
||||
if (self->at_start) {
|
||||
self->at_start = false;
|
||||
}
|
||||
else if (self->if0D_it->atLast()) {
|
||||
PyErr_SetNone(PyExc_StopIteration);
|
||||
return nullptr;
|
||||
}
|
||||
else {
|
||||
self->if0D_it->increment();
|
||||
}
|
||||
}
|
||||
Interface0D *if0D = self->if0D_it->operator->();
|
||||
return Any_BPy_Interface0D_from_Interface0D(*if0D);
|
||||
}
|
||||
|
||||
/*----------------------Interface0DIterator get/setters ----------------------------*/
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0DIterator_object_doc,
|
||||
"The 0D object currently pointed to by this iterator. The object may be an\n"
|
||||
"instance of :class:`Interface0D` or one of its subclasses. For example if\n"
|
||||
"the iterator has been created from the `vertices_begin()` method of the\n"
|
||||
":class:`Stroke` class, the .object property refers to a :class:`StrokeVertex`\n"
|
||||
"object.\n"
|
||||
"\n"
|
||||
":type: :class:`Interface0D`\n");
|
||||
static PyObject *Interface0DIterator_object_get(BPy_Interface0DIterator *self, void * /*closure*/)
|
||||
{
|
||||
if (self->if0D_it->isEnd()) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "iteration has stopped");
|
||||
return nullptr;
|
||||
}
|
||||
return Any_BPy_Interface0D_from_Interface0D(self->if0D_it->operator*());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0DIterator_t_doc,
|
||||
"The curvilinear abscissa of the current point.\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *Interface0DIterator_t_get(BPy_Interface0DIterator *self, void * /*closure*/)
|
||||
{
|
||||
return PyFloat_FromDouble(self->if0D_it->t());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0DIterator_u_doc,
|
||||
"The point parameter at the current point in the 1D element (0 <= u <= 1).\n"
|
||||
"\n"
|
||||
":type: float\n");
|
||||
static PyObject *Interface0DIterator_u_get(BPy_Interface0DIterator *self, void * /*closure*/)
|
||||
{
|
||||
return PyFloat_FromDouble(self->if0D_it->u());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
Interface0DIterator_at_last_doc,
|
||||
"True if the iterator points to the last valid element.\n"
|
||||
"For its counterpart (pointing to the first valid element), use it.is_begin.\n"
|
||||
"\n"
|
||||
":type: bool\n");
|
||||
static PyObject *Interface0DIterator_at_last_get(BPy_Interface0DIterator *self, void * /*closure*/)
|
||||
{
|
||||
return PyBool_from_bool(self->if0D_it->atLast());
|
||||
}
|
||||
|
||||
static PyGetSetDef BPy_Interface0DIterator_getseters[] = {
|
||||
{"object",
|
||||
(getter)Interface0DIterator_object_get,
|
||||
(setter) nullptr,
|
||||
Interface0DIterator_object_doc,
|
||||
nullptr},
|
||||
{"t", (getter)Interface0DIterator_t_get, (setter) nullptr, Interface0DIterator_t_doc, nullptr},
|
||||
{"u", (getter)Interface0DIterator_u_get, (setter) nullptr, Interface0DIterator_u_doc, nullptr},
|
||||
{"at_last",
|
||||
(getter)Interface0DIterator_at_last_get,
|
||||
(setter) nullptr,
|
||||
Interface0DIterator_at_last_doc,
|
||||
nullptr},
|
||||
{nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
|
||||
};
|
||||
|
||||
/*-----------------------BPy_Interface0DIterator type definition ------------------------------*/
|
||||
|
||||
PyTypeObject Interface0DIterator_Type = {
|
||||
/*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0)
|
||||
/*tp_name*/ "Interface0DIterator",
|
||||
/*tp_basicsize*/ sizeof(BPy_Interface0DIterator),
|
||||
/*tp_itemsize*/ 0,
|
||||
/*tp_dealloc*/ nullptr,
|
||||
/*tp_vectorcall_offset*/ 0,
|
||||
/*tp_getattr*/ nullptr,
|
||||
/*tp_setattr*/ nullptr,
|
||||
/*tp_as_async*/ nullptr,
|
||||
/*tp_repr*/ nullptr,
|
||||
/*tp_as_number*/ nullptr,
|
||||
/*tp_as_sequence*/ nullptr,
|
||||
/*tp_as_mapping*/ nullptr,
|
||||
/*tp_hash*/ nullptr,
|
||||
/*tp_call*/ nullptr,
|
||||
/*tp_str*/ nullptr,
|
||||
/*tp_getattro*/ nullptr,
|
||||
/*tp_setattro*/ nullptr,
|
||||
/*tp_as_buffer*/ nullptr,
|
||||
/*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
/*tp_doc*/ Interface0DIterator_doc,
|
||||
/*tp_traverse*/ nullptr,
|
||||
/*tp_clear*/ nullptr,
|
||||
/*tp_richcompare*/ nullptr,
|
||||
/*tp_weaklistoffset*/ 0,
|
||||
/*tp_iter*/ (getiterfunc)Interface0DIterator_iter,
|
||||
/*tp_iternext*/ (iternextfunc)Interface0DIterator_iternext,
|
||||
/*tp_methods*/ nullptr,
|
||||
/*tp_members*/ nullptr,
|
||||
/*tp_getset*/ BPy_Interface0DIterator_getseters,
|
||||
/*tp_base*/ &Iterator_Type,
|
||||
/*tp_dict*/ nullptr,
|
||||
/*tp_descr_get*/ nullptr,
|
||||
/*tp_descr_set*/ nullptr,
|
||||
/*tp_dictoffset*/ 0,
|
||||
/*tp_init*/ (initproc)Interface0DIterator_init,
|
||||
/*tp_alloc*/ nullptr,
|
||||
/*tp_new*/ nullptr,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,30 @@
|
||||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup freestyle
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../BPy_Iterator.h"
|
||||
|
||||
#include "../../view_map/Interface0D.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern PyTypeObject Interface0DIterator_Type;
|
||||
|
||||
#define BPy_Interface0DIterator_Check(v) \
|
||||
(PyObject_IsInstance((PyObject *)v, (PyObject *)&Interface0DIterator_Type))
|
||||
|
||||
/*---------------------------Python BPy_Interface0DIterator structure definition----------*/
|
||||
struct BPy_Interface0DIterator {
|
||||
BPy_Iterator py_it;
|
||||
Freestyle::Interface0DIterator *if0D_it;
|
||||
bool reversed;
|
||||
bool at_start;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user