Example #1
0
def cone_frustum(b: Point3d, br: float, t: Point3d, tr: float, bmat: MatId,
                 tmat: MatId, smat: MatId) -> Id:
    vec = t - b
    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.
    bm = bmesh.new()
    mat_idx = 0
    if br > 0:
        bmesh.ops.create_circle(bm,
                                cap_ends=True,
                                radius=br,
                                segments=32,
                                matrix=Matrix.Translation(
                                    Vector((0, 0, -depth / 2))),
                                calc_uvs=True)
        mat_idx += 0 if bmat < 0 else 1
    bmesh.ops.create_cone(bm,
                          cap_ends=False,
                          segments=32,
                          diameter1=br,
                          diameter2=tr,
                          depth=depth,
                          calc_uvs=True)
    for f in bm.faces:
        f.smooth = True
    if smat >= 0:
        for f in bm.faces:
            f.material_index = mat_idx
        mat_idx += 1
    if tr > 0:
        bmesh.ops.create_circle(bm,
                                cap_ends=True,
                                radius=tr,
                                segments=32,
                                matrix=Matrix.Translation(
                                    Vector((0, 0, depth / 2))),
                                calc_uvs=True)
        mat_idx += 0 if tmat < 0 else 1
    id, name = new_id()
    obj = mesh_from_bmesh(name, bm)
    obj.rotation_euler = rot.to_euler()
    obj.location = b + trans
    maybe_add_material(obj, bmat)
    maybe_add_material(obj, tmat)
    maybe_add_material(obj, smat)
    current_collection.objects.link(obj)
    return id
Example #2
0
def circle(c: Point3d, v: Vector3d, r: float, mat: MatId) -> Id:
    rot = Vector((0, 0, 1)).rotation_difference(v)  # Rotation from Z axis.
    bm = bmesh.new()
    bmesh.ops.create_circle(bm,
                            cap_ends=True,
                            radius=r,
                            segments=32,
                            calc_uvs=True)
    id, name = new_id()
    obj = mesh_from_bmesh(name, bm)
    obj.rotation_euler = rot.to_euler()
    obj.location = c
    maybe_add_material(obj, mat)
    current_collection.objects.link(obj)
    return id
def pov_cylinder_define(context, op, ob, radius, loc, loc_cap):
    """Pick POV cylinder properties either from creation operator, import, or data update"""
    if op:
        cy_rad = op.cy_rad
        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.data.use_auto_smooth = True
        ob.pov.object_as = "CYLINDER"
        ob.update_tag()  # as prop set via python not updated in depsgraph

    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()
Example #4
0
    def execute(self, context):
        from mathutils import Matrix

        verts = []
        faces = []
        materials = []
        blend_mats = []  # XXX
        pov_mats = []  # XXX
        colors = []
        mat_names = []
        lenverts = None
        lenfaces = None
        suffix = -1
        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  # XXX
        cache = []
        matrixes = {}
        write_matrix = False
        index = None
        value = None
        # file_pov = bpy.path.abspath(self.filepath) # was used for single files

        def mat_search(cache):
            r = g = b = 0.5
            f = t = 0
            color = None
            for item, value in enumerate(cache):
                # if value == 'texture': # add more later
                if value == 'pigment':
                    # Todo: create function for all color models.
                    # instead of current pass statements
                    # distinguish srgb from rgb into blend option
                    if cache[item + 2] in {'rgb', 'srgb'}:
                        pass
                    elif cache[item + 2] in {'rgbf', 'srgbf'}:
                        pass
                    elif cache[item + 2] in {'rgbt', 'srgbt'}:
                        try:
                            r, g, b, t = (
                                float(cache[item + 3]),
                                float(cache[item + 4]),
                                float(cache[item + 5]),
                                float(cache[item + 6]),
                            )
                        except BaseException as e:
                            print(e.__doc__)
                            print('An exception occurred: {}'.format(e))
                            r = g = b = t = float(cache[item + 2])
                        color = (r, g, b, t)

                    elif cache[item + 2] in {'rgbft', 'srgbft'}:
                        pass

                    else:
                        pass

            if colors == [] or (colors != [] and color not in colors):
                colors.append(color)
                name = ob.name + "_mat"
                mat_names.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
                ob.data.materials.append(mat)

            else:
                for i, value in enumerate(colors):
                    if color == value:
                        ob.data.materials.append(bpy.data.materials[mat_names[i]])

        for file in self.files:
            print("Importing file: " + file.name)
            file_pov = self.directory + file.name
            for line in open(file_pov):
                string = line.replace("{", " ")
                string = string.replace("}", " ")
                string = string.replace("<", " ")
                string = string.replace(">", " ")
                string = string.replace(",", " ")
                lw = string.split()
                # lenwords = len(lw) # Not used... why written?
                if lw:
                    if lw[0] == "object":
                        write_matrix = True
                    if write_matrix:
                        if lw[0] not in {"object", "matrix"}:
                            index = lw[0]
                        if lw[0] in {"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
                            write_matrix = False
            for line in open(file_pov):
                S = line.replace("{", " { ")
                S = S.replace("}", " } ")
                S = S.replace(",", " ")
                S = S.replace("<", "")
                S = S.replace(">", " ")
                S = S.replace("=", " = ")
                S = S.replace(";", " ; ")
                S = S.split()
                # lenS = len(S) # Not used... why written?
                for 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 = context.object
                                ob.location = (x0, y0, z0)
                                # ob.scale = (r,r,r)
                                mat_search(cache)
                            except ValueError:
                                pass
                            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)
                            except ValueError:
                                pass
                            cache = []
                            plane_search = False
                    if word == 'box':
                        box_search = True
                        name_search = False
                    if box_search:
                        cache.append(word)
                        if cache[-1] == '}':
                            try:
                                x0 = float(cache[2])
                                y0 = float(cache[3])
                                z0 = float(cache[4])
                                x1 = float(cache[5])
                                y1 = float(cache[6])
                                z1 = float(cache[7])
                                # imported_corner_1=(x0, y0, z0)
                                # imported_corner_2 =(x1, y1, z1)
                                center = ((x0 + x1) / 2, (y0 + y1) / 2, (z0 + z1) / 2)
                                bpy.ops.pov.addbox()
                                ob = context.object
                                ob.location = center
                                mat_search(cache)

                            except ValueError:
                                pass
                            cache = []
                            box_search = False
                    if word == 'cylinder':
                        cylinder_search = True
                        name_search = False
                    if cylinder_search:
                        cache.append(word)
                        if cache[-1] == '}':
                            try:
                                x0 = float(cache[2])
                                y0 = float(cache[3])
                                z0 = float(cache[4])
                                x1 = float(cache[5])
                                y1 = float(cache[6])
                                z1 = float(cache[7])
                                imported_cyl_loc = (x0, y0, z0)
                                imported_cyl_loc_cap = (x1, y1, z1)

                                r = float(cache[8])

                                vec = Vector(imported_cyl_loc_cap) - Vector(imported_cyl_loc)
                                depth = vec.length
                                rot = Vector((0, 0, 1)).rotation_difference(
                                    vec
                                )  # Rotation from Z axis.
                                trans = rot @ Vector(  # XXX Not used, why written?
                                    (0, 0, depth / 2)
                                )  # Such that origin is at center of the base of the cylinder.
                                # center = ((x0 + x1)/2,(y0 + y1)/2,(z0 + z1)/2)
                                scale_z = sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2 + (z1 - z0) ** 2) / 2
                                bpy.ops.pov.addcylinder(
                                    R=r,
                                    imported_cyl_loc=imported_cyl_loc,
                                    imported_cyl_loc_cap=imported_cyl_loc_cap,
                                )
                                ob = context.object
                                ob.location = (x0, y0, z0)
                                ob.rotation_euler = rot.to_euler()
                                ob.scale = (1, 1, scale_z)

                                # scale data rather than obj?
                                # bpy.ops.object.mode_set(mode='EDIT')
                                # bpy.ops.mesh.reveal()
                                # bpy.ops.mesh.select_all(action='SELECT')
                                # bpy.ops.transform.resize(value=(1,1,scale_z), orient_type='LOCAL')
                                # bpy.ops.mesh.hide(unselected=False)
                                # bpy.ops.object.mode_set(mode='OBJECT')

                                mat_search(cache)

                            except ValueError:
                                pass
                            cache = []
                            cylinder_search = False
                    if word == 'sphere':
                        sphere_search = True
                        name_search = False
                    if sphere_search:
                        cache.append(word)
                        if cache[-1] == '}':
                            x = y = z = r = 0
                            try:
                                x = float(cache[2])
                                y = float(cache[3])
                                z = float(cache[4])
                                r = float(cache[5])

                            except ValueError:
                                pass
                            except:
                                x = y = z = float(cache[2])
                                r = float(cache[3])
                            bpy.ops.pov.addsphere(R=r, imported_loc=(x, y, z))
                            ob = context.object
                            ob.location = (x, y, z)
                            ob.scale = (r, r, r)
                            mat_search(cache)
                            cache = []
                            sphere_search = False
                    # -------- End Primitives Import -------- #
                    if word == '#declare':
                        name_search = True
                    if name_search:
                        cache.append(word)
                        if word == 'mesh2':
                            name_search = False
                            if cache[-2] == '=':
                                name = cache[-3]
                            else:
                                suffix += 1
                            cache = []
                        if word in {'texture', ';'}:
                            name_search = False
                            cache = []
                    if word == 'vertex_vectors':
                        verts_search = True
                    if verts_search:
                        cache.append(word)
                        if word == '}':
                            verts_search = False
                            lenverts = cache[2]
                            cache.pop()
                            cache.pop(0)
                            cache.pop(0)
                            cache.pop(0)
                            for j in range(int(lenverts)):
                                x = j * 3
                                y = (j * 3) + 1
                                z = (j * 3) + 2
                                verts.append((float(cache[x]), float(cache[y]), float(cache[z])))
                            cache = []
                    # if word == 'face_indices':
                    # faces_search = True
                    if word == 'texture_list':  # XXX
                        tex_search = True  # XXX
                    if tex_search:  # XXX
                        if (
                            word not in {'texture_list', 'texture', '{', '}', 'face_indices'}
                            and not word.isdigit()
                        ):  # XXX
                            pov_mats.append(word)  # XXX
                    if word == 'face_indices':
                        tex_search = False  # XXX
                        faces_search = True
                    if faces_search:
                        cache.append(word)
                        if word == '}':
                            faces_search = False
                            lenfaces = cache[2]
                            cache.pop()
                            cache.pop(0)
                            cache.pop(0)
                            cache.pop(0)
                            lf = int(lenfaces)
                            var = int(len(cache) / lf)
                            for k in range(lf):
                                if var == 3:
                                    v0 = k * 3
                                    v1 = k * 3 + 1
                                    v2 = k * 3 + 2
                                    faces.append((int(cache[v0]), int(cache[v1]), int(cache[v2])))
                                if var == 4:
                                    v0 = k * 4
                                    v1 = k * 4 + 1
                                    v2 = k * 4 + 2
                                    m = k * 4 + 3
                                    materials.append((int(cache[m])))
                                    faces.append((int(cache[v0]), int(cache[v1]), int(cache[v2])))
                                if var == 6:
                                    v0 = k * 6
                                    v1 = k * 6 + 1
                                    v2 = k * 6 + 2
                                    m0 = k * 6 + 3
                                    m1 = k * 6 + 4
                                    m2 = k * 6 + 5
                                    materials.append(
                                        (int(cache[m0]), int(cache[m1]), int(cache[m2]))
                                    )
                                    faces.append((int(cache[v0]), int(cache[v1]), int(cache[v2])))
                            # mesh = pov_define_mesh(None, verts, [], faces, name, hide_geometry=False)
                            # ob = object_utils.object_data_add(context, mesh, operator=None)

                            me = bpy.data.meshes.new(name)  # XXX
                            ob = bpy.data.objects.new(name, me)  # XXX
                            bpy.context.collection.objects.link(ob)  # XXX
                            me.from_pydata(verts, [], faces)  # XXX

                            for mat in bpy.data.materials:  # XXX
                                blend_mats.append(mat.name)  # XXX
                            for m_name in pov_mats:  # XXX
                                if m_name not in blend_mats:  # XXX
                                    bpy.data.materials.new(m_name)  # XXX
                                    mat_search(cache)
                                ob.data.materials.append(
                                    bpy.data.materials[m_name]
                                )  # XXX
                            if materials:  # XXX
                                for idx, val in enumerate(materials):  # XXX
                                    try:  # XXX
                                        ob.data.polygons[
                                            idx
                                        ].material_index = val  # XXX
                                    except TypeError:  # XXX
                                        ob.data.polygons[idx].material_index = int(
                                            val[0]
                                        )  # XXX

                            blend_mats = []  # XXX
                            pov_mats = []  # XXX
                            materials = []  # XXX
                            cache = []
                            name_search = True
                            if name in matrixes and not self.import_at_cur:
                                global_matrix = Matrix.Rotation(pi / 2.0, 4, 'X')
                                ob = bpy.context.object
                                matrix = ob.matrix_world
                                v = matrixes[name]
                                matrix[0][0] = v[0]
                                matrix[1][0] = v[1]
                                matrix[2][0] = v[2]
                                matrix[0][1] = v[3]
                                matrix[1][1] = v[4]
                                matrix[2][1] = v[5]
                                matrix[0][2] = v[6]
                                matrix[1][2] = v[7]
                                matrix[2][2] = v[8]
                                matrix[0][3] = v[9]
                                matrix[1][3] = v[10]
                                matrix[2][3] = v[11]
                                matrix = global_matrix * ob.matrix_world
                                ob.matrix_world = matrix
                            verts = []
                            faces = []

                    # if word == 'pigment':
                    # try:
                    # #all indices have been incremented once to fit a bad test file
                    # r,g,b,t = float(S[2]),float(S[3]),float(S[4]),float(S[5])
                    # color = (r,g,b,t)

                    # except IndexError:
                    # #all indices have been incremented once to fit alternate test file
                    # r,g,b,t = float(S[3]),float(S[4]),float(S[5]),float(S[6])
                    # color = (r,g,b,t)
                    # except UnboundLocalError:
                    # # In case no transmit is specified ? put it to 0
                    # r,g,b,t = float(S[2]),float(S[3]),float(S[4],0)
                    # color = (r,g,b,t)

                    # except ValueError:
                    # color = (0.8,0.8,0.8,0)
                    # pass

                    # if colors == [] or (colors != [] and color not in colors):
                    # colors.append(color)
                    # name = ob.name+"_mat"
                    # mat_names.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
                    # ob.data.materials.append(mat)
                    # print (colors)
                    # else:
                    # for m in range(len(colors)):
                    # if color == colors[m]:
                    # ob.data.materials.append(bpy.data.materials[mat_names[m]])

        # To keep Avogadro Camera angle:
        # for obj in bpy.context.view_layer.objects:
        # if obj.type == "CAMERA":
        # track = obj.constraints.new(type = "TRACK_TO")
        # track.target = ob
        # track.track_axis ="TRACK_NEGATIVE_Z"
        # track.up_axis = "UP_Y"
        # obj.location = (0,0,0)
        return {'FINISHED'}
    def calc_angles_from_normal(self, co, normal):
        ''' Use normal to calculate rotation angles '''
        rot = Vector((0, 0, 1)).rotation_difference(normal)
        eul = rot.to_euler()

        return [a for a in eul]
    def calc_angles_from_normal(self, co, normal):
        ''' Use normal to calculate rotation angles '''
        rot = Vector((0, 0, 1)).rotation_difference(normal)
        eul = rot.to_euler()

        return [a for a in eul]