Skip to content
Snippets Groups Projects
primitives.py 79.2 KiB
Newer Older
# ##### 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>

""" Get POV-Ray specific objects In and Out of Blender """
import os.path
from bpy_extras.io_utils import ImportHelper
from bpy_extras import object_utils
from bpy.utils import register_class
from math import atan, pi, degrees, sqrt, cos, sin


from bpy.props import (
    StringProperty,
    BoolProperty,
    IntProperty,
    FloatProperty,
    FloatVectorProperty,
    EnumProperty,
    PointerProperty,
    CollectionProperty,
from mathutils import Vector, Matrix

# import collections


def pov_define_mesh(mesh, verts, edges, faces, name, hide_geometry=True):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Generate proxy mesh."""
    if mesh is None:
        mesh = bpy.data.meshes.new(name)
    mesh.from_pydata(verts, edges, faces)
    mesh.update()
    mesh.validate(
        verbose=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):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Add the representation of POV lathe using a screw modifier."""
    bl_options = {'REGISTER', 'UNDO'}
        # ayers=[False]*20
        # layers[0]=True
Campbell Barton's avatar
Campbell Barton committed
        bpy.ops.curve.primitive_bezier_curve_add(
            location=context.scene.cursor.location,
Campbell Barton's avatar
Campbell Barton committed
            rotation=(0, 0, 0),
        ob = context.view_layer.objects.active
Campbell Barton's avatar
Campbell Barton committed
        ob_data = ob.data
        ob.name = ob_data.name = "PovLathe"
        ob_data.dimensions = '2D'
        ob_data.transform(Matrix.Rotation(-pi / 2.0, 4, 'Z'))
        ob.pov.object_as = 'LATHE'
Campbell Barton's avatar
Campbell Barton committed
        self.report({'INFO'}, "This native POV-Ray primitive")
        ob.pov.curveshape = "lathe"
        bpy.ops.object.modifier_add(type='SCREW')
Campbell Barton's avatar
Campbell Barton committed
        mod = ob.modifiers[-1]
        mod.axis = 'Y'
        mod.show_render = False
        return {'FINISHED'}


def pov_superellipsoid_define(context, op, ob):
Maurice Raybaud's avatar
Maurice Raybaud committed
    """Create the proxy mesh of a POV superellipsoid using the pov_superellipsoid_define() function."""
Maurice Raybaud's avatar
Maurice Raybaud committed
    if op:
        mesh = None
Maurice Raybaud's avatar
Maurice Raybaud committed
        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
Maurice Raybaud's avatar
Maurice Raybaud committed
    else:
Maurice Raybaud's avatar
Maurice Raybaud committed
        mesh = ob.data
Maurice Raybaud's avatar
Maurice Raybaud committed
        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

    verts = []
    stepSegment = 360 / v * pi / 180
    stepRing = pi / u
    angSegment = 0
    angRing = -pi / 2
    step = 0
    for ring in range(0, u - 1):
Maurice Raybaud's avatar
Maurice Raybaud committed
        angRing += stepRing
        for segment in range(0, v):
Maurice Raybaud's avatar
Maurice Raybaud committed
            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
            ):
Maurice Raybaud's avatar
Maurice Raybaud committed
                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
            ):
Maurice Raybaud's avatar
Maurice Raybaud committed
                y = -y
            z = r * (abs(sin(angRing)) ** n1)
Maurice Raybaud's avatar
Maurice Raybaud committed
            if sin(angRing) < 0:
                z = -z
            x = round(x, 4)
            y = round(y, 4)
            z = round(z, 4)
            verts.append((x, y, z))
Maurice Raybaud's avatar
Maurice Raybaud committed
    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)
Maurice Raybaud's avatar
Maurice Raybaud committed
    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)
Maurice Raybaud's avatar
Maurice Raybaud committed
                faces.append(face)
            if i == v - 1:
                face = (indexDown, i, 0)
Maurice Raybaud's avatar
Maurice Raybaud committed
                faces.append(face)
        for i in range(0, v):
            if i < v - 1:
                face = (indexUp, i + indexStartDown, i + indexStartDown + 1)
Maurice Raybaud's avatar
Maurice Raybaud committed
                faces.append(face)
            if i == v - 1:
                face = (indexUp, i + indexStartDown, indexStartDown)
Maurice Raybaud's avatar
Maurice Raybaud committed
                faces.append(face)
    if edit == 'NGONS':
        face = []
        for i in range(0, v):
Maurice Raybaud's avatar
Maurice Raybaud committed
            face.append(i)
        faces.append(face)
        face = []
        indexUp = len(verts) - 1
        for i in range(0, v):
            face.append(indexUp - i)
Maurice Raybaud's avatar
Maurice Raybaud committed
        faces.append(face)
    mesh = pov_define_mesh(mesh, verts, [], faces, "SuperEllipsoid")
Maurice Raybaud's avatar
Maurice Raybaud committed
    if not ob:
        ob = object_utils.object_data_add(context, mesh, operator=None)
        # engine = context.scene.render.engine what for?
Maurice Raybaud's avatar
Maurice Raybaud committed
        ob = context.object
        ob.name = ob.data.name = "PovSuperellipsoid"
Maurice Raybaud's avatar
Maurice Raybaud committed
        ob.pov.object_as = 'SUPERELLIPSOID'
Loading
Loading full blame...