# edge_list not working with IndexFaceSet

Considering for example,

pl=implicit_plot3d((lambda x,y,z: x^2+y^2+z^2-1),
(x,-1,1),(y,-1,1),(z,-1,1), plot_points=[10,10,10])
pl.triangulate()


Then,

• pl.vertex_list() returns the vertex list and
• pl.index_faces() also works perfectly and returns the triangular faces.

However, pl.edge_list() gives the following error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-388-05ccc951c815> in <module>
----> 1 st.edge_list()

.. site-packages/sage/plot/plot3d/index_face_set.pyx in sage.plot.plot3d.index_face_set.IndexFaceSet.edge_list (build/cythonized/sage/plot/plot3d/index_face_set.c:9602)()
745             ((1.0, -2.0, 3.0), (1.0, 2.0, 3.0))
746         """
--> 747         return list(self.edges())
748
749     def vertices(self):

.. /site-packages/sage/plot/plot3d/index_face_set.pyx in sage.plot.plot3d.index_face_set.IndexFaceSet.edges (build/cythonized/sage/plot/plot3d/index_face_set.c:9522)()
732             ((1.0, -2.0, 3.0), (1.0, 2.0, 3.0))
733         """
--> 734         return EdgeIter(self)
735
736     def edge_list(self):

... site-packages/sage/plot/plot3d/index_face_set.pyx in sage.plot.plot3d.index_face_set.EdgeIter.__init__ (build/cythonized/sage/plot/plot3d/index_face_set.c:21418)()
1735         self.set = face_set
1736         if not self.set.enclosed:
-> 1737             raise TypeError("Must be closed to use the simple iterator.")
1738         self.i = 0
1739         self.j = 0

TypeError: Must be closed to use the simple iterator.

edit retag close merge delete

Sort by » oldest newest most voted

The corresponding IndexFaceSet is not enclosed. According to documentation:

is_enclosed()

Return a boolean telling whether or not it is necessary to render the back sides of the polygons (assuming, of course, that they have the correct orientation).

This is calculated in by verifying the opposite edges of the rendered domain either line up or are pinched together.

I do not know a reason for why it's not enclosed, but one can extract edges (as tuples of points) from the faces like:

edge_set = set.union( *[ {(f[0],f[1]),(f[0],f[2]),(f[1],f[2])} for f in map(sorted,pl.faces()) ] )

Here the points in each face are first sorted to ensure that they will consistently appear as first/second elements of edges, and then 3 edges (i.e. sides of the triangle) are extracted from it. We form a set to exclude duplicated edges, later it can be converted to a list if needed. In the given example, there are 1,074 distinct edges.

more

Thanks a lot for the answer. I also found that IndexFaceSet allows to set enclosed=True so that implicit_plot3d also does.

In this way, the sequence:

pl = implicit_plot3d(x**2 + y**2 + z**2 - 1, (x, -1, 1), (y, -1, 1), (z, -1, 1), enclosed=True, plot_points=10)
pl.triangulate()
pl.edge_list()


is also working.

Thanks again, Asier

( 2021-02-15 11:32:40 +0200 )edit