static PyObject *bpy_bm_utils_edge_rotate(PyObject *UNUSED(self), PyObject *args)
{
	BPy_BMEdge *py_edge;
	bool do_ccw = false;

	BMesh *bm;
	BMEdge *e_new = NULL;

	if (!PyArg_ParseTuple(
	        args, "O!|O&:edge_rotate",
	        &BPy_BMEdge_Type, &py_edge,
	        PyC_ParseBool, &do_ccw))
	{
		return NULL;
	}

	BPY_BM_CHECK_OBJ(py_edge);

	bm = py_edge->bm;

	e_new = BM_edge_rotate(bm, py_edge->e, do_ccw, 0);

	if (e_new) {
		return BPy_BMEdge_CreatePyObject(bm, e_new);
	}
	else {
		Py_RETURN_NONE;
	}
}
示例#2
0
static PyObject *bpy_bm_utils_edge_rotate(PyObject *UNUSED(self), PyObject *args)
{
	BPy_BMEdge *py_edge;
	int do_ccw = FALSE;

	BMesh *bm;
	BMEdge *e_new = NULL;

	if (!PyArg_ParseTuple(args, "O!|i:edge_rotate",
	                      &BPy_BMEdge_Type, &py_edge,
	                      &do_ccw))
	{
		return NULL;
	}

	BPY_BM_CHECK_OBJ(py_edge);

	bm = py_edge->bm;

	e_new = BM_edge_rotate(bm, py_edge->e, do_ccw, 0); /* BMESH_TODO - expose to API */

	if (e_new) {
		return BPy_BMEdge_CreatePyObject(bm, e_new);
	}
	else {
		Py_RETURN_NONE;
	}
}
示例#3
0
/**
 * \note This function sets the edge indices to invalid values.
 */
void BM_mesh_beautify_fill(
        BMesh *bm, BMEdge **edge_array, const int edge_array_len,
        const short flag, const short method,
        const short oflag_edge, const short oflag_face)
{
	Heap *eheap;             /* edge heap */
	HeapNode **eheap_table;  /* edge index aligned table pointing to the eheap */

	GSet       **edge_state_arr  = MEM_callocN((size_t)edge_array_len * sizeof(GSet *), __func__);
	BLI_mempool *edge_state_pool = BLI_mempool_create(sizeof(EdRotState), 0, 512, BLI_MEMPOOL_NOP);
	int i;

#ifdef DEBUG_TIME
	TIMEIT_START(beautify_fill);
#endif

	eheap = BLI_heap_new_ex((uint)edge_array_len);
	eheap_table = MEM_mallocN(sizeof(HeapNode *) * (size_t)edge_array_len, __func__);

	/* build heap */
	for (i = 0; i < edge_array_len; i++) {
		BMEdge *e = edge_array[i];
		const float cost = bm_edge_calc_rotate_beauty(e, flag, method);
		if (cost < 0.0f) {
			eheap_table[i] = BLI_heap_insert(eheap, cost, e);
		}
		else {
			eheap_table[i] = NULL;
		}

		BM_elem_index_set(e, i);  /* set_dirty */
	}
	bm->elem_index_dirty |= BM_EDGE;

	while (BLI_heap_is_empty(eheap) == false) {
		BMEdge *e = BLI_heap_popmin(eheap);
		i = BM_elem_index_get(e);
		eheap_table[i] = NULL;

		BLI_assert(BM_edge_face_count_is_equal(e, 2));

		e = BM_edge_rotate(bm, e, false, BM_EDGEROT_CHECK_EXISTS);

		BLI_assert(e == NULL || BM_edge_face_count_is_equal(e, 2));

		if (LIKELY(e)) {
			GSet *e_state_set = edge_state_arr[i];

			/* add the new state into the set so we don't move into this state again
			 * note: we could add the previous state too but this isn't essential)
			 *       for avoiding eternal loops */
			EdRotState *e_state = BLI_mempool_alloc(edge_state_pool);
			erot_state_current(e, e_state);
			if (UNLIKELY(e_state_set == NULL)) {
				edge_state_arr[i] = e_state_set = erot_gset_new();  /* store previous state */
			}
			BLI_assert(BLI_gset_haskey(e_state_set, (void *)e_state) == false);
			BLI_gset_insert(e_state_set, e_state);


			// printf("  %d -> %d, %d\n", i, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2));

			/* maintain the index array */
			edge_array[i] = e;
			BM_elem_index_set(e, i);

			/* recalculate faces connected on the heap */
			bm_edge_update_beauty_cost(e, eheap, eheap_table, edge_state_arr,
			                           (const BMEdge **)edge_array, edge_array_len,
			                           flag, method);

			/* update flags */
			if (oflag_edge) {
				BMO_edge_flag_enable(bm, e, oflag_edge);
			}

			if (oflag_face) {
				BMO_face_flag_enable(bm, e->l->f, oflag_face);
				BMO_face_flag_enable(bm, e->l->radial_next->f, oflag_face);
			}
		}
	}

	BLI_heap_free(eheap, NULL);
	MEM_freeN(eheap_table);

	for (i = 0; i < edge_array_len; i++) {
		if (edge_state_arr[i]) {
			BLI_gset_free(edge_state_arr[i], NULL);
		}
	}

	MEM_freeN(edge_state_arr);
	BLI_mempool_destroy(edge_state_pool);

#ifdef DEBUG_TIME
	TIMEIT_END(beautify_fill);
#endif
}