Ask Your Question
1

edge_list not working with IndexFaceSet

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

asier gravatar image

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

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

1 Answer

Sort by ยป oldest newest most voted
1

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

Max Alekseyev gravatar image

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

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.

edit flag offensive delete link more

Comments

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

asier gravatar imageasier ( 2021-02-15 11:32:40 +0200 )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

Stats

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

Seen: 150 times

Last updated: Feb 15 '21