Indexed face sets - 3D Graphics

Skip to content
Back to top
View this page
Edit this page

# Indexed face sets

Graphics3D object that consists of a list of polygons, also used for triangulations of other objects.

Usually these objects are not created directly by users.

AUTHORS:

- Robert Bradshaw (2007-08-26): initial version

- Robert Bradshaw (2007-08-28): significant optimizations

Todo

Smooth triangles using vertex normals

class sage.plot.plot3d.index_face_set.EdgeIter

  Bases: `object`

  A class for iteration over edges

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.shapes import *
      sage: S = Box(1,2,3)
      sage: len(list(S.edges())) == 12   # indirect doctest
      True

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.shapes import *
      >>> S = Box(Integer(1),Integer(2),Integer(3))
      >>> len(list(S.edges())) == Integer(12)   # indirect doctest
      True

class sage.plot.plot3d.index_face_set.FaceIter

  Bases: `object`

  A class for iteration over faces

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.shapes import *
      sage: S = Box(1,2,3)
      sage: len(list(S.faces())) == 6   # indirect doctest
      True

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.shapes import *
      >>> S = Box(Integer(1),Integer(2),Integer(3))
      >>> len(list(S.faces())) == Integer(6)   # indirect doctest
      True

class sage.plot.plot3d.index_face_set.IndexFaceSet

  Bases: `PrimitiveObject`

  Graphics3D object that consists of a list of polygons, also used for triangulations of other objects.

  Polygons (mostly triangles and quadrilaterals) are stored in the c struct `face_c` (see transform.pyx). Rather than storing the points directly for each polygon, each face consists a list of pointers into a common list of points which are basically triples of doubles in a `point_c`.

  Moreover, each face has an attribute `color` which is used to store color information when faces are colored. The red/green/blue components are then available as floats between 0 and 1 using `color.r,color.g,color.b`.

  Usually these objects are not created directly by users.

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.index_face_set import IndexFaceSet
      sage: S = IndexFaceSet([[(1,0,0),(0,1,0),(0,0,1)], [(1,0,0),(0,1,0),(0,0,0)]])
      sage: S.face_list()
      [[(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 0.0)]]
      sage: S.vertex_list()
      [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0), (0.0, 0.0, 0.0)]

      sage: def make_face(n): return [(0,0,n),(0,1,n),(1,1,n),(1,0,n)]
      sage: S = IndexFaceSet([make_face(n) for n in range(10)])
      sage: S.show()

      sage: point_list = [(1,0,0),(0,1,0)] + [(0,0,n) for n in range(10)]
      sage: face_list = [[0,1,n] for n in range(2,10)]
      sage: S = IndexFaceSet(face_list, point_list, color='red')
      sage: S.face_list()
      [[(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 0.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 2.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 3.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 4.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 5.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 6.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 7.0)]]
      sage: S.show()

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.index_face_set import IndexFaceSet
      >>> S = IndexFaceSet([[(Integer(1),Integer(0),Integer(0)),(Integer(0),Integer(1),Integer(0)),(Integer(0),Integer(0),Integer(1))], [(Integer(1),Integer(0),Integer(0)),(Integer(0),Integer(1),Integer(0)),(Integer(0),Integer(0),Integer(0))]])
      >>> S.face_list()
      [[(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 0.0)]]
      >>> S.vertex_list()
      [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0), (0.0, 0.0, 0.0)]

      >>> def make_face(n): return [(Integer(0),Integer(0),n),(Integer(0),Integer(1),n),(Integer(1),Integer(1),n),(Integer(1),Integer(0),n)]
      >>> S = IndexFaceSet([make_face(n) for n in range(Integer(10))])
      >>> S.show()

      >>> point_list = [(Integer(1),Integer(0),Integer(0)),(Integer(0),Integer(1),Integer(0))] + [(Integer(0),Integer(0),n) for n in range(Integer(10))]
      >>> face_list = [[Integer(0),Integer(1),n] for n in range(Integer(2),Integer(10))]
      >>> S = IndexFaceSet(face_list, point_list, color='red')
      >>> S.face_list()
      [[(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 0.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 1.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 2.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 3.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 4.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 5.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 6.0)],
       [(1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, 7.0)]]
      >>> S.show()

  A simple example of colored IndexFaceSet (Issue #12212):

  Sage

      sage: from sage.plot.plot3d.index_face_set import IndexFaceSet
      sage: from sage.plot.plot3d.texture import Texture
      sage: point_list = [(2,0,0),(0,2,0),(0,0,2),(0,1,1),(1,0,1),(1,1,0)]
      sage: face_list = [[0,4,5],[3,4,5],[2,3,4],[1,3,5]]
      sage: col = rainbow(10, 'rgbtuple')
      sage: t_list = [Texture(col[i]) for i in range(10)]
      sage: S = IndexFaceSet(face_list, point_list, texture_list=t_list)
      sage: S.show(viewer='tachyon')

  [Python]

      >>> from sage.all import *
      >>> from sage.plot.plot3d.index_face_set import IndexFaceSet
      >>> from sage.plot.plot3d.texture import Texture
      >>> point_list = [(Integer(2),Integer(0),Integer(0)),(Integer(0),Integer(2),Integer(0)),(Integer(0),Integer(0),Integer(2)),(Integer(0),Integer(1),Integer(1)),(Integer(1),Integer(0),Integer(1)),(Integer(1),Integer(1),Integer(0))]
      >>> face_list = [[Integer(0),Integer(4),Integer(5)],[Integer(3),Integer(4),Integer(5)],[Integer(2),Integer(3),Integer(4)],[Integer(1),Integer(3),Integer(5)]]
      >>> col = rainbow(Integer(10), 'rgbtuple')
      >>> t_list = [Texture(col[i]) for i in range(Integer(10))]
      >>> S = IndexFaceSet(face_list, point_list, texture_list=t_list)
      >>> S.show(viewer='tachyon')

  add_condition(condition, N=100, eps=1e-06)

    Cut the surface according to the given condition.

    This allows to take the intersection of the surface with a domain in 3-space, in such a way that the result has a smooth boundary.

    INPUT:

    - `condition` – boolean function on ambient space, that defines the domain

    - `N` – max number of steps used by the bisection method (default: 100) to cut the boundary triangles that are not entirely within the domain.

    - `eps` – target accuracy in the intersection (default: 1.0e-6)

    OUTPUT: an `IndexFaceSet`

    This will contain both triangular and quadrilateral faces.

    EXAMPLES:

    Sage

        sage: var('x,y,z')                                                          # needs sage.symbolic
        (x, y, z)
        sage: P = implicit_plot3d(z-x*y,(-2,2),(-2,2),(-2,2))                       # needs sage.symbolic
        sage: def condi(x, y, z):
        ....:     return bool(x*x+y*y+z*z <= Integer(1))
        sage: R = P.add_condition(condi, 20); R                                     # needs sage.symbolic
        Graphics3d Object

    Python

        >>> from sage.all import *
        >>> var('x,y,z')                                                          # needs sage.symbolic
        (x, y, z)
        >>> P = implicit_plot3d(z-x*y,(-Integer(2),Integer(2)),(-Integer(2),Integer(2)),(-Integer(2),Integer(2)))                       # needs sage.symbolic
        >>> def condi(x, y, z):
        ...     return bool(x*x+y*y+z*z <= Integer(Integer(1)))
        >>> R = P.add_condition(condi, Integer(20)); R                                     # needs sage.symbolic
        Graphics3d Object

    An example with colors:

    Sage

        sage: def condi(x, y, z):
        ....:     return bool(x*x+y*y <= 1.1)
        sage: cm = colormaps.hsv
        sage: cf = lambda x,y,z: float(x+y) % 1
        sage: P = implicit_plot3d(x**2+y**2+z**2-1-x**2*z+y**2*z,                   # needs sage.symbolic
        ....:                     (-2,2),(-2,2),(-2,2),color=(cm,cf))
        sage: R = P.add_condition(condi,40); R                                      # needs sage.symbolic
        Graphics3d Object

    [Python]

        >>> from sage.all import *
        >>> def condi(x, y, z):
        ...     return bool(x*x+y*y <= RealNumber('1.1'))
        >>> cm = colormaps.hsv
        >>> cf = lambda x,y,z: float(x+y) % Integer(1)
        >>> P = implicit_plot3d(x**Integer(2)+y**Integer(2)+z**Integer(2)-Integer(1)-x**Integer(2)*z+y**Integer(2)*z,                   # needs sage.symbolic
        ...                     (-Integer(2),Integer(2)),(-Integer(2),Integer(2)),(-Integer(2),Integer(2)),color=(cm,cf))
        >>> R = P.add_condition(condi,Integer(40)); R                                      # needs sage.symbolic
        Graphics3d Object

    An example with transparency:

    Sage

        sage: P = implicit_plot3d(x**4+y**4+z**2-4, (x,-2,2), (y,-2,2), (z,-2,2),   # needs sage.symbolic
        ....:                     alpha=0.3)
        sage: def cut(a, b, c):
        ....:     return a*a+c*c > 2
        sage: Q = P.add_condition(cut,40); Q                                        # needs sage.symbolic
        Graphics3d Object

    Python

        >>> from sage.all import *
        >>> P = implicit_plot3d(x**Integer(4)+y**Integer(4)+z**Integer(2)-Integer(4), (x,-Integer(2),Integer(2)), (y,-Integer(2),Integer(2)), (z,-Integer(2),Integer(2)),   # needs sage.symbolic
        ...                     alpha=RealNumber('0.3'))
        >>> def cut(a, b, c):
        ...     return a*a+c*c > Integer(2)
        >>> Q = P.add_condition(cut,Integer(40)); Q                                        # needs sage.symbolic
        Graphics3d Object

    A sombrero with quadrilaterals:

    Sage

        sage: P = plot3d(-sin(2*x*x+2*y*y)*exp(-x*x-y*y), (x,-2,2), (y,-2,2),       # needs sage.symbolic
        ....:            color='gold')
        sage: def cut(x, y, z):
        ....:     return x*x+y*y < 1
        sage: Q = P.add_condition(cut);Q                                            # needs sage.symbolic
        Graphics3d Object

    [Python]

        >>> from sage.all import *
        >>> P = plot3d(-sin(Integer(2)*x*x+Integer(2)*y*y)*exp(-x*x-y*y), (x,-Integer(2),Integer(2)), (y,-Integer(2),Integer(2)),       # needs sage.symbolic
        ...            color='gold')
        >>> def cut(x, y, z):
        ...     return x*x+y*y < Integer(1)
        >>> Q = P.add_condition(cut);Q                                            # needs sage.symbolic
        Graphics3d Object

    Todo

    - Use a dichotomy to search for the place where to cut,

    - Compute the cut only once for each edge.

  bounding_box()

    Calculate the bounding box for the vertices in this object (ignoring infinite or NaN coordinates).

    OUTPUT:

    a tuple ( (low_x, low_y, low_z), (high_x, high_y, high_z)), which gives the coordinates of opposite corners of the bounding box.

    EXAMPLES:

    Sage

        sage: x,y = var('x,y')                                                      # needs sage.symbolic
        sage: p = plot3d(sqrt(sin(x)*sin(y)), (x,0,2*pi), (y,0,2*pi))               # needs sage.symbolic
        sage: p.bounding_box()                                                      # needs sage.symbolic
        ((0.0, 0.0, 0.0), (6.283185307179586, 6.283185307179586, 0.9991889981715697))

    Python

        >>> from sage.all import *
        >>> x,y = var('x,y')                                                      # needs sage.symbolic
        >>> p = plot3d(sqrt(sin(x)*sin(y)), (x,Integer(0),Integer(2)*pi), (y,Integer(0),Integer(2)*pi))               # needs sage.symbolic
        >>> p.bounding_box()                                                      # needs sage.symbolic
        ((0.0, 0.0, 0.0), (6.283185307179586, 6.283185307179586, 0.9991889981715697))

  dual(**kwds)

    Return the dual.

    EXAMPLES:

    Sage

        sage: S = cube()
        sage: T = S.dual()
        sage: len(T.vertex_list())
        6

    Python

        >>> from sage.all import *
        >>> S = cube()
        >>> T = S.dual()
        >>> len(T.vertex_list())
        6

  edge_list()

    Return the list of edges.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import *
        sage: S = Box(1,2,3)
        sage: S.edge_list()[0]
        ((1.0, -2.0, 3.0), (1.0, 2.0, 3.0))

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import *
        >>> S = Box(Integer(1),Integer(2),Integer(3))
        >>> S.edge_list()[Integer(0)]
        ((1.0, -2.0, 3.0), (1.0, 2.0, 3.0))

  edges()

    An iterator over the edges.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import *
        sage: S = Box(1,2,3)
        sage: list(S.edges())[0]
        ((1.0, -2.0, 3.0), (1.0, 2.0, 3.0))

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import *
        >>> S = Box(Integer(1),Integer(2),Integer(3))
        >>> list(S.edges())[Integer(0)]
        ((1.0, -2.0, 3.0), (1.0, 2.0, 3.0))

  face_list(render_params=None)

    Return the list of faces.

    Every face is given as a tuple of vertices.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import *
        sage: S = Box(1,2,3)
        sage: S.face_list(S.default_render_params())[0]
        [(1.0, 2.0, 3.0), (-1.0, 2.0, 3.0), (-1.0, -2.0, 3.0), (1.0, -2.0, 3.0)]

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import *
        >>> S = Box(Integer(1),Integer(2),Integer(3))
        >>> S.face_list(S.default_render_params())[Integer(0)]
        [(1.0, 2.0, 3.0), (-1.0, 2.0, 3.0), (-1.0, -2.0, 3.0), (1.0, -2.0, 3.0)]

  faces()

    An iterator over the faces.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import *
        sage: S = Box(1,2,3)
        sage: list(S.faces()) == S.face_list()
        True

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import *
        >>> S = Box(Integer(1),Integer(2),Integer(3))
        >>> list(S.faces()) == S.face_list()
        True

  has_local_colors()

    Return `True` if and only if every face has an individual color.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.index_face_set import IndexFaceSet
        sage: from sage.plot.plot3d.texture import Texture
        sage: point_list = [(2,0,0),(0,2,0),(0,0,2),(0,1,1),(1,0,1),(1,1,0)]
        sage: face_list = [[0,4,5],[3,4,5],[2,3,4],[1,3,5]]
        sage: col = rainbow(10, 'rgbtuple')
        sage: t_list=[Texture(col[i]) for i in range(10)]
        sage: S = IndexFaceSet(face_list, point_list, texture_list=t_list)
        sage: S.has_local_colors()
        True

        sage: from sage.plot.plot3d.shapes import *
        sage: S = Box(1,2,3)
        sage: S.has_local_colors()
        False

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.index_face_set import IndexFaceSet
        >>> from sage.plot.plot3d.texture import Texture
        >>> point_list = [(Integer(2),Integer(0),Integer(0)),(Integer(0),Integer(2),Integer(0)),(Integer(0),Integer(0),Integer(2)),(Integer(0),Integer(1),Integer(1)),(Integer(1),Integer(0),Integer(1)),(Integer(1),Integer(1),Integer(0))]
        >>> face_list = [[Integer(0),Integer(4),Integer(5)],[Integer(3),Integer(4),Integer(5)],[Integer(2),Integer(3),Integer(4)],[Integer(1),Integer(3),Integer(5)]]
        >>> col = rainbow(Integer(10), 'rgbtuple')
        >>> t_list=[Texture(col[i]) for i in range(Integer(10))]
        >>> S = IndexFaceSet(face_list, point_list, texture_list=t_list)
        >>> S.has_local_colors()
        True

        >>> from sage.plot.plot3d.shapes import *
        >>> S = Box(Integer(1),Integer(2),Integer(3))
        >>> S.has_local_colors()
        False

  index_faces()

    Return the list over all faces of the indices of the vertices.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import *
        sage: S = Box(1,2,3)
        sage: S.index_faces()
        [[0, 1, 2, 3],
         [0, 4, 5, 1],
         [0, 3, 6, 4],
         [5, 4, 6, 7],
         [6, 3, 2, 7],
         [2, 1, 5, 7]]

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import *
        >>> S = Box(Integer(1),Integer(2),Integer(3))
        >>> S.index_faces()
        [[0, 1, 2, 3],
         [0, 4, 5, 1],
         [0, 3, 6, 4],
         [5, 4, 6, 7],
         [6, 3, 2, 7],
         [2, 1, 5, 7]]

  index_faces_with_colors()

    Return the list over all faces of (indices of the vertices, color).

    This only works if every face has its own color.

    See also

    `has_local_colors()`

    EXAMPLES:

    A simple colored one:

    Sage

        sage: from sage.plot.plot3d.index_face_set import IndexFaceSet
        sage: from sage.plot.plot3d.texture import Texture
        sage: point_list = [(2,0,0),(0,2,0),(0,0,2),(0,1,1),(1,0,1),(1,1,0)]
        sage: face_list = [[0,4,5],[3,4,5],[2,3,4],[1,3,5]]
        sage: col = rainbow(10, 'rgbtuple')
        sage: t_list = [Texture(col[i]) for i in range(10)]
        sage: S = IndexFaceSet(face_list, point_list, texture_list=t_list)
        sage: S.index_faces_with_colors()
        [([0, 4, 5], '#ff0000'),
         ([3, 4, 5], '#ff9900'),
         ([2, 3, 4], '#cbff00'),
         ([1, 3, 5], '#33ff00')]

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.index_face_set import IndexFaceSet
        >>> from sage.plot.plot3d.texture import Texture
        >>> point_list = [(Integer(2),Integer(0),Integer(0)),(Integer(0),Integer(2),Integer(0)),(Integer(0),Integer(0),Integer(2)),(Integer(0),Integer(1),Integer(1)),(Integer(1),Integer(0),Integer(1)),(Integer(1),Integer(1),Integer(0))]
        >>> face_list = [[Integer(0),Integer(4),Integer(5)],[Integer(3),Integer(4),Integer(5)],[Integer(2),Integer(3),Integer(4)],[Integer(1),Integer(3),Integer(5)]]
        >>> col = rainbow(Integer(10), 'rgbtuple')
        >>> t_list = [Texture(col[i]) for i in range(Integer(10))]
        >>> S = IndexFaceSet(face_list, point_list, texture_list=t_list)
        >>> S.index_faces_with_colors()
        [([0, 4, 5], '#ff0000'),
         ([3, 4, 5], '#ff9900'),
         ([2, 3, 4], '#cbff00'),
         ([1, 3, 5], '#33ff00')]

    When the texture is global, an error is raised:

    Sage

        sage: from sage.plot.plot3d.shapes import *
        sage: S = Box(1,2,3)
        sage: S.index_faces_with_colors()
        Traceback (most recent call last):
        ...
        ValueError: the texture is global

    [Python]

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import *
        >>> S = Box(Integer(1),Integer(2),Integer(3))
        >>> S.index_faces_with_colors()
        Traceback (most recent call last):
        ...
        ValueError: the texture is global

  is_enclosed()

    Whether or not it is necessary to render the back sides of the polygons.

    One is assuming, of course, that they have the correct orientation.

    This is may be passed in on construction. It is also calculated in `sage.plot.plot3d.parametric_surface.ParametricSurface` by verifying the opposite edges of the rendered domain either line up or are pinched together.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.index_face_set import IndexFaceSet
        sage: IndexFaceSet([[(0,0,1),(0,1,0),(1,0,0)]]).is_enclosed()
        False

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.index_face_set import IndexFaceSet
        >>> IndexFaceSet([[(Integer(0),Integer(0),Integer(1)),(Integer(0),Integer(1),Integer(0)),(Integer(1),Integer(0),Integer(0))]]).is_enclosed()
        False

  jmol_repr(render_params)

    Return a jmol representation for `self`.

  json_repr(render_params)

    Return a json representation for `self`.

  obj_repr(render_params)

    Return an obj representation for `self`.

  partition(f)

    Partition the faces of `self`.

    The partition is done according to the value of a map \(f: \RR^3 \rightarrow \ZZ\) applied to the center of each face.

    INPUT:

    - `f` – a function from \(\RR^3\) to \(\ZZ\)

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import *
        sage: S = Box(1,2,3)
        sage: len(S.partition(lambda x,y,z: floor(x+y+z)))
        6

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import *
        >>> S = Box(Integer(1),Integer(2),Integer(3))
        >>> len(S.partition(lambda x,y,z: floor(x+y+z)))
        6

  sticker(face_list, width, hover, **kwds)

    Return a sticker on the chosen faces.

  stickers(colors, width, hover)

    Return a group of IndexFaceSets.

    INPUT:

    - `colors` – list of colors/textures to use (in cyclic order)

    - `width` – offset perpendicular into the edge (to create a border) may also be negative

    - `hover` – offset normal to the face (usually have to float above the original surface so it shows, typically this value is very small compared to the actual object

    OUTPUT: Graphics3dGroup of stickers

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Box
        sage: B = Box(.5,.4,.3, color='black')
        sage: S = B.stickers(['red','yellow','blue'], 0.1, 0.05)
        sage: S.show()
        sage: (S+B).show()

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Box
        >>> B = Box(RealNumber('.5'),RealNumber('.4'),RealNumber('.3'), color='black')
        >>> S = B.stickers(['red','yellow','blue'], RealNumber('0.1'), RealNumber('0.05'))
        >>> S.show()
        >>> (S+B).show()

  stl_binary_repr(render_params)

    Return data for STL (STereoLithography) representation of the surface.

    The STL binary representation is a list of binary strings, one for each triangle.

    EXAMPLES:

    Sage

        sage: G = sphere()
        sage: data = G.stl_binary_repr(G.default_render_params()); len(data)
        1368

    Python

        >>> from sage.all import *
        >>> G = sphere()
        >>> data = G.stl_binary_repr(G.default_render_params()); len(data)
        1368

  tachyon_repr(render_params)

    Return a tachyon object for `self`.

    EXAMPLES:

    A basic test with a triangle:

    Sage

        sage: G = polygon([(0,0,1), (1,1,1), (2,0,1)])
        sage: s = G.tachyon_repr(G.default_render_params()); s
        ['TRI V0 0 0 1 V1 1 1 1 V2 2 0 1', ...]

    Python

        >>> from sage.all import *
        >>> G = polygon([(Integer(0),Integer(0),Integer(1)), (Integer(1),Integer(1),Integer(1)), (Integer(2),Integer(0),Integer(1))])
        >>> s = G.tachyon_repr(G.default_render_params()); s
        ['TRI V0 0 0 1 V1 1 1 1 V2 2 0 1', ...]

    A simple colored one:

    Sage

        sage: from sage.plot.plot3d.index_face_set import IndexFaceSet
        sage: from sage.plot.plot3d.texture import Texture
        sage: point_list = [(2,0,0),(0,2,0),(0,0,2),(0,1,1),(1,0,1),(1,1,0)]
        sage: face_list = [[0,4,5],[3,4,5],[2,3,4],[1,3,5]]
        sage: col = rainbow(10, 'rgbtuple')
        sage: t_list = [Texture(col[i]) for i in range(10)]
        sage: S = IndexFaceSet(face_list, point_list, texture_list=t_list)
        sage: S.tachyon_repr(S.default_render_params())
        ['TRI V0 2 0 0 V1 1 0 1 V2 1 1 0',
        'TEXTURE... AMBIENT 0.3 DIFFUSE 0.7 SPECULAR 0 OPACITY 1.0... COLOR 1 0 0 ... TEXFUNC 0',...]

    [Python]

        >>> from sage.all import *
        >>> from sage.plot.plot3d.index_face_set import IndexFaceSet
        >>> from sage.plot.plot3d.texture import Texture
        >>> point_list = [(Integer(2),Integer(0),Integer(0)),(Integer(0),Integer(2),Integer(0)),(Integer(0),Integer(0),Integer(2)),(Integer(0),Integer(1),Integer(1)),(Integer(1),Integer(0),Integer(1)),(Integer(1),Integer(1),Integer(0))]
        >>> face_list = [[Integer(0),Integer(4),Integer(5)],[Integer(3),Integer(4),Integer(5)],[Integer(2),Integer(3),Integer(4)],[Integer(1),Integer(3),Integer(5)]]
        >>> col = rainbow(Integer(10), 'rgbtuple')
        >>> t_list = [Texture(col[i]) for i in range(Integer(10))]
        >>> S = IndexFaceSet(face_list, point_list, texture_list=t_list)
        >>> S.tachyon_repr(S.default_render_params())
        ['TRI V0 2 0 0 V1 1 0 1 V2 1 1 0',
        'TEXTURE... AMBIENT 0.3 DIFFUSE 0.7 SPECULAR 0 OPACITY 1.0... COLOR 1 0 0 ... TEXFUNC 0',...]

  threejs_repr(render_params)

    Return representation of the surface suitable for plotting with three.js.

    EXAMPLES:

    A simple triangle:

    Sage

        sage: G = polygon([(0,0,1), (1,1,1), (2,0,1)])
        sage: G.threejs_repr(G.default_render_params())
        [('surface',
          {'color': '#0000ff',
           'faces': [[0, 1, 2]],
           'opacity': 1.0,
           'vertices': [{'x': 0.0, 'y': 0.0, 'z': 1.0},
            {'x': 1.0, 'y': 1.0, 'z': 1.0},
            {'x': 2.0, 'y': 0.0, 'z': 1.0}]})]

    Python

        >>> from sage.all import *
        >>> G = polygon([(Integer(0),Integer(0),Integer(1)), (Integer(1),Integer(1),Integer(1)), (Integer(2),Integer(0),Integer(1))])
        >>> G.threejs_repr(G.default_render_params())
        [('surface',
          {'color': '#0000ff',
           'faces': [[0, 1, 2]],
           'opacity': 1.0,
           'vertices': [{'x': 0.0, 'y': 0.0, 'z': 1.0},
            {'x': 1.0, 'y': 1.0, 'z': 1.0},
            {'x': 2.0, 'y': 0.0, 'z': 1.0}]})]

    The same but with more options applied:

    Sage

        sage: G = polygon([(0,0,1), (1,1,1), (2,0,1)], color='red', opacity=0.5,
        ....:             render_order=2, threejs_flat_shading=True,
        ....:             single_side=True, mesh=True, thickness=10, depth_write=True)
        sage: G.threejs_repr(G.default_render_params())
        [('surface',
          {'color': '#ff0000',
           'depthWrite': True,
           'faces': [[0, 1, 2]],
           'linewidth': 10.0,
           'opacity': 0.5,
           'renderOrder': 2.0,
           'showMeshGrid': True,
           'singleSide': True,
           'useFlatShading': True,
           'vertices': [{'x': 0.0, 'y': 0.0, 'z': 1.0},
            {'x': 1.0, 'y': 1.0, 'z': 1.0},
            {'x': 2.0, 'y': 0.0, 'z': 1.0}]})]

    [Python]

        >>> from sage.all import *
        >>> G = polygon([(Integer(0),Integer(0),Integer(1)), (Integer(1),Integer(1),Integer(1)), (Integer(2),Integer(0),Integer(1))], color='red', opacity=RealNumber('0.5'),
        ...             render_order=Integer(2), threejs_flat_shading=True,
        ...             single_side=True, mesh=True, thickness=Integer(10), depth_write=True)
        >>> G.threejs_repr(G.default_render_params())
        [('surface',
          {'color': '#ff0000',
           'depthWrite': True,
           'faces': [[0, 1, 2]],
           'linewidth': 10.0,
           'opacity': 0.5,
           'renderOrder': 2.0,
           'showMeshGrid': True,
           'singleSide': True,
           'useFlatShading': True,
           'vertices': [{'x': 0.0, 'y': 0.0, 'z': 1.0},
            {'x': 1.0, 'y': 1.0, 'z': 1.0},
            {'x': 2.0, 'y': 0.0, 'z': 1.0}]})]

  vertex_list()

    Return the list of vertices.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import *
        sage: S = polygon([(0,0,1), (1,1,1), (2,0,1)])
        sage: S.vertex_list()[0]
        (0.0, 0.0, 1.0)

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import *
        >>> S = polygon([(Integer(0),Integer(0),Integer(1)), (Integer(1),Integer(1),Integer(1)), (Integer(2),Integer(0),Integer(1))])
        >>> S.vertex_list()[Integer(0)]
        (0.0, 0.0, 1.0)

  vertices()

    An iterator over the vertices.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import *
        sage: S = Cone(1,1)
        sage: list(S.vertices()) == S.vertex_list()
        True

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import *
        >>> S = Cone(Integer(1),Integer(1))
        >>> list(S.vertices()) == S.vertex_list()
        True

  x3d_geometry()

    Return the x3d data.

    EXAMPLES:

    A basic test with a triangle:

    Sage

        sage: G = polygon([(0,0,1), (1,1,1), (2,0,1)])
        sage: print(G.x3d_geometry())

        <IndexedFaceSet coordIndex='0,1,2,-1'>
          <Coordinate point='0.0 0.0 1.0,1.0 1.0 1.0,2.0 0.0 1.0'/>
        </IndexedFaceSet>

    Python

        >>> from sage.all import *
        >>> G = polygon([(Integer(0),Integer(0),Integer(1)), (Integer(1),Integer(1),Integer(1)), (Integer(2),Integer(0),Integer(1))])
        >>> print(G.x3d_geometry())
        <BLANKLINE>
        <IndexedFaceSet coordIndex='0,1,2,-1'>
          <Coordinate point='0.0 0.0 1.0,1.0 1.0 1.0,2.0 0.0 1.0'/>
        </IndexedFaceSet>
        <BLANKLINE>

    A simple colored one:

    Sage

        sage: from sage.plot.plot3d.index_face_set import IndexFaceSet
        sage: from sage.plot.plot3d.texture import Texture
        sage: point_list = [(2,0,0),(0,2,0),(0,0,2),(0,1,1),(1,0,1),(1,1,0)]
        sage: face_list = [[0,4,5],[3,4,5],[2,3,4],[1,3,5]]
        sage: col = rainbow(10, 'rgbtuple')
        sage: t_list = [Texture(col[i]) for i in range(10)]
        sage: S = IndexFaceSet(face_list, point_list, texture_list=t_list)
        sage: print(S.x3d_geometry())

        <IndexedFaceSet solid='False' colorPerVertex='False' coordIndex='0,4,5,-1,3,4,5,-1,2,3,4,-1,1,3,5,-1'>
          <Coordinate point='2.0 0.0 0.0,0.0 2.0 0.0,0.0 0.0 2.0,0.0 1.0 1.0,1.0 0.0 1.0,1.0 1.0 0.0'/>
          <Color color='1.0 0.0 0.0,1.0 0.6000000000000001 0.0,0.7999999999999998 1.0 0.0,0.20000000000000018 1.0 0.0' />
        </IndexedFaceSet>

    [Python]

        >>> from sage.all import *
        >>> from sage.plot.plot3d.index_face_set import IndexFaceSet
        >>> from sage.plot.plot3d.texture import Texture
        >>> point_list = [(Integer(2),Integer(0),Integer(0)),(Integer(0),Integer(2),Integer(0)),(Integer(0),Integer(0),Integer(2)),(Integer(0),Integer(1),Integer(1)),(Integer(1),Integer(0),Integer(1)),(Integer(1),Integer(1),Integer(0))]
        >>> face_list = [[Integer(0),Integer(4),Integer(5)],[Integer(3),Integer(4),Integer(5)],[Integer(2),Integer(3),Integer(4)],[Integer(1),Integer(3),Integer(5)]]
        >>> col = rainbow(Integer(10), 'rgbtuple')
        >>> t_list = [Texture(col[i]) for i in range(Integer(10))]
        >>> S = IndexFaceSet(face_list, point_list, texture_list=t_list)
        >>> print(S.x3d_geometry())
        <BLANKLINE>
        <IndexedFaceSet solid='False' colorPerVertex='False' coordIndex='0,4,5,-1,3,4,5,-1,2,3,4,-1,1,3,5,-1'>
          <Coordinate point='2.0 0.0 0.0,0.0 2.0 0.0,0.0 0.0 2.0,0.0 1.0 1.0,1.0 0.0 1.0,1.0 1.0 0.0'/>
          <Color color='1.0 0.0 0.0,1.0 0.6000000000000001 0.0,0.7999999999999998 1.0 0.0,0.20000000000000018 1.0 0.0' />
        </IndexedFaceSet>
        <BLANKLINE>

class sage.plot.plot3d.index_face_set.VertexIter

  Bases: `object`

  A class for iteration over vertices

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.shapes import *
      sage: S = Box(1,2,3)
      sage: len(list(S.vertices())) == 8   # indirect doctest
      True

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.shapes import *
      >>> S = Box(Integer(1),Integer(2),Integer(3))
      >>> len(list(S.vertices())) == Integer(8)   # indirect doctest
      True

sage.plot.plot3d.index_face_set.cut_edge_by_bisection(pointa, pointb, condition, eps=1e-06, N=100)

  Cut an intersecting edge using the bisection method.

  Given two points (pointa and pointb) and a condition (boolean function), this calculates the position at the edge (defined by both points) where the boolean condition switches its value.

  INPUT:

  - `pointa`, `pointb` – two points in 3-dimensional space

  - `N` – max number of steps in the bisection method (default: 100) to cut the boundary triangles that are not entirely within the domain.

  - `eps` – target accuracy in the intersection (default: 1.0e-6)

  OUTPUT:

  intersection of the edge defined by `pointa` and `pointb`, and `condition`.

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.index_face_set import cut_edge_by_bisection
      sage: cut_edge_by_bisection((0.0,0.0,0.0), (1.0,1.0,0.0),
      ....:                       lambda x,y,z: x**2+y**2+z**2 < 1, eps=1.0E-12)
      (0.7071067811864395, 0.7071067811864395, 0.0)

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.index_face_set import cut_edge_by_bisection
      >>> cut_edge_by_bisection((RealNumber('0.0'),RealNumber('0.0'),RealNumber('0.0')), (RealNumber('1.0'),RealNumber('1.0'),RealNumber('0.0')),
      ...                       lambda x,y,z: x**Integer(2)+y**Integer(2)+z**Integer(2) < Integer(1), eps=RealNumber('1.0E-12'))
      (0.7071067811864395, 0.7071067811864395, 0.0)

sage.plot.plot3d.index_face_set.midpoint(pointa, pointb, w)

  Return the weighted mean of two points in 3-space.

  INPUT:

  - `pointa`, `pointb` – two points in 3-dimensional space

  - `w` – a real weight between 0 and 1

  If the weight is zero, the result is `pointb`. If the weight is one, the result is `pointa`.

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.index_face_set import midpoint
      sage: midpoint((1,2,3),(4,4,4),0.8)
      (1.60000000000000, 2.40000000000000, 3.20000000000000)

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.index_face_set import midpoint
      >>> midpoint((Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(4),Integer(4)),RealNumber('0.8'))
      (1.60000000000000, 2.40000000000000, 3.20000000000000)

sage.plot.plot3d.index_face_set.sticker(face, width, hover)

  Return a sticker over the given face.