Skip to content
Snippets Groups Projects
primitives.py 70.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • # ##### BEGIN GPL LICENSE BLOCK #####
    #
    #  This program is free software; you can redistribute it and/or
    #  modify it under the terms of the GNU General Public License
    #  as published by the Free Software Foundation; either version 2
    #  of the License, or (at your option) any later version.
    #
    #  This program is distributed in the hope that it will be useful,
    #  but WITHOUT ANY WARRANTY; without even the implied warranty of
    #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    #  GNU General Public License for more details.
    #
    #  You should have received a copy of the GNU General Public License
    #  along with this program; if not, write to the Free Software Foundation,
    #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    #
    # ##### END GPL LICENSE BLOCK #####
    
    # <pep8 compliant>
    
    
    ############ To get POV-Ray specific objects In and Out of Blender ###########
    
    import bpy
    
    import os.path
    
    from bpy_extras.io_utils import ImportHelper
    from bpy_extras import object_utils
    from math import atan, pi, degrees, sqrt, cos, sin
    
    
    from bpy.props import (
            StringProperty,
            BoolProperty,
            IntProperty,
            FloatProperty,
            FloatVectorProperty,
            EnumProperty,
            PointerProperty,
            CollectionProperty,
            )
    
    
    
    def pov_define_mesh(mesh, verts, edges, faces, name, hide_geometry=True):
        if mesh is None:
            mesh = bpy.data.meshes.new(name)
        mesh.from_pydata(verts, edges, faces)
        mesh.update()
        mesh.validate(False)  # Set it to True to see debug messages (helps ensure you generate valid geometry).
        if hide_geometry:
            mesh.vertices.foreach_set("hide", [True] * len(mesh.vertices))
            mesh.edges.foreach_set("hide", [True] * len(mesh.edges))
            mesh.polygons.foreach_set("hide", [True] * len(mesh.polygons))
        return mesh
    
    
    class POVRAY_OT_lathe_add(bpy.types.Operator):
        bl_idname = "pov.addlathe"
        bl_label = "Lathe"
        bl_options = {'REGISTER','UNDO'}
        bl_description = "adds lathe"
    
    
        def execute(self, context):
            layers=[False]*20
            layers[0]=True
            bpy.ops.curve.primitive_bezier_curve_add(location=(0, 0, 0),
                rotation=(0, 0, 0), layers=layers)
            ob=context.scene.objects.active
            ob.name = ob.data.name = "PovLathe"
    
            ob.pov.object_as='LATHE'
    
            self.report({'INFO'}, "This native POV-Ray primitive "
    
                                     "won't have any vertex to show in edit mode")
            bpy.ops.transform.rotate(value=-pi/2, axis=(0, 0, 1))
            bpy.ops.object.mode_set(mode='OBJECT')
            ob.pov.curveshape = "lathe"
            bpy.ops.object.modifier_add(type='SCREW')
            bpy.context.object.modifiers["Screw"].axis = 'Y'
            bpy.context.object.modifiers["Screw"].show_render = False
            return {'FINISHED'}
    
    
    
    def pov_superellipsoid_define(context, op, ob):
    
            if op:
                mesh = None
    
                u = op.se_u
                v = op.se_v
                n1 = op.se_n1
                n2 = op.se_n2
                edit = op.se_edit
                se_param1 = n2 # op.se_param1
                se_param2 = n1 # op.se_param2
    
            else:
                assert(ob)
                mesh = ob.data
    
                u = ob.pov.se_u
                v = ob.pov.se_v
                n1 = ob.pov.se_n1
                n2 = ob.pov.se_n2
                edit = ob.pov.se_edit
                se_param1 = ob.pov.se_param1
                se_param2 = ob.pov.se_param2
    
            stepSegment=360/v*pi/180
            stepRing=pi/u
            angSegment=0
            angRing=-pi/2
    
            step=0
            for ring in range(0,u-1):
                angRing += stepRing
                for segment in range(0,v):
                    step += 1
                    angSegment += stepSegment
                    x = r*(abs(cos(angRing))**n1)*(abs(cos(angSegment))**n2)
                    if (cos(angRing) < 0 and cos(angSegment) > 0) or \
                            (cos(angRing) > 0 and cos(angSegment) < 0):
                        x = -x
                    y = r*(abs(cos(angRing))**n1)*(abs(sin(angSegment))**n2)
                    if (cos(angRing) < 0 and sin(angSegment) > 0) or \
                            (cos(angRing) > 0 and sin(angSegment) < 0):
                        y = -y
                    z = r*(abs(sin(angRing))**n1)
                    if sin(angRing) < 0:
                        z = -z
                    x = round(x,4)
                    y = round(y,4)
                    z = round(z,4)
                    verts.append((x,y,z))
            if edit == 'TRIANGLES':
                verts.append((0,0,1))
                verts.append((0,0,-1))
    
            for i in range(0,u-2):
                m=i*v
                for p in range(0,v):
                    if p < v-1:
                        face=(m+p,1+m+p,v+1+m+p,v+m+p)
                    if p == v-1:
                        face=(m+p,m,v+m,v+m+p)
                    faces.append(face)
            if edit == 'TRIANGLES':
                indexUp=len(verts)-2
                indexDown=len(verts)-1
                indexStartDown=len(verts)-2-v
                for i in range(0,v):
                    if i < v-1:
                        face=(indexDown,i,i+1)
                        faces.append(face)
                    if i == v-1:
                        face=(indexDown,i,0)
                        faces.append(face)
                for i in range(0,v):
                    if i < v-1:
                        face=(indexUp,i+indexStartDown,i+indexStartDown+1)
                        faces.append(face)
                    if i == v-1:
                        face=(indexUp,i+indexStartDown,indexStartDown)
                        faces.append(face)
            if edit == 'NGONS':
                face=[]
                for i in range(0,v):
                    face.append(i)
                faces.append(face)
                face=[]
                indexUp=len(verts)-1
                for i in range(0,v):
                    face.append(indexUp-i)
                faces.append(face)
            mesh = pov_define_mesh(mesh, verts, [], faces, "SuperEllipsoid")
    
            if not ob:
                ob_base = object_utils.object_data_add(context, mesh, operator=None)
                ob = ob_base.object
                #engine = context.scene.render.engine what for?
                ob = context.object
                ob.name =  ob.data.name = "PovSuperellipsoid"
                ob.pov.object_as = 'SUPERELLIPSOID'
                ob.pov.se_param1 = n2
                ob.pov.se_param2 = n1
    
                ob.pov.se_n1 = n1
    
                ob.pov.se_edit = edit
    
    
                bpy.ops.object.mode_set(mode="EDIT")
                bpy.ops.mesh.hide(unselected=False)
                bpy.ops.object.mode_set(mode="OBJECT")
    
    class POVRAY_OT_superellipsoid_add(bpy.types.Operator):
        bl_idname = "pov.addsuperellipsoid"
        bl_label = "Add SuperEllipsoid"
        bl_description = "Create a SuperEllipsoid"
        bl_options = {'REGISTER', 'UNDO'}
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
        # XXX Keep it in sync with __init__'s RenderPovSettingsConePrimitive
        #     If someone knows how to define operators' props from a func, I'd be delighted to learn it!
        se_param1 = FloatProperty(
                name="Parameter 1",
                description="",
                min=0.00, max=10.0, default=0.04)
    
        se_param2 = FloatProperty(
                name="Parameter 2",
                description="",
                min=0.00, max=10.0, default=0.04)
    
        se_u = IntProperty(name = "U-segments",
                        description = "radial segmentation",
                        default = 20, min = 4, max = 265)
        se_v = IntProperty(name = "V-segments",
                        description = "lateral segmentation",
                        default = 20, min = 4, max = 265)
        se_n1 = FloatProperty(name = "Ring manipulator",
                          description = "Manipulates the shape of the Ring",
                          default = 1.0, min = 0.01, max = 100.0)
        se_n2 = FloatProperty(name = "Cross manipulator",
                          description = "Manipulates the shape of the cross-section",
                          default = 1.0, min = 0.01, max = 100.0)
        se_edit = EnumProperty(items=[("NOTHING", "Nothing", ""),
                                    ("NGONS", "N-Gons", ""),
                                    ("TRIANGLES", "Triangles", "")],
                            name="Fill up and down",
                            description="",
                            default='TRIANGLES')
    
        @classmethod
        def poll(cls, context):
            engine = context.scene.render.engine
            return (engine in cls.COMPAT_ENGINES)
    
        def execute(self,context):
            pov_superellipsoid_define(context, self, None)
    
    
            self.report({'INFO'}, "This native POV-Ray primitive won't have any vertex to show in edit mode")
    
    
            return {'FINISHED'}
    
    class POVRAY_OT_superellipsoid_update(bpy.types.Operator):
        bl_idname = "pov.superellipsoid_update"
        bl_label = "Update"
        bl_description = "Update Superellipsoid"
        bl_options = {'REGISTER', 'UNDO'}
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
        @classmethod
        def poll(cls, context):
            engine = context.scene.render.engine
            ob = context.object
            return (ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES)
    
        def execute(self, context):
            bpy.ops.object.mode_set(mode="EDIT")
            bpy.ops.mesh.reveal()
            bpy.ops.mesh.select_all(action='SELECT')
            bpy.ops.mesh.delete(type='VERT')
            bpy.ops.object.mode_set(mode="OBJECT")
    
            pov_superellipsoid_define(context, None, context.object)
    
            return {'FINISHED'}
    
    def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False):
        faces = []
        if not vertIdx1 or not vertIdx2:
            return None
        if len(vertIdx1) < 2 and len(vertIdx2) < 2:
            return None
        fan = False
        if (len(vertIdx1) != len(vertIdx2)):
            if (len(vertIdx1) == 1 and len(vertIdx2) > 1):
                fan = True
            else:
                return None
        total = len(vertIdx2)
        if closed:
            if flipped:
                face = [
                    vertIdx1[0],
                    vertIdx2[0],
                    vertIdx2[total - 1]]
                if not fan:
                    face.append(vertIdx1[total - 1])
                faces.append(face)
    
            else:
                face = [vertIdx2[0], vertIdx1[0]]
                if not fan:
                    face.append(vertIdx1[total - 1])
                face.append(vertIdx2[total - 1])
                faces.append(face)
        for num in range(total - 1):
            if flipped:
                if fan:
                    face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]]
                else:
                    face = [vertIdx2[num], vertIdx1[num],
                        vertIdx1[num + 1], vertIdx2[num + 1]]
                faces.append(face)
            else:
                if fan:
                    face = [vertIdx1[0], vertIdx2[num], vertIdx2[num + 1]]
                else:
                    face = [vertIdx1[num], vertIdx2[num],
                        vertIdx2[num + 1], vertIdx1[num + 1]]
                faces.append(face)
    
        return faces
    
    def power(a,b):
        if a < 0:
            return -((-a)**b)
        return a**b
    
    def supertoroid(R,r,u,v,n1,n2):
        a = 2*pi/u
        b = 2*pi/v
        verts = []
        faces = []
        for i in range(u):
            s = power(sin(i*a),n1)
            c = power(cos(i*a),n1)
            for j in range(v):
                c2 = R+r*power(cos(j*b),n2)
                s2 = r*power(sin(j*b),n2)
                verts.append((c*c2,s*c2,s2))# type as a (mathutils.Vector(c*c2,s*c2,s2))?
            if i > 0:
                f = createFaces(range((i-1)*v,i*v),range(i*v,(i+1)*v),closed = True)
                faces.extend(f)
        f = createFaces(range((u-1)*v,u*v),range(v),closed=True)
        faces.extend(f)
        return verts, faces
    
    
    def pov_supertorus_define(context, op, ob):
    
            if op:
                mesh = None
                st_R = op.st_R
                st_r = op.st_r
                st_u = op.st_u
                st_v = op.st_v
                st_n1 = op.st_n1
                st_n2 = op.st_n2
                st_ie = op.st_ie
                st_edit = op.st_edit
    
            else:
                assert(ob)
                mesh = ob.data
                st_R = ob.pov.st_major_radius
                st_r = ob.pov.st_minor_radius
                st_u = ob.pov.st_u
                st_v = ob.pov.st_v
                st_n1 = ob.pov.st_ring
                st_n2 = ob.pov.st_cross
                st_ie = ob.pov.st_ie
                st_edit = ob.pov.st_edit
    
            if st_ie:
                rad1 = (st_R+st_r)/2
                rad2 = (st_R-st_r)/2
                if rad2 > rad1:
                    [rad1,rad2] = [rad2,rad1]
            else:
                rad1 = st_R
                rad2 = st_r
                if rad2 > rad1:
                    rad1 = rad2
            verts,faces = supertoroid(rad1,
                                      rad2,
                                      st_u,
                                      st_v,
                                      st_n1,
                                      st_n2)
            mesh = pov_define_mesh(mesh, verts, [], faces, "PovSuperTorus", True)
            if not ob:
                ob_base = object_utils.object_data_add(context, mesh, operator=None)
    
                ob = ob_base.object
                ob.pov.object_as = 'SUPERTORUS'
                ob.pov.st_major_radius = st_R
                ob.pov.st_minor_radius = st_r
                ob.pov.st_u = st_u
                ob.pov.st_v = st_v
                ob.pov.st_ring = st_n1
                ob.pov.st_cross = st_n2
                ob.pov.st_ie = st_ie
                ob.pov.st_edit = st_edit
    
    class POVRAY_OT_supertorus_add(bpy.types.Operator):
        bl_idname = "pov.addsupertorus"
        bl_label = "Add Supertorus"
        bl_description = "Create a SuperTorus"
        bl_options = {'REGISTER', 'UNDO'}
    
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
    
        st_R = FloatProperty(name = "big radius",
                          description = "The radius inside the tube",
                          default = 1.0, min = 0.01, max = 100.0)
        st_r = FloatProperty(name = "small radius",
                          description = "The radius of the tube",
                          default = 0.3, min = 0.01, max = 100.0)
        st_u = IntProperty(name = "U-segments",
                        description = "radial segmentation",
                        default = 16, min = 3, max = 265)
        st_v = IntProperty(name = "V-segments",
                        description = "lateral segmentation",
                        default = 8, min = 3, max = 265)
        st_n1 = FloatProperty(name = "Ring manipulator",
                          description = "Manipulates the shape of the Ring",
                          default = 1.0, min = 0.01, max = 100.0)
        st_n2 = FloatProperty(name = "Cross manipulator",
                          description = "Manipulates the shape of the cross-section",
                          default = 1.0, min = 0.01, max = 100.0)
        st_ie = BoolProperty(name = "Use Int.+Ext. radii",
                          description = "Use internal and external radii",
                          default = False)
        st_edit = BoolProperty(name="",
                            description="",
                            default=False,
    
                            options={'HIDDEN'})
    
    
        @classmethod
        def poll(cls, context):
            engine = context.scene.render.engine
            return (engine in cls.COMPAT_ENGINES)
    
        def execute(self, context):
            pov_supertorus_define(context, self, None)
    
    
            self.report({'INFO'}, "This native POV-Ray primitive won't have any vertex to show in edit mode")
            return {'FINISHED'}
    
    
    class POVRAY_OT_supertorus_update(bpy.types.Operator):
        bl_idname = "pov.supertorus_update"
        bl_label = "Update"
        bl_description = "Update SuperTorus"
        bl_options = {'REGISTER', 'UNDO'}
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
        @classmethod
        def poll(cls, context):
            engine = context.scene.render.engine
            ob = context.object
            return (ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES)
    
        def execute(self, context):
            bpy.ops.object.mode_set(mode="EDIT")
            bpy.ops.mesh.reveal()
            bpy.ops.mesh.select_all(action='SELECT')
            bpy.ops.mesh.delete(type='VERT')
            bpy.ops.object.mode_set(mode="OBJECT")
    
            pov_supertorus_define(context, None, context.object)
    
            return {'FINISHED'}
    #########################################################################################################
    class POVRAY_OT_loft_add(bpy.types.Operator):
        bl_idname = "pov.addloft"
        bl_label = "Add Loft Data"
        bl_description = "Create a Curve data for Meshmaker"
        bl_options = {'REGISTER', 'UNDO'}
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
        loft_n = IntProperty(name = "Segments",
                        description = "Vertical segments",
                        default = 16, min = 3, max = 720)
        loft_rings_bottom = IntProperty(name = "Bottom",
                        description = "Bottom rings",
                        default = 5, min = 2, max = 100)
        loft_rings_side = IntProperty(name = "Side",
                        description = "Side rings",
                        default = 10, min = 2, max = 100)
        loft_thick = FloatProperty(name = "Thickness",
                          description = "Manipulates the shape of the Ring",
                          default = 0.3, min = 0.01, max = 1.0)
        loft_r = FloatProperty(name = "Radius",
                          description = "Radius",
                          default = 1, min = 0.01, max = 10)
        loft_height = FloatProperty(name = "Height",
                          description = "Manipulates the shape of the Ring",
                          default = 2, min = 0.01, max = 10.0)
    
        def execute(self,context):
    
            props = self.properties
            loftData = bpy.data.curves.new('Loft', type='CURVE')
            loftData.dimensions = '3D'
            loftData.resolution_u = 2
            loftData.show_normal_face = False
            n=props.loft_n
            thick = props.loft_thick
            side = props.loft_rings_side
            bottom = props.loft_rings_bottom
            h = props.loft_height
            r = props.loft_r
            distB = r/bottom
            r0 = 0.00001
            z = -h/2
            print("New")
            for i in range(bottom+1):
                coords = []
                angle = 0
                for p in range(n):
                    x = r0*cos(angle)
                    y = r0*sin(angle)
                    coords.append((x,y,z))
                    angle+=pi*2/n
                r0+=distB
                nurbs = loftData.splines.new('NURBS')
                nurbs.points.add(len(coords)-1)
                for i, coord in enumerate(coords):
                    x,y,z = coord
                    nurbs.points[i].co = (x, y, z, 1)
                nurbs.use_cyclic_u = True
            for i in range(side):
                z+=h/side
                coords = []
                angle = 0
                for p in range(n):
                    x = r*cos(angle)
                    y = r*sin(angle)
                    coords.append((x,y,z))
                    angle+=pi*2/n
                nurbs = loftData.splines.new('NURBS')
                nurbs.points.add(len(coords)-1)
                for i, coord in enumerate(coords):
                    x,y,z = coord
                    nurbs.points[i].co = (x, y, z, 1)
                nurbs.use_cyclic_u = True
            r-=thick
            for i in range(side):
                coords = []
                angle = 0
                for p in range(n):
                    x = r*cos(angle)
                    y = r*sin(angle)
                    coords.append((x,y,z))
                    angle+=pi*2/n
                nurbs = loftData.splines.new('NURBS')
                nurbs.points.add(len(coords)-1)
                for i, coord in enumerate(coords):
                    x,y,z = coord
                    nurbs.points[i].co = (x, y, z, 1)
                nurbs.use_cyclic_u = True
                z-=h/side
            z = (-h/2) + thick
            distB = (r-0.00001)/bottom
            for i in range(bottom+1):
                coords = []
                angle = 0
                for p in range(n):
                    x = r*cos(angle)
                    y = r*sin(angle)
                    coords.append((x,y,z))
                    angle+=pi*2/n
                r-=distB
                nurbs = loftData.splines.new('NURBS')
                nurbs.points.add(len(coords)-1)
                for i, coord in enumerate(coords):
                    x,y,z = coord
                    nurbs.points[i].co = (x, y, z, 1)
                nurbs.use_cyclic_u = True
            ob = bpy.data.objects.new('Loft_shape', loftData)
            scn = bpy.context.scene
            scn.objects.link(ob)
            scn.objects.active = ob
            ob.select = True
            ob.pov.curveshape = "loft"
            return {'FINISHED'}
    
    class POVRAY_OT_plane_add(bpy.types.Operator):
        bl_idname = "pov.addplane"
        bl_label = "Plane"
        bl_description = "Add Plane"
        bl_options = {'REGISTER', 'UNDO'}
    
        def execute(self,context):
            layers = 20*[False]
            layers[0] = True
            bpy.ops.mesh.primitive_plane_add(radius = 100000,layers=layers)
            ob = context.object
            ob.name = ob.data.name = 'PovInfinitePlane'
            bpy.ops.object.mode_set(mode="EDIT")
    
            self.report({'INFO'}, "This native POV-Ray primitive "
    
                                     "won't have any vertex to show in edit mode")
            bpy.ops.mesh.hide(unselected=False)
            bpy.ops.object.mode_set(mode="OBJECT")
            bpy.ops.object.shade_smooth()
            ob.pov.object_as = "PLANE"
            return {'FINISHED'}
    
    class POVRAY_OT_box_add(bpy.types.Operator):
        bl_idname = "pov.addbox"
        bl_label = "Box"
        bl_description = "Add Box"
        bl_options = {'REGISTER', 'UNDO'}
    
        def execute(self,context):
            layers = 20*[False]
            layers[0] = True
            bpy.ops.mesh.primitive_cube_add(layers=layers)
            ob = context.object
            ob.name = ob.data.name = 'PovBox'
            bpy.ops.object.mode_set(mode="EDIT")
    
            self.report({'INFO'}, "This native POV-Ray primitive "
    
                                     "won't have any vertex to show in edit mode")
            bpy.ops.mesh.hide(unselected=False)
            bpy.ops.object.mode_set(mode="OBJECT")
            ob.pov.object_as = "BOX"
            return {'FINISHED'}
    
    
    
    def pov_cylinder_define(context, op, ob, radius, loc, loc_cap):
        if op:
            R = op.R
            loc = bpy.context.scene.cursor_location
            loc_cap[0] = loc[0]
            loc_cap[1] = loc[1]
            loc_cap[2] = (loc[2]+2)
        vec = Vector(loc_cap) - Vector(loc)
        depth = vec.length
        rot = Vector((0, 0, 1)).rotation_difference(vec)  # Rotation from Z axis.
        trans = rot * Vector((0, 0, depth / 2)) # Such that origin is at center of the base of the cylinder.
        roteuler = rot.to_euler()
        if not ob:
            bpy.ops.object.add(type='MESH', location=loc)
            ob = context.object
            ob.name = ob.data.name = "PovCylinder"
            ob.pov.cylinder_radius = radius
            ob.pov.cylinder_location_cap = vec
            ob.pov.object_as = "CYLINDER"
        else:
            ob.location = loc
    
        bpy.ops.object.mode_set(mode="EDIT")
        bpy.ops.mesh.reveal()
        bpy.ops.mesh.select_all(action='SELECT')
        bpy.ops.mesh.delete(type='VERT')
        bpy.ops.mesh.primitive_cylinder_add(radius=radius, depth=depth, location=loc, rotation=roteuler, end_fill_type='NGON') #'NOTHING'
        bpy.ops.transform.translate(value=trans)
    
        bpy.ops.mesh.hide(unselected=False)
        bpy.ops.object.mode_set(mode="OBJECT")
        bpy.ops.object.shade_smooth()
    
    
    
    class POVRAY_OT_cylinder_add(bpy.types.Operator):
        bl_idname = "pov.addcylinder"
        bl_label = "Cylinder"
        bl_description = "Add Cylinder"
        bl_options = {'REGISTER', 'UNDO'}
    
    
        # XXX Keep it in sync with __init__'s cylinder Primitive
    
        R = FloatProperty(name="Cylinder radius", min=0.00, max=10.0, default=1.0)
    
    
        imported_cyl_loc = FloatVectorProperty(
            name="Imported Pov base location",
    
            precision=6,
            default=(0.0, 0.0, 0.0))
    
    
        imported_cyl_loc_cap = FloatVectorProperty(
            name="Imported Pov cap location",
    
            precision=6,
    
            ob = context.object
    
            if ob:
                if ob.pov.imported_cyl_loc:
                    LOC = ob.pov.imported_cyl_loc
                if ob.pov.imported_cyl_loc_cap:
                    LOC_CAP = ob.pov.imported_cyl_loc_cap
            else:
                if not props.imported_cyl_loc:
                    LOC_CAP = LOC = bpy.context.scene.cursor_location
                    LOC_CAP[2] += 2.0
                else:
                    LOC = props.imported_cyl_loc
                    LOC_CAP = props.imported_cyl_loc_cap
    
                self.report({'INFO'}, "This native POV-Ray primitive "
    
                                         "won't have any vertex to show in edit mode")
    
    
            pov_cylinder_define(context, self, None, self.R, LOC, LOC_CAP)
    
            return {'FINISHED'}
    
    
    class POVRAY_OT_cylinder_update(bpy.types.Operator):
        bl_idname = "pov.cylinder_update"
        bl_label = "Update"
        bl_description = "Update Cylinder"
        bl_options = {'REGISTER', 'UNDO'}
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
        @classmethod
        def poll(cls, context):
            engine = context.scene.render.engine
    
            return (ob and ob.data and ob.type == 'MESH' and ob.pov.object_as == "CYLINDER" and engine in cls.COMPAT_ENGINES)
    
        def execute(self, context):
            ob = context.object
            radius = ob.pov.cylinder_radius
            loc = ob.location
            loc_cap = loc + ob.pov.cylinder_location_cap
    
            pov_cylinder_define(context, None, ob, radius, loc, loc_cap)
    
    ################################SPHERE##########################################
    def pov_sphere_define(context, op, ob, loc):
            if op:
                R = op.R
    
                loc = bpy.context.scene.cursor_location
    
            else:
                assert(ob)
                R = ob.pov.sphere_radius
    
                #keep object rotation and location for the add object operator
                obrot = ob.rotation_euler
                #obloc = ob.location
                obscale = ob.scale
    
                bpy.ops.object.mode_set(mode="EDIT")
                bpy.ops.mesh.reveal()
                bpy.ops.mesh.select_all(action='SELECT')
                bpy.ops.mesh.delete(type='VERT')
                bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, size=ob.pov.sphere_radius, location=loc, rotation=obrot)
                #bpy.ops.transform.rotate(axis=obrot,constraint_orientation='GLOBAL')
                bpy.ops.transform.resize(value=obscale)
                #bpy.ops.transform.rotate(axis=obrot, proportional_size=1)
    
                bpy.ops.mesh.hide(unselected=False)
                bpy.ops.object.mode_set(mode="OBJECT")
    
                #bpy.ops.transform.rotate(axis=obrot,constraint_orientation='GLOBAL')
    
            if not ob:
                bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, size=R, location=loc)
                ob = context.object
                ob.name =  ob.data.name = "PovSphere"
                ob.pov.object_as = "SPHERE"
                ob.pov.sphere_radius = R
                bpy.ops.object.mode_set(mode="EDIT")
                bpy.ops.mesh.hide(unselected=False)
                bpy.ops.object.mode_set(mode="OBJECT")
    
    class POVRAY_OT_sphere_add(bpy.types.Operator):
        bl_idname = "pov.addsphere"
        bl_label = "Sphere"
        bl_description = "Add Sphere Shape"
        bl_options = {'REGISTER', 'UNDO'}
    
        # XXX Keep it in sync with __init__'s torus Primitive
    
        R = FloatProperty(name="Sphere radius",min=0.00, max=10.0, default=0.5)
    
    
        imported_loc = FloatVectorProperty(
            name="Imported Pov location",
    
            precision=6,
    
        def execute(self,context):
            props = self.properties
            R = props.R
            ob = context.object
    
                if not props.imported_loc:
                    LOC = bpy.context.scene.cursor_location
    
                    LOC = props.imported_loc
    
                    self.report({'INFO'}, "This native POV-Ray primitive "
    
                                             "won't have any vertex to show in edit mode")
    
        # def execute(self,context):
            # layers = 20*[False]
            # layers[0] = True
    
            # bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4, radius=ob.pov.sphere_radius, layers=layers)
            # ob = context.object
            # bpy.ops.object.mode_set(mode="EDIT")
    
            # self.report({'INFO'}, "This native POV-Ray primitive "
    
                                     # "won't have any vertex to show in edit mode")
            # bpy.ops.mesh.hide(unselected=False)
            # bpy.ops.object.mode_set(mode="OBJECT")
            # bpy.ops.object.shade_smooth()
            # ob.pov.object_as = "SPHERE"
            # ob.name = ob.data.name = 'PovSphere'
            # return {'FINISHED'}
    class POVRAY_OT_sphere_update(bpy.types.Operator):
        bl_idname = "pov.sphere_update"
        bl_label = "Update"
        bl_description = "Update Sphere"
        bl_options = {'REGISTER', 'UNDO'}
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
        @classmethod
        def poll(cls, context):
            engine = context.scene.render.engine
            ob = context.object
            return (ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES)
    
        def execute(self, context):
    
            pov_sphere_define(context, None, context.object,context.object.location)
    
    
            return {'FINISHED'}
    
    
    
    ####################################CONE#######################################
    def pov_cone_define(context, op, ob):
        verts = []
        faces = []
        if op:
            mesh = None
            base = op.base
            cap = op.cap
            seg = op.seg
            height = op.height
        else:
            assert(ob)
            mesh = ob.data
            base = ob.pov.cone_base_radius
            cap = ob.pov.cone_cap_radius
            seg = ob.pov.cone_segments
    
            height = ob.pov.cone_height
    
    
        zc = height / 2
        zb = -zc
        angle = 2 * pi / seg
        t = 0
        for i in range(seg):
            xb = base * cos(t)
            yb = base * sin(t)
            xc = cap * cos(t)
            yc = cap * sin(t)
            verts.append((xb, yb, zb))
            verts.append((xc, yc, zc))
            t += angle
        for i in range(seg):
            f = i * 2
            if i == seg - 1:
                faces.append([0, 1, f + 1, f])
            else:
                faces.append([f + 2, f + 3, f + 1, f])
        if base != 0:
            base_face = []
            for i in range(seg - 1, -1, -1):
                p = i * 2
                base_face.append(p)
            faces.append(base_face)
        if cap != 0:
            cap_face = []
            for i in range(seg):
                p = i * 2 + 1
                cap_face.append(p)
            faces.append(cap_face)
    
        mesh = pov_define_mesh(mesh, verts, [], faces, "PovCone", True)
        if not ob:
            ob_base = object_utils.object_data_add(context, mesh, operator=None)
            ob = ob_base.object
            ob.pov.object_as = "CONE"
            ob.pov.cone_base_radius = base
            ob.pov.cone_cap_radius = cap
            ob.pov.cone_height = height
            ob.pov.cone_base_z = zb
            ob.pov.cone_cap_z = zc
    
    
    class POVRAY_OT_cone_add(bpy.types.Operator):
        bl_idname = "pov.cone_add"
        bl_label = "Cone"
        bl_description = "Add Cone"
        bl_options = {'REGISTER', 'UNDO'}
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
        # XXX Keep it in sync with __init__'s RenderPovSettingsConePrimitive
        #     If someone knows how to define operators' props from a func, I'd be delighted to learn it!
        base = FloatProperty(
            name = "Base radius", description = "The first radius of the cone",
            default = 1.0, min = 0.01, max = 100.0)
        cap = FloatProperty(
            name = "Cap radius", description = "The second radius of the cone",
            default = 0.3, min = 0.0, max = 100.0)
        seg = IntProperty(
            name = "Segments", description = "Radial segmentation of the proxy mesh",
            default = 16, min = 3, max = 265)
        height = FloatProperty(
            name = "Height", description = "Height of the cone",
            default = 2.0, min = 0.01, max = 100.0)
    
        @classmethod
        def poll(cls, context):
            engine = context.scene.render.engine
            return (engine in cls.COMPAT_ENGINES)
    
        def execute(self, context):
            pov_cone_define(context, self, None)
    
    
            self.report({'INFO'}, "This native POV-Ray primitive won't have any vertex to show in edit mode")
    
            return {'FINISHED'}
    
    
    class POVRAY_OT_cone_update(bpy.types.Operator):
        bl_idname = "pov.cone_update"
        bl_label = "Update"
        bl_description = "Update Cone"
        bl_options = {'REGISTER', 'UNDO'}
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
        @classmethod
        def poll(cls, context):
            engine = context.scene.render.engine
            ob = context.object
            return (ob and ob.data and ob.type == 'MESH' and engine in cls.COMPAT_ENGINES)
    
        def execute(self, context):
            bpy.ops.object.mode_set(mode="EDIT")
            bpy.ops.mesh.reveal()
            bpy.ops.mesh.select_all(action='SELECT')
            bpy.ops.mesh.delete(type='VERT')
            bpy.ops.object.mode_set(mode="OBJECT")
    
            pov_cone_define(context, None, context.object)
    
            return {'FINISHED'}
    #########################################################################################################
    
    class POVRAY_OT_isosurface_box_add(bpy.types.Operator):
        bl_idname = "pov.addisosurfacebox"
        bl_label = "Isosurface Box"
        bl_description = "Add Isosurface contained by Box"
        bl_options = {'REGISTER', 'UNDO'}
    
    
        def execute(self,context):
            layers = 20*[False]
            layers[0] = True
            bpy.ops.mesh.primitive_cube_add(layers = layers)
            ob = context.object
            bpy.ops.object.mode_set(mode="EDIT")
    
            self.report({'INFO'}, "This native POV-Ray primitive "
    
                                     "won't have any vertex to show in edit mode")
            bpy.ops.mesh.hide(unselected=False)
            bpy.ops.object.mode_set(mode="OBJECT")
            ob.pov.object_as = "ISOSURFACE"
            ob.pov.contained_by = 'box'
            ob.name = 'Isosurface'
            return {'FINISHED'}
    
    class POVRAY_OT_isosurface_sphere_add(bpy.types.Operator):
        bl_idname = "pov.addisosurfacesphere"
        bl_label = "Isosurface Sphere"
        bl_description = "Add Isosurface contained by Sphere"
        bl_options = {'REGISTER', 'UNDO'}
    
    
        def execute(self,context):
            layers = 20*[False]
            layers[0] = True
            bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=4,layers=layers)
            ob = context.object
            bpy.ops.object.mode_set(mode="EDIT")
    
            self.report({'INFO'}, "This native POV-Ray primitive "
    
                                     "won't have any vertex to show in edit mode")
            bpy.ops.mesh.hide(unselected=False)