code review, patch neesd some more work. http://www.pasteall.org/pic/show.php?id=32822
On Thu, Jun 7, 2012 at 3:36 PM, Antonio Ospite <[email protected]> wrote: > On Tue, 5 Jun 2012 13:06:08 +0200 > Antonio Ospite <[email protected]> wrote: > >> On Tue, 5 Jun 2012 12:54:12 +0200 >> Campbell Barton <[email protected]> wrote: >> >> > On Fri, Jun 1, 2012 at 3:06 PM, Antonio Ospite <[email protected]> >> > wrote: >> [...] >> > > >> > > On Wed, 15 Feb 2012 23:37:09 +0100 >> > > Antonio Ospite <[email protected]> wrote: >> > > >> [...] >> > >> I could use something like: >> > >> scene.objects.sort(key=some key based on objects properties) >> > >> mesh.faces.sort(key=some key [face index?] based on faces and vertices >> > >> properties) >> > > >> > > This would be handy for my use case, maybe it is a bit of a stretch to >> > > use modeling structures for rendering operations, so I will accept a >> > > "you're doing it wrong" type of comments here :) >> [...] >> > > >> > > This question boils down to: is the ability to sort faces arbitrarily >> > > (or other elements) something modeling tools can make use of? >> > >> > replying on a single issue if face sorting, while you cant ensure >> > order when adding faces - which may be added at any index. >> > there is support for sorting: see >> > BM_mesh_remap >> > >> >> I'll take a look, thanks. >> >> > adding support for something like this isnt so hard: >> > faces.sort(key=lambda f: f.calc_area()) >> > >> >> I'll try to add this and will send a patch if I succeed. > > I've got an experimental patch for BMElemSeq.sort() but I have a doubt, > when I iterate on the bmesh elements after sorting them I don't get the > elements in the order of their indices, look at the attached > BMElemSeq_sort.log file. > > I am attaching the test script too, see BMElemSeq_sort_test.py. > > And I am inlining the patch so you can comment it where needed like > quoting a regular email, it is just a prototype, and it does not follow > the blender style either, but it should illustrate the idea I have in > mind for the implementation. > > With this patch VRM can implement the simple painter algorithm for > the visibility problem, with just a call to: > > mesh.faces.sort(key=lambda f: max([v.co[2] for v in f.verts])) > > (just sorting on 'z' is enough because I do that in Normalized View > Coordinates) > > Thanks, > Antonio > > diff --git a/CMakeLists.txt b/CMakeLists.txt > index 191fb61..8f591ed 100644 > --- a/CMakeLists.txt > +++ b/CMakeLists.txt > @@ -1428,8 +1428,8 @@ elseif(APPLE) > > set(EXETYPE MACOSX_BUNDLE) > > - set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -g") > - set(CMAKE_CXX_FLAGS_DEBUG "-fno-strict-aliasing -g") > + set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -ggdb") > + set(CMAKE_CXX_FLAGS_DEBUG "-fno-strict-aliasing -ggdb") > if(CMAKE_OSX_ARCHITECTURES MATCHES "i386") > set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic > -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller") > set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic > -ftree-vectorize -msse -msse2 -fvariable-expansion-in-unroller") > diff --git a/source/blender/python/bmesh/bmesh_py_types.c > b/source/blender/python/bmesh/bmesh_py_types.c > index 053dac7..5ed67bc 100644 > --- a/source/blender/python/bmesh/bmesh_py_types.c > +++ b/source/blender/python/bmesh/bmesh_py_types.c > @@ -2083,6 +2083,200 @@ static PyObject > *bpy_bmelemseq_index_update(BPy_BMElemSeq *self) > Py_RETURN_NONE; > } > > +PyDoc_STRVAR(bpy_bmelemseq_sort_doc, > +".. method:: sort(key=None, reverse=False)\n" > +"\n" > +" Sort the elements of this sequence.\n" > +"\n" > +" :arg key: Sequence of verts.\n" > +" :type key: :function: returning a number\n" > +" :arg reverse: Reverse the order of the elements\n" > +" :type reverse: :boolean:\n" > +"\n" > +" .. code-block:: python\n" > +"\n" > +" mesh.faces.sort(key=lambda f: f.calc_area())\n" > +"\n" > +); > +static PyObject *bpy_bmelemseq_sort(BPy_BMElemSeq *self, PyObject *args, > PyObject *kw) > +{ > + PyObject *keyfunc = NULL; /* optional */ > + int reverse = FALSE; /* optional */ > + static const char *kwlist[] = {"key", "reverse", NULL}; > + int n_elem = 0; > + > + BMIter iter; > + BMElem *ele; > + PyObject *py_elem = Py_None; > + PyObject *index = NULL; > + > + const char htype = bm_iter_itype_htype_map[self->itype]; > + > + double *keys = NULL; > + int *elem_idx = NULL; > + int *elem_map_idx = NULL; > + > + int *vert_idx = NULL; > + int *edge_idx = NULL; > + int *face_idx = NULL; > + int i; > + int j; > + > + BMesh *bm = self->bm; > + > + BPY_BM_CHECK_OBJ(self); > + if (args != NULL) { > + if(!PyArg_ParseTupleAndKeywords(args, kw, > + "|Oi:BMElemSeq.sort", > + (char **)kwlist, > + &keyfunc, &reverse)) > + return NULL; > + } > + fprintf(stderr, "%s: key: %p\n", __func__, keyfunc); > + fprintf(stderr, "%s: reverse: %d\n", __func__, reverse); > + > + n_elem = BM_mesh_elem_count(bm, htype); > + fprintf(stderr, "%s: sequence size: %d\n", __func__, n_elem); > + > + keys = malloc(sizeof(*keys) * n_elem); > + if (keys == NULL) > + return NULL; > + > + elem_idx = malloc(sizeof(*elem_idx) * n_elem); > + if (elem_idx == NULL) > + goto out_free_keys; > + > + elem_map_idx = malloc(sizeof(*elem_map_idx) * n_elem); > + if (elem_map_idx == NULL) > + goto out_free_elem_idx; > + > + i = 0; > + BM_ITER_BPY_BM_SEQ (ele, &iter, self) { > + if (keyfunc != NULL) { > + py_elem = BPy_BMElem_CreatePyObject(self->bm, > (BMHeader *)ele); > + if (py_elem == Py_None) { > + fprintf(stderr, "%s: failed to create a > python element!\n", __func__); > + goto out; > + } > + index = PyObject_CallFunctionObjArgs(keyfunc, > py_elem, NULL); > + /* Check that the result is a number? */ > + > + keys[i] = PyFloat_AsDouble(index); > + } else { > + keys[i] = (double)i; > + } > + > + i++; > + } > + > + fprintf(stderr, "%s: original keys\n", __func__); > + for (i = 0; i < n_elem; i++) { > + fprintf(stderr, "%s: key: %g\n", __func__, keys[i]); > + } > + fprintf(stderr, "\n"); > + > + /* initialize the index array */ > + for (i = 0; i < n_elem; i++) > + elem_idx[i] = i; > + > + fprintf(stderr, "%s: elem_idx\n", __func__); > + for (i = 0; i < n_elem; i++) { > + fprintf(stderr, "%s: elem idx: %d\n", __func__, elem_idx[i]); > + } > + fprintf(stderr, "\n"); > + > + /* sort the index array according to the order of the 'keys' array */ > + for (i = 0; i < n_elem - 1; i++) { > + for(j = 0; j < n_elem - i - 1; j++) { > + if (reverse == 0) { > + if (keys[elem_idx[j]] > keys[elem_idx[j+1]]) { > + int tmp; > + tmp = elem_idx[j]; > + elem_idx[j] = elem_idx[j+1]; > + elem_idx[j+1] = tmp; > + } > + } else { > + if (keys[elem_idx[j]] < keys[elem_idx[j+1]]) { > + int tmp; > + tmp = elem_idx[j]; > + elem_idx[j] = elem_idx[j+1]; > + elem_idx[j+1] = tmp; > + } > + } > + } > + } > + > + fprintf(stderr, "%s: elem_idx sorted\n", __func__); > + for (i = 0; i < n_elem; i++) { > + fprintf(stderr, "%s: elem idx: %d\n", __func__, elem_idx[i]); > + } > + fprintf(stderr, "\n"); > + > + fprintf(stderr, "%s: sorted keys\n", __func__); > + for (i=0; i < n_elem; i++) { > + fprintf(stderr, "%s: key: %g\n", __func__, keys[elem_idx[i]]); > + } > + fprintf(stderr, "\n"); > + > + /* print the mapping, just for debug */ > + fprintf(stderr, "%s: mapping of elem_idx\n", __func__); > + for (i = 0; i < n_elem; i++) { > + fprintf(stderr, "%s: new_index <- orig_index: %-3d <- %3d\n", > + __func__, i, elem_idx[i]); > + } > + fprintf(stderr, "\n"); > + > + /* initialize the map array > + * > + * whe need to know the index such that > + * if used as the new_index in BM_mesh_remap() will give the > + * order of the sorted keys like in elem_idx */ > + for (i = 0; i < n_elem; i++) { > + elem_map_idx[elem_idx[i]] = i; > + } > + > + fprintf(stderr, "%s: elem_map_idx\n", __func__); > + for (i = 0; i < n_elem; i++) { > + fprintf(stderr, "%s: map idx: %d\n", __func__, > elem_map_idx[i]); > + } > + fprintf(stderr, "\n"); > + > + > + switch ((BMIterType)self->itype) { > + case BM_VERTS_OF_MESH: > + vert_idx = elem_map_idx; > + break; > + case BM_EDGES_OF_MESH: > + edge_idx = elem_map_idx; > + break; > + case BM_FACES_OF_MESH: > + face_idx = elem_map_idx; > + break; > + default: > + fprintf(stderr, "%s: element type not supported > (%d)!\n", > + __func__, self->itype); > + goto out; > + } > + > + fprintf(stderr, "%s: Calling BM_mesh_remap (verts:%p, edges:%p, > faces:%p)!\n", > + __func__, vert_idx, edge_idx, face_idx); > + > + BM_mesh_remap(bm, vert_idx, edge_idx, face_idx); > + BM_mesh_elem_index_ensure(bm, htype); > + > + fprintf(stderr, "%s: REMAPPING done!\n\n", __func__); > + > +out: > + free(elem_map_idx); > + > +out_free_elem_idx: > + free(elem_idx); > + > +out_free_keys: > + free(keys); > + > + Py_RETURN_NONE; > +} > > static struct PyMethodDef bpy_bmesh_methods[] = { > /* utility */ > @@ -2166,6 +2360,7 @@ static struct PyMethodDef bpy_bmloop_methods[] = { > static struct PyMethodDef bpy_bmelemseq_methods[] = { > /* odd function, initializes index values */ > {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, > bpy_bmelemseq_index_update_doc}, > + {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, > bpy_bmelemseq_sort_doc}, > {NULL, NULL, 0, NULL} > }; > > @@ -2175,6 +2370,7 @@ static struct PyMethodDef bpy_bmvertseq_methods[] = { > > /* odd function, initializes index values */ > {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, > bpy_bmelemseq_index_update_doc}, > + {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, > bpy_bmelemseq_sort_doc}, > {NULL, NULL, 0, NULL} > }; > > @@ -2186,6 +2382,7 @@ static struct PyMethodDef bpy_bmedgeseq_methods[] = { > > /* odd function, initializes index values */ > {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, > bpy_bmelemseq_index_update_doc}, > + {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, > bpy_bmelemseq_sort_doc}, > {NULL, NULL, 0, NULL} > }; > > @@ -2197,12 +2394,14 @@ static struct PyMethodDef bpy_bmfaceseq_methods[] = { > > /* odd function, initializes index values */ > {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, > bpy_bmelemseq_index_update_doc}, > + {"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, > bpy_bmelemseq_sort_doc}, > {NULL, NULL, 0, NULL} > }; > > static struct PyMethodDef bpy_bmloopseq_methods[] = { > /* odd function, initializes index values */ > /* no: index_update() function since we cant iterate over loops */ > + /* no: sort() function since we cant iterate over loops */ > {NULL, NULL, 0, NULL} > }; > > -- > Antonio Ospite > http://ao2.it > > A: Because it messes up the order in which people normally read text. > See http://en.wikipedia.org/wiki/Posting_style > Q: Why is top-posting such a bad thing? > > _______________________________________________ > Bf-python mailing list > [email protected] > http://lists.blender.org/mailman/listinfo/bf-python > -- - Campbell _______________________________________________ Bf-python mailing list [email protected] http://lists.blender.org/mailman/listinfo/bf-python
