return 0;
}
else if (BPy_BMFace_Check(value)) {
- BPY_BM_CHECK_INT(value);
+ BPY_BM_CHECK_SOURCE_INT(value, bm, "faces.active = f");
- if (((BPy_BMFace *)value)->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "faces.active = f: f is from another mesh");
- return -1;
- }
- else {
- bm->act_face = ((BPy_BMFace *)value)->f;
- return 0;
- }
+ bm->act_face = ((BPy_BMFace *)value)->f;
+ return 0;
}
else {
PyErr_Format(PyExc_TypeError,
else {
BMesh *bm = self->bm;
- BPY_BM_CHECK_OBJ(py_face);
-
- if (py_face->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "BMVert.copy_from_face_interp(face): face is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "copy_from_face_interp()");
BM_vert_interp_from_face(bm, self->v, py_face->f);
return NULL;
}
- BPY_BM_CHECK_OBJ(value);
-
- if (self->bm != value->bm) {
- PyErr_SetString(PyExc_ValueError,
- "BMEdge.other_vert(vert): vert is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "BMEdge.other_vert(vert)");
other = BM_edge_other_vert(self->e, value->v);
else {
BMesh *bm = self->bm;
- BPY_BM_CHECK_OBJ(py_face);
-
- if (py_face->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "BMFace.copy_from_face_interp(face): face is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "BMFace.copy_from_face_interp(face)");
BM_face_interp_from_face(bm, self->f, py_face->f);
else {
BMesh *bm = self->bm;
- BPY_BM_CHECK_OBJ(py_face);
-
- if (py_face->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "BMLoop.copy_from_face_interp(face): face is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "BMLoop.copy_from_face_interp(face)");
BM_loop_interp_from_face(bm, self->l, py_face->f, do_vertex, do_multires);
else {
BMesh *bm = self->bm;
- BPY_BM_CHECK_OBJ(value);
-
- if (value->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "verts.remove(vert): vert is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(value, bm, "verts.remove(vert)");
BM_vert_kill(bm, value->v);
bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
else {
BMesh *bm = self->bm;
- BPY_BM_CHECK_OBJ(value);
-
- if (value->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "edges.remove(edge): edge is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(value, bm, "edges.remove(edges)");
BM_edge_kill(bm, value->e);
bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
else {
BMesh *bm = self->bm;
- BPY_BM_CHECK_OBJ(value);
-
- if (value->bm != bm) {
- PyErr_SetString(PyExc_ValueError,
- "faces.remove(face): face is from another mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(value, bm, "faces.remove(face)");
BM_face_kill(bm, value->f);
bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
}
}
+int bpy_bm_generic_valid_check_source(BPy_BMGeneric *self, BMesh *bm_source, const char *error_prefix)
+{
+ int ret = bpy_bm_generic_valid_check(self);
+ if (LIKELY(ret == 0)) {
+ if (UNLIKELY(self->bm != bm_source)) {
+ /* could give more info here */
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: BMesh data of type %.200s is from another mesh",
+ error_prefix, Py_TYPE(self)->tp_name);
+ ret = -1;
+ }
+ }
+ return ret;
+}
+
void bpy_bm_generic_invalidate(BPy_BMGeneric *self)
{
self->bm = NULL;
PyObject *BPy_BMElem_CreatePyObject(BMesh *bm, BMHeader *ele); /* just checks type and creates v/e/f/l */
-int bpy_bm_generic_valid_check(BPy_BMGeneric *self);
-void bpy_bm_generic_invalidate(BPy_BMGeneric *self);
-
void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ssize_t max, Py_ssize_t *r_size,
const char htype,
const char do_unique_check, const char do_bm_check,
char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32]);
char *BPy_BMElem_StringFromHType(const char htype);
-
-#define BPY_BM_CHECK_OBJ(obj) if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return NULL; } (void)0
-#define BPY_BM_CHECK_INT(obj) if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return -1; } (void)0
+void bpy_bm_generic_invalidate(BPy_BMGeneric *self);
+int bpy_bm_generic_valid_check(BPy_BMGeneric *self);
+int bpy_bm_generic_valid_check_source(BPy_BMGeneric *self, BMesh *bm_source, const char *error_prefix);
+
+#define BPY_BM_CHECK_OBJ(obj) \
+ if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return NULL; } (void)0
+#define BPY_BM_CHECK_INT(obj) \
+ if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return -1; } (void)0
+
+/* macros like BPY_BM_CHECK_OBJ/BPY_BM_CHECK_INT that ensure we're from the right BMesh */
+#define BPY_BM_CHECK_SOURCE_OBJ(obj, bm, errmsg) \
+ if (UNLIKELY(bpy_bm_generic_valid_check_source((BPy_BMGeneric *)obj, bm, errmsg) == -1)) { return NULL; } (void)0
+#define BPY_BM_CHECK_SOURCE_INT(obj, bm, errmsg) \
+ if (UNLIKELY(bpy_bm_generic_valid_check_source((BPy_BMGeneric *)obj, bm, errmsg) == -1)) { return -1; } (void)0
#define BPY_BM_IS_VALID(obj) (LIKELY((obj)->bm != NULL))
return NULL;
}
- BPY_BM_CHECK_OBJ(value);
-
- if (self->bm != value->bm) {
- PyErr_SetString(PyExc_ValueError,
- "Element is not from this mesh");
- return NULL;
- }
+ BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "select_history.add()");
BM_select_history_store(self->bm, value->ele);
return NULL;
}
- BPY_BM_CHECK_OBJ(value);
+ BPY_BM_CHECK_SOURCE_OBJ(value, self->bm, "select_history.remove()");
- if ((self->bm != value->bm) ||
- (BM_select_history_remove(self->bm, value->ele) == FALSE))
- {
+ if (BM_select_history_remove(self->bm, value->ele) == FALSE) {
PyErr_SetString(PyExc_ValueError,
"Element not found in selection history");
return NULL;