Ask Your Question

edge_list not working with IndexFaceSet

asked 2021-02-11 12:40:15 +0100

asier gravatar image

updated 2021-02-12 10:14:59 +0100

slelievre gravatar image

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.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())
    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)
    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 flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2021-02-12 22:12:57 +0100

Max Alekseyev gravatar image

updated 2021-02-12 22:31:53 +0100

The corresponding IndexFaceSet is not enclosed. According to documentation:


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.

edit flag offensive delete link 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)

is also working.

Thanks again, Asier

asier gravatar imageasier ( 2021-02-15 11:32:40 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2021-02-11 12:40:15 +0100

Seen: 64 times

Last updated: Feb 15