Skip to content
Snippets Groups Projects
primitives.py 79.2 KiB
Newer Older
  • Learn to ignore specific revisions
  •     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
            )
    
            pov_sphere_define(
                context, None, context.object, context.object.location
            )
    
            return {'FINISHED'}
    
    
    
    ####################################CONE#######################################
    def pov_cone_define(context, op, ob):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV cone using pov_define_mesh() function.
    
        Blender cone does not offer the same features such as a second radius."""
    
        verts = []
        faces = []
        if op:
            mesh = None
            base = op.base
            cap = op.cap
            seg = op.seg
            height = op.height
        else:
    
            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:
    
    Dalai Felinto's avatar
    Dalai Felinto committed
            ob = object_utils.object_data_add(context, mesh, operator=None)
    
            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):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV cone using pov_cone_define() function."""
    
    
        bl_idname = "pov.cone_add"
        bl_label = "Cone"
        bl_description = "Add Cone"
        bl_options = {'REGISTER', 'UNDO'}
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        # XXX Keep it in sync with __init__.py'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
    
            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):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Update the POV cone.
    
        Delete its previous proxy geometry and rerun pov_cone_define() function
        with the new parameters"""
    
    
        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'}
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
    ########################################ISOSURFACES##################################
    
    class POVRAY_OT_isosurface_box_add(bpy.types.Operator):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV isosurface box using also just a Blender mesh cube.
    
        Flag its primitive type with a specific pov.object_as attribute and lock edit mode
        to keep proxy consistency by hiding edit geometry."""
    
    
        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()
    
            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 = 'PovIsosurfaceBox'
    
    class POVRAY_OT_isosurface_sphere_add(bpy.types.Operator):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV isosurface sphere by a Blender mesh icosphere.
    
        Flag its primitive type with a specific pov.object_as attribute and lock edit mode
        to keep proxy consistency by hiding edit geometry."""
    
    
        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)
    
            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 = "ISOSURFACE"
            ob.pov.contained_by = 'sphere'
    
            ob.name = 'PovIsosurfaceSphere'
    
    class POVRAY_OT_sphere_sweep_add(bpy.types.Operator):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV sphere_sweep using a Blender NURBS curve.
    
        Flag its primitive type with a specific ob.pov.curveshape attribute and
        leave access to edit mode to keep user editable handles."""
    
    
        bl_idname = "pov.addspheresweep"
        bl_label = "Sphere Sweep"
        bl_description = "Create Sphere Sweep along curve"
        bl_options = {'REGISTER', 'UNDO'}
    
    
        def execute(self, context):
            # layers = 20*[False]
            # layers[0] = True
    
            bpy.ops.curve.primitive_nurbs_curve_add()
    
            ob = context.object
            ob.name = ob.data.name = "PovSphereSweep"
            ob.pov.curveshape = "sphere_sweep"
            ob.data.bevel_depth = 0.02
            ob.data.bevel_resolution = 4
            ob.data.fill_mode = 'FULL'
    
            # ob.data.splines[0].order_u = 4
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV blob using a Blender meta ball.
    
        No need to flag its primitive type as meta are exported to blobs
        and leave access to edit mode to keep user editable thresholds."""
    
    
        bl_idname = "pov.addblobsphere"
        bl_label = "Blob Sphere"
        bl_description = "Add Blob Sphere"
        bl_options = {'REGISTER', 'UNDO'}
    
    
        def execute(self, context):
            # layers = 20*[False]
            # layers[0] = True
            bpy.ops.object.metaball_add(type='BALL')
    
    
    class POVRAY_OT_rainbow_add(bpy.types.Operator):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV rainbow using a Blender spot light.
    
        Rainbows indeed propagate along a visibility cone.
        Flag its primitive type with a specific ob.pov.object_as attribute
        and leave access to edit mode to keep user editable handles.
        Add a constraint to orient it towards camera because POV Rainbows
        are view dependant and having it always initially visible is less
        confusing """
    
    
        bl_idname = "pov.addrainbow"
        bl_label = "Rainbow"
        bl_description = "Add Rainbow"
        bl_options = {'REGISTER', 'UNDO'}
    
        def execute(self, context):
    
            bpy.ops.object.light_add(type='SPOT', radius=1)
    
            ob = context.object
            ob.data.show_cone = False
            ob.data.spot_blend = 0.5
    
            # ob.data.shadow_buffer_clip_end = 0 # deprecated in 2.8
    
            ob.data.shadow_buffer_clip_start = 4 * cam.location.length
    
            ob.data.energy = 0
    
            ob.name = ob.data.name = "PovRainbow"
            ob.pov.object_as = "RAINBOW"
    
            # obj = context.object
    
            bpy.ops.object.constraint_add(type='DAMPED_TRACK')
    
            ob.constraints["Damped Track"].target = cam
            ob.constraints["Damped Track"].track_axis = 'TRACK_NEGATIVE_Z'
            ob.location = -cam.location
    
    
            # refocus on the actual rainbow
    
            bpy.context.view_layer.objects.active = ob
    
            ob.select_set(True)
    
    class POVRAY_OT_height_field_add(bpy.types.Operator, ImportHelper):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV height_field using a displaced grid.
    
        texture slot fix and displace modifier will be needed because noise
        displace operator was deprecated in 2.8"""
    
    
        bl_idname = "pov.addheightfield"
        bl_label = "Height Field"
        bl_description = "Add Height Field "
        bl_options = {'REGISTER', 'UNDO'}
    
        # XXX Keep it in sync with __init__'s hf Primitive
        # filename_ext = ".png"
    
        # default="*.exr;*.gif;*.hdr;*.iff;*.jpeg;*.jpg;*.pgm;*.png;*.pot;*.ppm;*.sys;*.tga;*.tiff;*.EXR;*.GIF;*.HDR;*.IFF;*.JPEG;*.JPG;*.PGM;*.PNG;*.POT;*.PPM;*.SYS;*.TGA;*.TIFF",
        # options={'HIDDEN'},
        # )
        quality: IntProperty(
            name="Quality", description="", default=100, min=1, max=100
        )
        hf_filename: StringProperty(maxlen=1024)
    
        hf_gamma: FloatProperty(
    
            name="Gamma", description="Gamma", min=0.0001, max=20.0, default=1.0
        )
    
        hf_premultiplied: BoolProperty(
    
            name="Premultiplied", description="Premultiplied", default=True
        )
    
        hf_smooth: BoolProperty(name="Smooth", description="Smooth", default=False)
    
        hf_water: FloatProperty(
    
            name="Water Level",
            description="Wather Level",
            min=0.00,
            max=1.00,
            default=0.0,
        )
    
        hf_hierarchy: BoolProperty(
    
            name="Hierarchy", description="Height field hierarchy", default=True
        )
    
        def execute(self, context):
    
            props = self.properties
            impath = bpy.path.abspath(self.filepath)
            img = bpy.data.images.load(impath)
            im_name = img.name
            im_name, file_extension = os.path.splitext(im_name)
    
            hf_tex = bpy.data.textures.new('%s_hf_image' % im_name, type='IMAGE')
    
            mat = bpy.data.materials.new('Tex_%s_hf' % im_name)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            hf_slot = mat.pov_texture_slots.add()
            hf_slot.texture = hf_tex.name
    
            # layers = 20*[False]
            # layers[0] = True
    
            res = 100 / quality
            w, h = hf_tex.image.size[:]
            w = int(w / res)
            h = int(h / res)
            bpy.ops.mesh.primitive_grid_add(
                x_subdivisions=w, y_subdivisions=h, size=0.5
            )
    
            ob.name = ob.data.name = '%s' % im_name
    
            ob.data.materials.append(mat)
            bpy.ops.object.mode_set(mode="EDIT")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            # bpy.ops.mesh.noise(factor=1) # TODO replace by a displace modifier as noise deprecated in 2.8
    
            # needs a loop to select by index?
            # bpy.ops.object.material_slot_remove()
            # material just left there for now
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            mat.pov_texture_slots.clear()
    
            bpy.ops.object.mode_set(mode="EDIT")
            bpy.ops.mesh.hide(unselected=False)
            bpy.ops.object.mode_set(mode="OBJECT")
            ob.pov.object_as = 'HEIGHT_FIELD'
            ob.pov.hf_filename = impath
            return {'FINISHED'}
    
    ############################TORUS############################################
    def pov_torus_define(context, op, ob):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV torus using just a Blender torus.
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        But flag its primitive type with a specific pov.object_as attribute and lock edit mode
        to keep proxy consistency by hiding edit geometry."""
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        if op:
            mas = op.mas
            mis = op.mis
            mar = op.mar
            mir = op.mir
        else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            mas = ob.pov.torus_major_segments
            mis = ob.pov.torus_minor_segments
            mar = ob.pov.torus_major_radius
            mir = ob.pov.torus_minor_radius
    
            # keep object rotation and location for the add object operator
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            obrot = ob.rotation_euler
            obloc = ob.location
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            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_torus_add(
                rotation=obrot,
                location=obloc,
                major_segments=mas,
                minor_segments=mis,
                major_radius=mar,
                minor_radius=mir,
            )
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            bpy.ops.mesh.hide(unselected=False)
            bpy.ops.object.mode_set(mode="OBJECT")
    
        if not ob:
    
            bpy.ops.mesh.primitive_torus_add(
                major_segments=mas,
                minor_segments=mis,
                major_radius=mar,
                minor_radius=mir,
            )
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            ob = context.object
    
            ob.name = ob.data.name = "PovTorus"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            ob.pov.object_as = "TORUS"
            ob.pov.torus_major_segments = mas
            ob.pov.torus_minor_segments = mis
            ob.pov.torus_major_radius = mar
            ob.pov.torus_minor_radius = mir
            bpy.ops.object.mode_set(mode="EDIT")
            bpy.ops.mesh.hide(unselected=False)
            bpy.ops.object.mode_set(mode="OBJECT")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV torus using using pov_torus_define() function."""
    
    
        bl_idname = "pov.addtorus"
        bl_label = "Torus"
        bl_description = "Add Torus"
        bl_options = {'REGISTER', 'UNDO'}
    
        # XXX Keep it in sync with __init__'s torus Primitive
    
        mas: IntProperty(
            name="Major Segments", description="", default=48, min=3, max=720
        )
        mis: IntProperty(
            name="Minor Segments", description="", default=12, min=3, max=720
        )
        mar: FloatProperty(name="Major Radius", description="", default=1.0)
        mir: FloatProperty(name="Minor Radius", description="", default=0.25)
    
        def execute(self, context):
    
            props = self.properties
            mar = props.mar
            mir = props.mir
            mas = props.mas
            mis = props.mis
            pov_torus_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_torus_update(bpy.types.Operator):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Update the POV torus.
    
        Delete its previous proxy geometry and rerun pov_torus_define() function
        with the new parameters"""
    
    
        bl_idname = "pov.torus_update"
        bl_label = "Update"
        bl_description = "Update Torus"
        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_torus_define(context, None, context.object)
    
    
            return {'FINISHED'}
    
    
    ###################################################################################
    
    
    class POVRAY_OT_prism_add(bpy.types.Operator):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV prism using using an extruded curve."""
    
    
        bl_idname = "pov.addprism"
        bl_label = "Prism"
        bl_description = "Create Prism"
        bl_options = {'REGISTER', 'UNDO'}
    
        prism_n: IntProperty(
            name="Sides", description="Number of sides", default=5, min=3, max=720
        )
        prism_r: FloatProperty(name="Radius", description="Radius", default=1.0)
    
        def execute(self, context):
    
            props = self.properties
            loftData = bpy.data.curves.new('Prism', type='CURVE')
            loftData.dimensions = '2D'
            loftData.resolution_u = 2
    
            # loftData.show_normal_face = False
    
            n = props.prism_n
            r = props.prism_r
    
                x = r * cos(angle)
                y = r * sin(angle)
                coords.append((x, y, z))
                angle += pi * 2 / n
    
            poly.points.add(len(coords) - 1)
    
                poly.points[i].co = (x, y, z, 1)
            poly.use_cyclic_u = True
    
            ob = bpy.data.objects.new('Prism_shape', loftData)
            scn = bpy.context.scene
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            scn.collection.objects.link(ob)
    
            context.view_layer.objects.active = ob
    
            ob.select_set(True)
    
            ob.pov.curveshape = "prism"
            ob.name = ob.data.name = "Prism"
            return {'FINISHED'}
    
    ##############################PARAMETRIC######################################
    
    def pov_parametric_define(context, op, ob):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV parametric surfaces by math surface from add mesh extra objects addon."""
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        if op:
            u_min = op.u_min
            u_max = op.u_max
            v_min = op.v_min
            v_max = op.v_max
            x_eq = op.x_eq
            y_eq = op.y_eq
            z_eq = op.z_eq
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        else:
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            u_min = ob.pov.u_min
            u_max = ob.pov.u_max
            v_min = ob.pov.v_min
            v_max = ob.pov.v_max
            x_eq = ob.pov.x_eq
            y_eq = ob.pov.y_eq
            z_eq = ob.pov.z_eq
    
    
            # keep object rotation and location for the updated object
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            obloc = ob.location
    
            obrot = ob.rotation_euler  # In radians
            # Parametric addon has no loc rot, some extra work is needed
            # in case cursor has moved
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            curloc = bpy.context.scene.cursor.location
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            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_xyz_function_surface(
                x_eq=x_eq,
                y_eq=y_eq,
                z_eq=z_eq,
                range_u_min=u_min,
                range_u_max=u_max,
                range_v_min=v_min,
                range_v_max=v_max,
            )
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            bpy.ops.mesh.select_all(action='SELECT')
    
            # extra work:
            bpy.ops.transform.translate(value=(obloc - curloc), proportional_size=1)
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            bpy.ops.transform.rotate(axis=obrot, proportional_size=1)
    
            bpy.ops.mesh.hide(unselected=False)
            bpy.ops.object.mode_set(mode="OBJECT")
    
        if not ob:
    
            bpy.ops.mesh.primitive_xyz_function_surface(
                x_eq=x_eq,
                y_eq=y_eq,
                z_eq=z_eq,
                range_u_min=u_min,
                range_u_max=u_max,
                range_v_min=v_min,
                range_v_max=v_max,
            )
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            ob = context.object
    
            ob.name = ob.data.name = "PovParametric"
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
            ob.pov.object_as = "PARAMETRIC"
    
            ob.pov.u_min = u_min
            ob.pov.u_max = u_max
            ob.pov.v_min = v_min
            ob.pov.v_max = v_max
            ob.pov.x_eq = x_eq
            ob.pov.y_eq = y_eq
            ob.pov.z_eq = z_eq
    
            bpy.ops.object.mode_set(mode="EDIT")
            bpy.ops.mesh.hide(unselected=False)
            bpy.ops.object.mode_set(mode="OBJECT")
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the representation of POV parametric surfaces using pov_parametric_define() function."""
    
        bl_idname = "pov.addparametric"
        bl_label = "Parametric"
        bl_description = "Add Paramertic"
        bl_options = {'REGISTER', 'UNDO'}
    
        # XXX Keep it in sync with __init__'s Parametric primitive
    
        u_min: FloatProperty(name="U Min", description="", default=0.0)
        v_min: FloatProperty(name="V Min", description="", default=0.0)
        u_max: FloatProperty(name="U Max", description="", default=6.28)
        v_max: FloatProperty(name="V Max", description="", default=12.57)
        x_eq: StringProperty(maxlen=1024, default="cos(v)*(1+cos(u))*sin(v/8)")
        y_eq: StringProperty(maxlen=1024, default="sin(u)*sin(v/8)+cos(v/8)*1.5")
        z_eq: StringProperty(maxlen=1024, default="sin(v)*(1+cos(u))*sin(v/8)")
    
        def execute(self, context):
    
            props = self.properties
            u_min = props.u_min
            v_min = props.v_min
            u_max = props.u_max
            v_max = props.v_max
            x_eq = props.x_eq
            y_eq = props.y_eq
            z_eq = props.z_eq
    
            self.report(
                {'INFO'},
                "This native POV-Ray primitive "
                "won't have any vertex to show in edit mode",
            )
    
    class POVRAY_OT_parametric_update(bpy.types.Operator):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Update the representation of POV parametric surfaces.
    
        Delete its previous proxy geometry and rerun pov_parametric_define() function
        with the new parameters"""
    
        bl_idname = "pov.parametric_update"
        bl_label = "Update"
        bl_description = "Update parametric object"
        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_parametric_define(context, None, context.object)
    
            return {'FINISHED'}
    
    #######################################################################
    
    class POVRAY_OT_shape_polygon_to_circle_add(bpy.types.Operator):
    
    Maurice Raybaud's avatar
    Maurice Raybaud committed
        """Add the proxy mesh for POV Polygon to circle lofting macro"""
    
    
        bl_idname = "pov.addpolygontocircle"
        bl_label = "Polygon To Circle Blending"
        bl_description = "Add Polygon To Circle Blending Surface"
        bl_options = {'REGISTER', 'UNDO'}
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
        # XXX Keep it in sync with __init__'s polytocircle properties
    
        polytocircle_resolution: IntProperty(
            name="Resolution", description="", default=3, min=0, max=256
        )
        polytocircle_ngon: IntProperty(
            name="NGon", description="", min=3, max=64, default=5
        )
        polytocircle_ngonR: FloatProperty(
            name="NGon Radius", description="", default=0.3
        )
        polytocircle_circleR: FloatProperty(
            name="Circle Radius", description="", default=1.0
        )
    
        def execute(self, context):
    
            props = self.properties
            ngon = props.polytocircle_ngon
            ngonR = props.polytocircle_ngonR
            circleR = props.polytocircle_circleR
            resolution = props.polytocircle_resolution
    
            # layers = 20*[False]
            # layers[0] = True
            bpy.ops.mesh.primitive_circle_add(
                vertices=ngon, radius=ngonR, fill_type='NGON', enter_editmode=True
            )
    
            bpy.ops.transform.translate(value=(0, 0, 1))
            bpy.ops.mesh.subdivide(number_cuts=resolution)
    
            numCircleVerts = ngon + (ngon * resolution)
    
            bpy.ops.mesh.primitive_circle_add(
                vertices=numCircleVerts,
                radius=circleR,
                fill_type='NGON',
                enter_editmode=True,
            )
    
            bpy.ops.transform.translate(value=(0, 0, -1))
            bpy.ops.mesh.select_all(action='SELECT')
            bpy.ops.mesh.bridge_edge_loops()
            if ngon < 5:
                bpy.ops.mesh.select_all(action='DESELECT')
    
                bpy.ops.mesh.primitive_circle_add(
                    vertices=ngon,
                    radius=ngonR,
                    fill_type='TRIFAN',
                    enter_editmode=True,
                )
    
                bpy.ops.transform.translate(value=(0, 0, 1))
                bpy.ops.mesh.select_all(action='SELECT')
                bpy.ops.mesh.remove_doubles()
            bpy.ops.object.mode_set(mode='OBJECT')
            ob = context.object
            ob.name = "Polygon_To_Circle"
            ob.pov.object_as = 'POLYCIRCLE'
            ob.pov.ngon = ngon
            ob.pov.ngonR = ngonR
            ob.pov.circleR = circleR
            bpy.ops.object.mode_set(mode="EDIT")
            bpy.ops.mesh.hide(unselected=False)
            bpy.ops.object.mode_set(mode="OBJECT")
            return {'FINISHED'}
    
    class ImportPOV(bpy.types.Operator, ImportHelper):
        """Load Povray files"""
    
        bl_idname = "import_scene.pov"
        bl_label = "POV-Ray files (.pov/.inc)"
    
        bl_options = {'PRESET', 'UNDO'}
        COMPAT_ENGINES = {'POVRAY_RENDER'}
    
    
        files: CollectionProperty(
            type=bpy.types.OperatorFileListElement, options={'HIDDEN', 'SKIP_SAVE'}
        )
        directory: StringProperty(
            maxlen=1024, subtype='FILE_PATH', options={'HIDDEN', 'SKIP_SAVE'}
        )
    
        filename_ext = {".pov", ".inc"}
        filter_glob: StringProperty(default="*.pov;*.inc", options={'HIDDEN'})
    
        import_at_cur: BoolProperty(
            name="Import at Cursor Location",
            description="Ignore Object Matrix",
            default=False,
        )
    
            blendMats = []  ##############
            povMats = []  ##############
    
            name = 'Mesh2_%s' % suffix
    
            name_search = False
            verts_search = False
            faces_search = False
            plane_search = False
            box_search = False
            cylinder_search = False
            sphere_search = False
            cone_search = False
    
            tex_search = False  ##################
    
            cache = []
            matrixes = {}
            writematrix = False
            index = None
            value = None
    
            # filepov = bpy.path.abspath(self.filepath) #was used for single files
    
                r = g = b = 0.5
                f = t = 0
                color = None
    
                for item, value in enumerate(cache):
    
                    if value == 'texture':
                        pass
    
                    if value == 'pigment':
    
                        if cache[item + 2] in {'rgb', 'srgb'}:
    
                        elif cache[item + 2] in {'rgbf', 'srgbf'}:
    
                        elif cache[item + 2] in {'rgbt', 'srgbt'}:
    
                                r, g, b, t = (
                                    float(cache[item + 3]),
                                    float(cache[item + 4]),
                                    float(cache[item + 5]),
                                    float(cache[item + 6]),
                                )
    
                                r = g = b = t = float(cache[item + 2])
                            color = (r, g, b, t)
    
                        elif cache[item + 2] in {'rgbft', 'srgbft'}:
    
                if colors == [] or (colors != [] and color not in colors):
                    colors.append(color)
    
                    name = ob.name + "_mat"
    
                    matNames.append(name)
                    mat = bpy.data.materials.new(name)
    
                    mat.diffuse_color = (r, g, b)
                    mat.alpha = 1 - t
    
                    if mat.alpha != 1:
    
                        mat.use_transparency = True
    
                    for i, value in enumerate(colors):
                        if color == value:
    
                            ob.data.materials.append(
                                bpy.data.materials[matNames[i]]
                            )
    
    
                print("Importing file: " + file.name)
    
                filepov = self.directory + file.name
                for line in open(filepov):
    
                    string = line.replace("{", " ")
                    string = string.replace("}", " ")
                    string = string.replace("<", " ")
                    string = string.replace(">", " ")
                    string = string.replace(",", " ")
    
                    lw = string.split()
                    lenwords = len(lw)
                    if lw:
                        if lw[0] == "object":
                            writematrix = True
                        if writematrix:
    
                            if lw[0] not in {"object", "matrix"}:
    
                                value = [
                                    float(lw[1]),
                                    float(lw[2]),
                                    float(lw[3]),
                                    float(lw[4]),
                                    float(lw[5]),
                                    float(lw[6]),
                                    float(lw[7]),
                                    float(lw[8]),
                                    float(lw[9]),
                                    float(lw[10]),
                                    float(lw[11]),
                                    float(lw[12]),
                                ]
                                matrixes[index] = value
    
                                writematrix = False
                for line in open(filepov):
    
                    S = line.replace("{", " { ")
                    S = S.replace("}", " } ")
                    S = S.replace(",", " ")
                    S = S.replace("<", "")
                    S = S.replace(">", " ")
                    S = S.replace("=", " = ")
                    S = S.replace(";", " ; ")
    
                    lenS = len(S)
                    for i, word in enumerate(S):
                        ##################Primitives Import##################
    
                        if word == 'cone':
                            cone_search = True
                            name_search = False
                        if cone_search:
                            cache.append(word)
                            if cache[-1] == '}':
                                try:
                                    x0 = float(cache[2])
                                    y0 = float(cache[3])
                                    z0 = float(cache[4])
                                    r0 = float(cache[5])
                                    x1 = float(cache[6])
                                    y1 = float(cache[7])
                                    z1 = float(cache[8])
                                    r1 = float(cache[9])
                                    # Y is height in most pov files, not z
    
                                    bpy.ops.pov.cone_add(
                                        base=r0, cap=r1, height=(y1 - y0)
                                    )
    
                                    ob.location = (x0, y0, z0)
                                    # ob.scale = (r,r,r)
    
                                    mat_search(cache)
    
                                cone_search = False
    
                        if word == 'plane':
                            plane_search = True
                            name_search = False
                        if plane_search:
                            cache.append(word)
                            if cache[-1] == '}':
                                try:
                                    bpy.ops.pov.addplane()
                                    ob = context.object
    
                                    mat_search(cache)