示例#1
0
    def test_create_materials(self):
        not_a_mesh = Object()
        mesh_with_0_mat = Object()
        mesh_with_1_mat = Object()
        mesh_with_2_mat = Object()

        mesh_with_0_mat.data = Mesh()
        mesh_with_1_mat.data = Mesh()
        mesh_with_2_mat.data = Mesh()

        material = Material()
        material.name = "material"
        material.diffuse_color = [1.0, 1.0, 1.0, 1.0]

        mesh_with_0_mat.data.materials = []
        mesh_with_1_mat.data.materials = [material] * 1
        mesh_with_2_mat.data.materials = [material] * 2

        exporter = Exporter()
        exporter.create_materials(
            [not_a_mesh, mesh_with_0_mat, mesh_with_1_mat, mesh_with_2_mat])

        self.assertEqual(len(exporter.names), 4)
        self.assertEqual(len(exporter.materials), 4)
        self.assertEqual(exporter.materials[0],
                         exporter.get_default_material())
        self.assertEqual(not_a_mesh.data in exporter.materials_by_mesh, False)
        self.assertEqual(len(exporter.materials_by_mesh[mesh_with_0_mat.data]),
                         0)
        self.assertEqual(len(exporter.materials_by_mesh[mesh_with_1_mat.data]),
                         1)
        self.assertEqual(len(exporter.materials_by_mesh[mesh_with_2_mat.data]),
                         2)
示例#2
0
def apply_modifiers(obj: Object, calc_undeformed: bool = False):
    """ apply modifiers to object """
    m = obj.to_mesh(bpy.context.depsgraph if b280() else bpy.context.scene,
                    True,
                    calc_undeformed=calc_undeformed)
    obj.modifiers.clear()
    obj.data = m
示例#3
0
    def test_create_vector_groups(self):
        not_a_mesh = Object()
        mesh = Object()

        mesh.data = Mesh()

        vertex = MeshVertex()
        mesh.data.vertices = [vertex] * 3

        n_x = MeshLoop()
        n_x.normal = [1.0, 0.0, 0.0]
        n_y = MeshLoop()
        n_y.normal = [0.0, 1.0, 0.0]
        n_z = MeshLoop()
        n_z.normal = [0.0, 0.0, 1.0]
        mesh.data.loops = [n_x, n_y, n_z]

        tri = MeshLoopTriangle()
        tri.vertices = [0, 1, 2]
        tri.loops = [0, 1, 2]
        mesh.data.loop_triangles = [tri]

        exporter = Exporter()
        exporter.create_vector_groups([not_a_mesh, mesh])

        self.assertEqual(len(exporter.tri_nv_groups),
                         len(exporter.vtx_nv_groups))
        self.assertEqual(not_a_mesh.data in exporter.normal_indices_by_mesh,
                         False)
        self.assertEqual(exporter.normal_indices_by_mesh[mesh.data], [0, 1, 2])
        self.assertEqual(exporter.tri_nv_groups[0].tri_nv_num, 1)
        self.assertEqual(exporter.tri_nv_groups[1].tri_nv_num, 1)
        self.assertEqual(exporter.vtx_nv_groups[0].vtx_nv_num, 1)
        self.assertEqual(exporter.vtx_nv_groups[1].vtx_nv_num, 3)
def add_driver_to_vars(obj: bpy_types.Object, prop_to, variables, expression: str = None) -> None:
    """
    Add a driver to obj's prop_to property

    Each var must be under the form : (var_name, id_type, _id, prop_from)"""
    if obj:
        if type(prop_to) is tuple:
            driver = obj.driver_add(prop_to[0], prop_to[1]).driver
        else:
            driver = obj.driver_add(prop_to).driver
            ModifierManager.drivers.append((obj, prop_to))
        for i, var_prop in enumerate(variables):
            try:
                var = driver.variables[i]
            except IndexError:
                var = driver.variables.new()
            var.name = var_prop[0]
            var.type = 'SINGLE_PROP'

            target = var.targets[0]
            target.id_type = var_prop[1]
            target.id = var_prop[2]
            target.data_path = str(var_prop[3])

        if expression:
            driver.expression = expression
        else:
            driver.expression = variables[0][0]
示例#5
0
def safeUnlink(obj: Object, protect: bool = True):
    scn = bpy.context.scene
    try:
        unlink_object(obj)
    except RuntimeError:
        pass
    obj.protected = protect
    obj.use_fake_user = True
示例#6
0
def safeLink(obj: Object, protect: bool = False, collections=None):
    collections = collections or [scn.collection]
    for coll in collections:
        try:
            coll.objects.link(obj)
        except RuntimeError:
            continue
    obj.protected = protect
    obj.use_fake_user = False
示例#7
0
def safe_unlink(obj: Object, protect: bool = True):
    # unlink object from scene
    try:
        unlink_object(obj, all=True)
    except RuntimeError:
        pass
    # prevent object data from being tossed on Blender exit
    obj.use_fake_user = True
    # protect object from deletion (useful in Bricker addon)
    if hasattr(obj, "protected"):
        obj.protected = protect
示例#8
0
def safeUnlink(obj:Object, protect:bool=True):
    # unlink object from scene
    try:
        unlink_object(obj)
    except RuntimeError:
        pass
    # prevent object data from being tossed on Blender exit
    obj.use_fake_user = True
    # protect object from deletion (useful in Bricker addon)
    if hasattr(obj, "protected"):
        obj.protected = protect
示例#9
0
def safeLink(obj:Object, protect:bool=False, collections=None):
    # link object to scene
    try:
        link_object(obj)
    except RuntimeError:
        pass
    # remove fake user from object data
    obj.use_fake_user = False
    # protect object from deletion (useful in Bricker addon)
    if hasattr(obj, "protected"):
        obj.protected = protect
示例#10
0
def safe_link(obj: Object, protect: bool = False, collections=None):
    # link object to scene
    try:
        link_object(obj)
    except RuntimeError:
        pass
    # remove fake user from object data
    obj.use_fake_user = False
    # protect object from deletion (useful in Bricker addon)
    if hasattr(obj, "protected"):
        obj.protected = protect
示例#11
0
def safeLink(obj:Object, protect:bool=False, collections=None):
    # link object to target collections (scene collection by default)
    collections = collections or [bpy.context.scene.collection]
    for coll in collections:
        try:
            coll.objects.link(obj)
        except RuntimeError:
            continue
    # remove fake user from object data
    obj.use_fake_user = False
    # protect object from deletion (useful in Bricker addon)
    if hasattr(obj, "protected"):
        obj.protected = protect
示例#12
0
def safe_link(obj: Object, protect: bool = False, collections=[]):
    # link object to target collections (scene collection by default)
    collections = collections or [bpy.context.scene.collection]
    for coll in collections:
        try:
            coll.objects.link(obj)
        except RuntimeError:
            continue
    # remove fake user from object data
    obj.use_fake_user = False
    # protect object from deletion (useful in Bricker addon)
    if hasattr(obj, "protected"):
        obj.protected = protect
示例#13
0
def apply_transform(obj:Object, location:bool=True, rotation:bool=True, scale:bool=True):
    loc, rot, scale = obj.matrix_world.decompose()
    obj.matrix_world = Matrix.Identity(4)
    m = obj.data
    s_mat_x = Matrix.Scale(scale.x, 4, Vector((1, 0, 0)))
    s_mat_y = Matrix.Scale(scale.y, 4, Vector((0, 1, 0)))
    s_mat_z = Matrix.Scale(scale.z, 4, Vector((0, 0, 1)))
    if scale:    m.transform(s_mat_x * s_mat_y * s_mat_z)
    else:        obj.scale = scale
    if rotation: m.transform(rot.to_matrix().to_4x4())
    else:        obj.rotation_euler = rot.to_euler()
    if location: m.transform(Matrix.Translation(loc))
    else:        obj.location = loc
示例#14
0
    def test_create_shapes(self):
        obj = Object()

        mesh = Mesh()
        mesh.name = "mesh"
        obj.data = mesh

        mat_red = Material()
        mat_red.name = "red"
        mat_red.diffuse_color = [1.0, 0.0, 0.0, 1.0]

        mesh.materials = [mat_red]

        vertex = MeshVertex()
        vertex.co = [0.0, 0.0, 0.0]

        mesh.vertices = [vertex] * 3

        uv_loop = MeshUVLoop()
        uv_loop.uv = [0.5, 0.5]

        uv_loop_layer = MeshUVLoopLayer()
        uv_loop_layer.data = [uv_loop] * 3
        mesh.uv_layers = [uv_loop_layer]

        loop = MeshLoop()
        loop.normal = [1.0, 2.0, 3.0]
        mesh.loops = [loop] * 3

        tri_red = MeshLoopTriangle()
        tri_red.vertices = [0, 1, 2]
        tri_red.loops = [0, 1, 2]
        tri_red.material_index = 0

        mesh.loop_triangles = [tri_red]

        exporter = Exporter()
        exporter.create_materials([obj])
        exporter.create_vertex_groups([obj])
        exporter.create_vector_groups([obj])
        exporter.create_st_groups([obj])
        exporter.create_tri_groups([obj])
        exporter.create_parts([obj])
        exporter.create_shapes([obj])

        self.assertEqual(exporter.shapes[0].shape_tri_link,
                         exporter.tri_groups[0].this_tri_group_index)
        self.assertEqual(exporter.shapes[0].shape_mat_link,
                         exporter.get_default_material().this_mat_index)
        self.assertEqual(exporter.shapes[0].shape_part_num, 1)
        self.assertEqual(exporter.shape_by_mesh[mesh], exporter.shapes[0])
示例#15
0
def apply_transform(obj:Object, location:bool=True, rotation:bool=True, scale:bool=True):
    """ apply object transformation to mesh """
    loc, rot, scale = obj.matrix_world.decompose()
    obj.matrix_world = Matrix.Identity(4)
    m = obj.data
    s_mat_x = Matrix.Scale(scale.x, 4, Vector((1, 0, 0)))
    s_mat_y = Matrix.Scale(scale.y, 4, Vector((0, 1, 0)))
    s_mat_z = Matrix.Scale(scale.z, 4, Vector((0, 0, 1)))
    if scale:    m.transform(mathutils_mult(s_mat_x, s_mat_y, s_mat_z))
    else:        obj.scale = scale
    if rotation: m.transform(rot.to_matrix().to_4x4())
    else:        obj.rotation_euler = rot.to_euler()
    if location: m.transform(Matrix.Translation(loc))
    else:        obj.location = loc
示例#16
0
def copyAnimationData(source:Object, target:Object):
    """ copy animation data from one object to another """
    if source.animation_data is None:
        return

    ad = source.animation_data

    properties = [p.identifier for p in ad.bl_rna.properties if not p.is_readonly]

    if target.animation_data is None:
        target.animation_data_create()
    ad2 = target.animation_data

    for prop in properties:
        setattr(ad2, prop, getattr(ad, prop))
示例#17
0
def copyAnimationData(source:Object, target:Object):
    """ copy animation data from one object to another """
    if source.animation_data is None:
        return

    ad = source.animation_data

    properties = [p.identifier for p in ad.bl_rna.properties if not p.is_readonly]

    if target.animation_data is None:
        target.animation_data_create()
    ad2 = target.animation_data

    for prop in properties:
        setattr(ad2, prop, getattr(ad, prop))
示例#18
0
def cast_rays(obj_eval: Object,
              point: Vector,
              direction: Vector,
              mini_dist: float,
              round_type: str = "CEILING",
              edge_len: int = 0):
    """
    obj_eval   -- source object to test intersections for
    point      -- starting point for ray casting
    direction  -- cast ray in this direction
    mini_dist  -- Vector with miniscule amount to add after intersection
    round_type -- round final intersection location Vector with this type
    edge_len   -- distance to test for intersections
    """
    # initialize variables
    first_direction = False
    first_intersection = None
    next_intersection_loc = None
    last_intersection = None
    edge_intersects = False
    edge_len2 = round(edge_len + 0.000001, 6)
    starting_point = point
    intersections = 0
    # cast rays until no more rays to cast
    while True:
        _, location, normal, index = obj_eval.ray_cast(
            starting_point, direction)  #distance=edge_len*1.00000000001)
        if index == -1: break
        if intersections == 0:
            first_direction = direction.dot(normal)
        if edge_len != 0:
            dist = (location - point).length
            # get first and last intersection (used when getting materials of nearest (first or last intersected) face)
            if dist <= edge_len2:
                if intersections == 0:
                    edge_intersects = True
                    first_intersection = {
                        "idx": index,
                        "dist": dist,
                        "loc": location,
                        "normal": normal
                    }
                last_intersection = {
                    "idx": index,
                    "dist": edge_len - dist,
                    "loc": location,
                    "normal": normal
                }

            # set next_intersection_loc
            if next_intersection_loc is None:
                next_intersection_loc = location.copy()
        intersections += 1
        location = vec_round(location, precision=6, round_type=round_type)
        starting_point = location + mini_dist

    if edge_len != 0:
        return intersections, first_direction, first_intersection, next_intersection_loc, last_intersection, edge_intersects
    else:
        return intersections, first_direction
示例#19
0
def castRays(obj: Object,
             point: Vector,
             direction: Vector,
             miniDist: float,
             roundType: str = "CEILING",
             edgeLen: int = 0):
    """
    obj       -- source object to test intersections for
    point     -- origin point for ray casting
    direction -- cast ray in this direction
    miniDist  -- Vector with miniscule amount to add after intersection
    roundType -- round final intersection location Vector with this type
    edgeLen   -- distance to test for intersections
    """
    # initialize variables
    firstDirection = False
    firstIntersection = None
    nextIntersection = None
    lastIntersection = None
    edgeIntersects = False
    edgeLen2 = edgeLen * 1.00001
    orig = point
    intersections = 0
    # cast rays until no more rays to cast
    while True:
        _, location, normal, index = obj.ray_cast(
            orig, direction)  #distance=edgeLen*1.00000000001)
        if index == -1: break
        if intersections == 0:
            firstDirection = direction.dot(normal)
        if edgeLen != 0:
            dist = (location - point).length
            # get first and last intersection (used when getting materials of nearest (first or last intersected) face)
            if dist <= edgeLen2:
                if intersections == 0:
                    edgeIntersects = True
                    firstIntersection = {
                        "idx": index,
                        "dist": dist,
                        "loc": location,
                        "normal": normal
                    }
                lastIntersection = {
                    "idx": index,
                    "dist": edgeLen - dist,
                    "loc": location,
                    "normal": normal
                }

            # set nextIntersection
            if nextIntersection is None:
                nextIntersection = location.copy()
        intersections += 1
        location = VectorRound(location, 5, roundType=roundType)
        orig = location + miniDist

    if edgeLen != 0:
        return intersections, firstDirection, firstIntersection, nextIntersection, lastIntersection, edgeIntersects
    else:
        return intersections, firstDirection
示例#20
0
    def position_bone_in_animation_frame(
            self,
            armature_obj: Object,
            animation_frame_armature_bone_model: 'BlenderPoseModeAnimationFrameModelNode'):
        pose = armature_obj.pose  # type: Pose
        complementary_pose_bone = pose.bones.get(animation_frame_armature_bone_model.bone_name)  # type: PoseBone
        complementary_pose_bone.rotation_mode = 'QUATERNION'

        if animation_frame_armature_bone_model.bone_name != "ROOT_CHANNEL":
            loc = Matrix.Translation(Vector((
                animation_frame_armature_bone_model.position.x,
                animation_frame_armature_bone_model.position.y,
                animation_frame_armature_bone_model.position.z)))
            rot = Quaternion(Vector((
                animation_frame_armature_bone_model.rotation.w,
                animation_frame_armature_bone_model.rotation.x,
                animation_frame_armature_bone_model.rotation.y,
                animation_frame_armature_bone_model.rotation.z)),
                ).to_matrix().to_4x4()
            scale = Matrix()
            scale[0][0] = animation_frame_armature_bone_model.scale.x
            scale[1][1] = animation_frame_armature_bone_model.scale.y
            scale[2][2] = animation_frame_armature_bone_model.scale.z
            world_mat = loc @ rot @ scale
            complementary_pose_bone.matrix = armature_obj.convert_space(
                pose_bone=complementary_pose_bone,
                matrix=world_mat,
                from_space='WORLD',
                to_space='POSE')
示例#21
0
def create(name: str, location: Vector, template: Object, collection: Collection) \
        -> bpy.types.Object:
    obj = template.copy()
    obj.name = name
    obj.location = location
    collection.objects.link(obj)
    return obj
示例#22
0
def ob_copy_to_faces(ob: Object) -> None:
    mats = mesh.face_pos()

    if mats:
        ob.matrix_world = mats.pop()
        collection = bpy.context.collection
        space_data = bpy.context.space_data
        use_local_view = bool(space_data.local_view)

        for mat in mats:
            ob_copy = ob.copy()
            collection.objects.link(ob_copy)
            ob_copy.matrix_world = mat
            ob_copy.select_set(True)

            if use_local_view:
                ob_copy.local_view_set(space_data, True)
示例#23
0
def duplicate(obj:Object, linked:bool=False, link_to_scene:bool=False):
    """ efficient duplication of objects """
    copy = obj.copy()
    if not linked and copy.data:
        copy.data = copy.data.copy()
    copy.hide = False
    if link_to_scene:
        bpy.context.scene.objects.link(copy)
    return copy
示例#24
0
def duplicate(obj: Object, linked: bool = False, link_to_scene: bool = False):
    """ efficient duplication of objects """
    copy = obj.copy()
    if not linked and copy.data:
        copy.data = copy.data.copy()
    unhide(copy, render=False)
    if link_to_scene:
        link_object(copy)
    return copy
示例#25
0
def duplicate(obj:Object, linked:bool=False, link_to_scene:bool=False):
    """ efficient duplication of objects """
    copy = obj.copy()
    if not linked and copy.data:
        copy.data = copy.data.copy()
    unhide(copy, render=False)
    if link_to_scene:
        link_object(copy)
    return copy
示例#26
0
def est_curve_length(ob: Object) -> float:
    if ob.modifiers:

        # Reset curve
        # ---------------------------

        settings = {
            "bevel_object": None,
            "bevel_depth": 0.0,
            "extrude": 0.0,
        }

        for k, v in settings.items():
            x = getattr(ob.data, k)
            setattr(ob.data, k, v)
            settings[k] = x

        # Calculate length
        # ---------------------------

        depsgraph = bpy.context.evaluated_depsgraph_get()
        ob_eval = ob.evaluated_get(depsgraph)
        me = ob_eval.to_mesh()
        me.transform(ob.matrix_world)

        bm = bmesh.new()
        bm.from_mesh(me)

        ob_eval.to_mesh_clear()

        length = 0.0

        for edge in bm.edges:
            length += edge.calc_length()

        bm.free()

        # Restore curve
        # ---------------------------

        for k, v in settings.items():
            setattr(ob.data, k, v)

    else:

        curve = ob.data.copy()
        curve.transform(ob.matrix_world)

        length = 0.0

        for spline in curve.splines:
            length += spline.calc_length()

        bpy.data.curves.remove(curve)

    return length
示例#27
0
    def test_create_textures(self):
        image = Image()
        image.filepath = "//test/image/path.png"
        image.library = "//test/image/library"

        node = ShaderNodeTexImage()
        node.image = image

        material = Material()
        material.name = "material"
        material.diffuse_color = [1.0, 1.0, 1.0, 1.0]
        material.use_nodes = True
        material.node_tree = NodeTree()
        material.node_tree.nodes = [node]

        mesh = Mesh()
        mesh.materials = [material]

        obj = Object()
        obj.data = mesh

        bpy.path.abspath = Mock(return_value=image.filepath)
        bpy.path.display_name_from_filepath = Mock(return_value="texture")

        reader = Mock()
        reader.read = Mock(return_value=[12, 34, [[0x05, 0x06], [0x07, 0x08]]])
        png.Reader = Mock(return_value=reader)

        exporter = Exporter()
        exporter.create_textures([obj])

        bpy.path.abspath.assert_called_once_with(
            "//test/image/path.png", library="//test/image/library")
        bpy.path.display_name_from_filepath.assert_called_once_with(
            "//test/image/path.png")
        png.Reader.assert_called_once_with("//test/image/path.png")
        reader.read.assert_called_once()

        self.assertEqual(exporter.names[0].node_name, "texture.tex")
        self.assertEqual(exporter.tex_images[0].tex_img_data, [5, 6, 7, 8])
        self.assertEqual(exporter.textures[0].tex_img_width, 12)
        self.assertEqual(exporter.textures[0].tex_img_height, 34)
示例#28
0
def apply_transform(obj:Object, location:bool=True, rotation:bool=True, scale:bool=True):
    """ apply object transformation to mesh """
    loc, rot, scl = obj.matrix_world.decompose()
    obj.matrix_world = Matrix.Identity(4)
    m = obj.data
    s_mat_x = Matrix.Scale(scl.x, 4, Vector((1, 0, 0)))
    s_mat_y = Matrix.Scale(scl.y, 4, Vector((0, 1, 0)))
    s_mat_z = Matrix.Scale(scl.z, 4, Vector((0, 0, 1)))
    if scale:
        m.transform(mathutils_mult(s_mat_x, s_mat_y, s_mat_z))
    else:
        obj.scale = scl
    if rotation:
        m.transform(rot.to_matrix().to_4x4())
    else:
        obj.rotation_euler = rot.to_euler()
    if location:
        m.transform(Matrix.Translation(loc))
    else:
        obj.location = loc
示例#29
0
    def test_create_vertex_groups(self):
        not_a_mesh = Object()
        mesh = Object()

        mesh.data = Mesh()
        mesh.data.name = "mesh"

        vertex = MeshVertex()
        vertex.co = [0.0, 0.0, 0.0]

        mesh.data.vertices = [vertex] * 10

        exporter = Exporter()
        exporter.create_vertex_groups([not_a_mesh, mesh])

        self.assertEqual(len(exporter.names), 1)
        self.assertEqual(len(exporter.vtx_groups), 1)
        self.assertEqual(not_a_mesh.data in exporter.vtx_group_by_mesh, False)
        self.assertEqual(exporter.vtx_group_by_mesh[mesh.data],
                         exporter.vtx_groups[0])
示例#30
0
def new_mesh_from_object(obj: Object):
    unlink_later = False
    depsgraph = bpy.context.evaluated_depsgraph_get()
    # link the object if it's not in the scene, because otherwise the evaluated data may be outdated (e.g. after file is reopened)
    if obj.name not in bpy.context.scene.objects:
        link_object(obj)
        depsgraph_update()
        unlink_later = True
    obj_eval = obj.evaluated_get(depsgraph)
    if unlink_later:
        unlink_object(obj)
    return bpy.data.meshes.new_from_object(obj_eval)
示例#31
0
def setObjOrigin(obj: Object, loc: Vector):
    """ set object origin """
    l, r, s = obj.matrix_world.decompose()
    l_mat = Matrix.Translation(l)
    r_mat = r.to_matrix().to_4x4()
    s_mat_x = Matrix.Scale(s.x, 4, Vector((1, 0, 0)))
    s_mat_y = Matrix.Scale(s.y, 4, Vector((0, 1, 0)))
    s_mat_z = Matrix.Scale(s.z, 4, Vector((0, 0, 1)))
    s_mat = mathutils_mult(s_mat_x, s_mat_y, s_mat_z)
    m = obj.data
    mx = mathutils_mult((obj.location - loc), l_mat, r_mat, s_mat.inverted())
    m.transform(Matrix.Translation(mx))
    obj.location = loc
示例#32
0
def apply_transform(obj: Object):
    """ efficiently apply object transformation """
    # select(obj, active=True, only=True)
    # bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
    loc, rot, scale = obj.matrix_world.decompose()
    obj.matrix_world = Matrix.Identity(4)
    m = obj.data
    s_mat_x = Matrix.Scale(scale.x, 4, Vector((1, 0, 0)))
    s_mat_y = Matrix.Scale(scale.y, 4, Vector((0, 1, 0)))
    s_mat_z = Matrix.Scale(scale.z, 4, Vector((0, 0, 1)))
    m.transform(s_mat_x * s_mat_y * s_mat_z)
    m.transform(rot.to_matrix().to_4x4())
    m.transform(Matrix.Translation(loc))
示例#33
0
    def test_create_tri_groups(self):
        not_a_mesh = Object()
        mesh = Object()

        mesh.data = Mesh()
        mesh.data.name = "mesh"

        vertex = MeshVertex()
        vertex.co = [0.0, 0.0, 0.0]

        mesh.data.vertices = [vertex] * 3

        uv_loop = MeshUVLoop()
        uv_loop.uv = [0.5, 0.5]

        uv_loop_layer = MeshUVLoopLayer()
        uv_loop_layer.data = [uv_loop] * 3
        mesh.data.uv_layers = [uv_loop_layer]

        loop = MeshLoop()
        loop.normal = [1.0, 2.0, 3.0]
        mesh.data.loops = [loop] * 3

        tri = MeshLoopTriangle()
        tri.vertices = [0, 1, 2]
        tri.loops = [0, 1, 2]
        mesh.data.loop_triangles = [tri]

        exporter = Exporter()
        exporter.create_vertex_groups([not_a_mesh, mesh])
        exporter.create_vector_groups([not_a_mesh, mesh])
        exporter.create_st_groups([not_a_mesh, mesh])
        exporter.create_tri_groups([not_a_mesh, mesh])

        self.assertEqual(len(exporter.tri_groups), 1)
        self.assertEqual(not_a_mesh.data in exporter.tri_group_by_mesh, False)
        self.assertEqual(exporter.tri_group_by_mesh[mesh.data],
                         exporter.tri_groups[0])
示例#34
0
def ob_copy_and_parent(ob: Object, parents: Iterable[Object]) -> None:
    is_orig = True
    space_data = bpy.context.space_data
    use_local_view = bool(space_data.local_view)

    for parent in parents:
        if is_orig:
            ob_copy = ob
            is_orig = False
        else:
            ob_copy = ob.copy()

        for coll in parent.users_collection:
            coll.objects.link(ob_copy)

        if use_local_view:
            ob_copy.local_view_set(space_data, True)

        ob_copy.select_set(True)
        ob.location = parent.location
        ob.rotation_euler = parent.rotation_euler
        ob.parent = parent
        ob.matrix_parent_inverse = parent.matrix_basis.inverted()
示例#35
0
def _create_dstr(ob: Object, curve: Object, sizes: list, con_add=True) -> list[tuple[Constraint, float, float]]:
    space_data = bpy.context.space_data
    use_local_view = bool(space_data.local_view)
    ob_colls = ob.users_collection
    child_colls = [(child, child.users_collection) for child in ob.children]

    obs = []
    app = obs.append

    for is_last, size in iterutils.spot_last(_flatten(sizes)):

        if is_last:
            ob_copy = ob
        else:
            ob_copy = ob.copy()

            for coll in ob_colls:
                coll.objects.link(ob_copy)

            if use_local_view:
                ob_copy.local_view_set(space_data, True)

            for child, colls in child_colls:
                child_copy = child.copy()
                for coll in colls:
                    coll.objects.link(child_copy)
                child_copy.parent = ob_copy
                child_copy.matrix_parent_inverse = child.matrix_parent_inverse

        if con_add:
            con = ob_copy.constraints.new("FOLLOW_PATH")
            con.target = curve
            con.use_curve_follow = True
            con.forward_axis = "FORWARD_X"
        else:
            for con in ob_copy.constraints:
                if con.type == "FOLLOW_PATH":
                    break

        scaling = size / ob_copy.dimensions.y

        if not _eq(scaling, 1.0):
            ob_copy.scale *= scaling

        app((con, None, size))

    return obs
示例#36
0
def generate_uv_map_materials(use_existing_materials: str, uv_image_path: str,
                              model_name: str, capmodel: Object) -> [str, str]:
    uv_material_name: str = model_name + '_material'
    if uv_material_name not in data.materials or not use_existing_materials:
        # Overwrite material if not using existing ones!
        if uv_material_name in data.materials:
            printw(
                'Existing material named "%s" is overwritten, you may require the "use existing materials" option'
                % uv_material_name)
            data.materials.remove(data.materials[uv_material_name])
        mat = data.materials.new(name=uv_material_name)
        mat.use_nodes = True
        mat_nodes = mat.node_tree.nodes
        mat_edges = mat.node_tree.links

        # Get BSDF shader node
        bsdfNode: ShaderNodeBsdfPrincipled = mat_nodes['Principled BSDF']

        # Add coordinate and image nodes
        coordsNode: ShaderNodeTexCoord = mat_nodes.new('ShaderNodeTexCoord')
        imgNode: ShaderNodeTexImage = mat_nodes.new('ShaderNodeTexImage')

        # Position the new nodes relative to the old ones
        node_horizontal_margin_offset: Vector = Vector((300.0, 0.0))
        imgNode.location = bsdfNode.location - node_horizontal_margin_offset
        coordsNode.location = imgNode.location - node_horizontal_margin_offset

        # Add appropriate edges
        mat_edges.new(coordsNode.outputs['UV'], imgNode.inputs['Vector'])
        mat_edges.new(imgNode.outputs['Color'], bsdfNode.inputs['Base Color'])
    else:
        bpy_internal_uv_image_name: str = basename(uv_image_path)
        imgNode = get_only(
            [
                n for n in data.materials[uv_material_name].node_tree.nodes
                if n.type == 'TEX_IMAGE' and n.image is not None
                and n.image.name is not None
                and n.image.name.endswith(bpy_internal_uv_image_name)
            ],
            'No image node for "%s" found in material "%s" when trying to use existing materials for uv'
            % (bpy_internal_uv_image_name, uv_material_name),
            'Multiple image nodes for "%s" were found in material "%s" when trying to use existing materials for uv'
            % (bpy_internal_uv_image_name, uv_material_name))

    capmodel.active_material = data.materials[uv_material_name]

    return (imgNode, uv_material_name)
示例#37
0
 def _children_to_fds(self, context) -> "list":
     """Export children in FDS notation."""
     # Init
     bodies = list()
     # Materials
     bodies.append("! --- Boundary conditions (from Blender Materials)\n\n")
     mas = [ma for ma in bpy.data.materials]
     mas.sort(key=lambda k: k.name)  # Alphabetic order by element name
     for ma in mas:
         body = ma.to_fds(context)
         if body:
             bodies.append(body)
     bodies.append("\n")
     # Objects
     bodies.append("! --- Geometric entities (from Blender Objects)\n\n")
     bodies.extend(Object._children_to_fds(self=None, context=context))  # Call objects without a parent
     bodies.append("\n")
     # Return
     return bodies
示例#38
0
def hide(obj:Object, viewport:bool=True, render:bool=True):
    if not obj.hide_viewport and viewport:
        obj.hide_viewport = True
    if not obj.hide_render and render:
        obj.hide_render = True
示例#39
0
def unhide(obj:Object, viewport:bool=True, render:bool=True):
    if obj.hide_viewport and viewport:
        obj.hide_viewport = False
    if obj.hide_render and render:
        obj.hide_render = False
示例#40
0
def apply_modifiers(obj:Object, settings:str="PREVIEW"):
    """ apply modifiers to object """
    m = obj.to_mesh(bpy.context.scene, True, "PREVIEW")
    obj.modifiers.clear()
    obj.data = m