Python mathutils.Matrix.Scale() Examples
The following are 30
code examples of mathutils.Matrix.Scale().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
mathutils.Matrix
, or try the search function
.
Example #1
Source File: __init__.py From Fluid-Designer with GNU General Public License v3.0 | 6 votes |
def execute(self, context): from . import export_obj from mathutils import Matrix keywords = self.as_keywords(ignore=("axis_forward", "axis_up", "global_scale", "check_existing", "filter_glob", )) global_matrix = (Matrix.Scale(self.global_scale, 4) * axis_conversion(to_forward=self.axis_forward, to_up=self.axis_up, ).to_4x4()) keywords["global_matrix"] = global_matrix return export_obj.save(context, **keywords)
Example #2
Source File: pia.py From BlenderTools with GNU General Public License v2.0 | 6 votes |
def _get_delta_matrix(bone_rest_matrix_scs, parent_bone_rest_matrix_scs, bone_animation_matrix_scs, import_scale): """.""" scale_matrix = Matrix.Scale(import_scale, 4) # NOTE: apply scaling bone rest matrix, because it's subtracted by bone rest matrix inverse loc, rot, sca = bone_rest_matrix_scs.decompose() scale = Matrix.Identity(4) scale[0] = (sca[0], 0, 0, 0) scale[1] = (0, sca[1], 0, 0) scale[2] = (0, 0, sca[2], 0) return (scale_matrix @ scale @ bone_rest_matrix_scs.inverted() @ parent_bone_rest_matrix_scs @ bone_animation_matrix_scs)
Example #3
Source File: model.py From BlenderTools with GNU General Public License v2.0 | 6 votes |
def draw_model_locator(obj, scs_globals): """ Draw Model locator. :param obj: :return: """ import mathutils size = scs_globals.locator_size empty_size = scs_globals.locator_empty_size mat_sca = mathutils.Matrix.Scale(size, 4) mat_orig = obj.matrix_world mat = mat_orig @ mat_sca _primitive.draw_shape_x_axis(mat, empty_size) _primitive.draw_shape_y_axis_neg(mat, empty_size) _primitive.draw_shape_z_axis(mat, empty_size) draw_shape_model_locator(mat, scs_globals) if not obj.scs_props.locator_preview_model_present: draw_model_box(mat_orig, scs_globals)
Example #4
Source File: model.py From BlenderTools with GNU General Public License v2.0 | 6 votes |
def draw_model_box(mat, scs_globals): """ Draw Cube for Model locator. :param mat: :param scs_globals: :return: """ mat1 = mat @ (Matrix.Translation((0.0, 0.0, 0.0)) @ Matrix.Scale(scs_globals.locator_size / 5, 4, (1.0, 0.0, 0.0)) @ Matrix.Scale(scs_globals.locator_size / 5, 4, (0.0, 1.0, 0.0)) @ Matrix.Scale(scs_globals.locator_size / 5, 4, (0.0, 0.0, 1.0))) cube_vertices, cube_faces, cube_wire_lines = _primitive.get_box_data() _primitive.draw_polygon_object(mat1, cube_vertices, cube_faces, scs_globals.locator_coll_face_color, False, True, wire_lines=cube_wire_lines, wire_color=scs_globals.locator_model_wire_color)
Example #5
Source File: pim.py From BlenderTools with GNU General Public License v2.0 | 6 votes |
def _fill_locator_sections(model_locator_list): """ Fills up "Locator" sections. :param model_locator_list: :return: """ locator_sections = [] locator_i = 0 for item in model_locator_list: # print('locator: "%s" - "%s"' % (item.name, str(item.scs_props.locator_model_hookup))) part_section = _SectionData("Locator") loc_name = _name_utils.tokenize_name(item.name) part_section.props.append(("Name", loc_name)) if item.scs_props.locator_model_hookup: part_section.props.append(("Hookup", item.scs_props.locator_model_hookup.split(':', 1)[1].strip())) part_section.props.append(("Index", locator_i)) loc, qua, sca = _convert_utils.get_scs_transformation_components(item.matrix_world) part_section.props.append(("Position", ["&&", loc])) part_section.props.append(("Rotation", ["&&", qua])) part_section.props.append(("Scale", ["&&", sca])) locator_sections.append(part_section) locator_i += 1 return locator_sections
Example #6
Source File: floorplan_types.py From building_tools with MIT License | 6 votes |
def create_random_floorplan(bm, prop): """Create randomly generated building floorplan """ random.seed(prop.seed) scale_x = Matrix.Scale(prop.width / 2, 4, (1, 0, 0)) scale_y = Matrix.Scale(prop.length / 2, 4, (0, 1, 0)) bmesh.ops.create_grid( bm, x_segments=1, y_segments=1, size=1, matrix=scale_x @ scale_y ) amount = prop.extension_amount if prop.random_extension_amount: amount = random.randrange(len(bm.edges) // 3, len(bm.edges)) random_edges = random.sample( list(bm.edges), amount ) median_reference = list(bm.faces).pop().calc_center_median() for edge in random_edges: edge_median = calc_edge_median(edge) middle_edge = subdivide_edge_twice_and_get_middle(bm, edge) random_scale_and_translate(bm, middle_edge) random_extrude(bm, middle_edge, (edge_median - median_reference).normalized())
Example #7
Source File: __init__.py From Fluid-Designer with GNU General Public License v3.0 | 6 votes |
def execute(self, context): from . import export_ply from mathutils import Matrix keywords = self.as_keywords(ignore=("axis_forward", "axis_up", "global_scale", "check_existing", "filter_glob", )) global_matrix = axis_conversion(to_forward=self.axis_forward, to_up=self.axis_up, ).to_4x4() * Matrix.Scale(self.global_scale, 4) keywords["global_matrix"] = global_matrix filepath = self.filepath filepath = bpy.path.ensure_ext(filepath, self.filename_ext) return export_ply.save(self, context, **keywords)
Example #8
Source File: __init__.py From Fluid-Designer with GNU General Public License v3.0 | 6 votes |
def execute(self, context): from mathutils import Matrix if not self.filepath: raise Exception("filepath not set") global_matrix = (Matrix.Scale(self.global_scale, 4) * axis_conversion(to_forward=self.axis_forward, to_up=self.axis_up, ).to_4x4()) keywords = self.as_keywords(ignore=("global_scale", "check_existing", "filter_glob", "ui_tab", )) keywords["global_matrix"] = global_matrix if self.version == 'BIN7400': from . import export_fbx_bin return export_fbx_bin.save(self, context, **keywords) else: from . import export_fbx return export_fbx.save(self, context, **keywords)
Example #9
Source File: __init__.py From Fluid-Designer with GNU General Public License v3.0 | 6 votes |
def execute(self, context): from . import export_x3d from mathutils import Matrix keywords = self.as_keywords(ignore=("axis_forward", "axis_up", "global_scale", "check_existing", "filter_glob", )) global_matrix = axis_conversion(to_forward=self.axis_forward, to_up=self.axis_up, ).to_4x4() * Matrix.Scale(self.global_scale, 4) keywords["global_matrix"] = global_matrix return export_x3d.save(context, **keywords)
Example #10
Source File: import_svg.py From Fluid-Designer with GNU General Public License v3.0 | 6 votes |
def __init__(self, filepath, do_colormanage): """ Initialize SVG loader """ node = xml.dom.minidom.parse(filepath) m = Matrix() m = m * Matrix.Scale(1.0 / 90.0 * 0.3048 / 12.0, 4, Vector((1.0, 0.0, 0.0))) m = m * Matrix.Scale(-1.0 / 90.0 * 0.3048 / 12.0, 4, Vector((0.0, 1.0, 0.0))) rect = (1, 1) self._context = {'defines': {}, 'transform': [], 'rects': [rect], 'rect': rect, 'matrix': m, 'materials': {}, 'styles': [None], 'style': None, 'do_colormanage': do_colormanage} super().__init__(node, self._context)
Example #11
Source File: collider.py From BlenderTools with GNU General Public License v2.0 | 5 votes |
def draw_shape_box(mat, obj_scs_props, scs_globals): """Draw box collider. :param mat: Object matrix 4x4 :type mat: Matrix :param obj_scs_props: SCS Object properties :type obj_scs_props: prop :param scs_globals: global settings :type scs_globals: prop """ if obj_scs_props.locator_collider_centered: shift = 0.0 else: shift = -obj_scs_props.locator_collider_box_y / 2 mat1 = mat @ Matrix.Translation((0.0, shift, 0.0)) @ ( Matrix.Scale(obj_scs_props.locator_collider_box_x, 4, (1.0, 0.0, 0.0)) @ Matrix.Scale(obj_scs_props.locator_collider_box_y, 4, (0.0, 1.0, 0.0)) @ Matrix.Scale(obj_scs_props.locator_collider_box_z, 4, (0.0, 0.0, 1.0))) cube_vertices, cube_faces, cube_wire_lines = _primitive.get_box_data() _primitive.draw_polygon_object(mat1, cube_vertices, cube_faces, scs_globals.locator_coll_face_color, obj_scs_props.locator_collider_faces, obj_scs_props.locator_collider_wires, wire_lines=cube_wire_lines, wire_color=scs_globals.locator_coll_wire_color)
Example #12
Source File: export.py From se-blender with GNU General Public License v2.0 | 5 votes |
def __getitem__(self, key): # makes all attributes available for parameter substitution if not type(key) is str or key.startswith('_'): raise KeyError(key) try: value = getattr(self, key) if value is None or type(value) is _FUNCTION_TYPE: raise KeyError(key) return value except AttributeError: raise KeyError(key) # FWD = 'Z' # UP = 'Y' # MATRIX_NORMAL = axis_conversion(to_forward=FWD, to_up=UP).to_4x4() # MATRIX_SCALE_DOWN = Matrix.Scale(0.2, 4) * MATRIX_NORMAL
Example #13
Source File: utils.py From se-blender with GNU General Public License v2.0 | 5 votes |
def scaleZ(z): return Matrix.Scale(z, 4, 'Z')
Example #14
Source File: utils.py From se-blender with GNU General Public License v2.0 | 5 votes |
def scaleY(y): return Matrix.Scale(y, 4, 'Y')
Example #15
Source File: utils.py From se-blender with GNU General Public License v2.0 | 5 votes |
def scaleX(x): return Matrix.Scale(x, 4, 'X')
Example #16
Source File: light.py From BlendLuxCore with GNU General Public License v3.0 | 5 votes |
def calc_area_light_transformation(light, transform_matrix): scale_x = Matrix.Scale(light.size / 2, 4, (1, 0, 0)) if light.shape in {"RECTANGLE", "ELLIPSE"}: scale_y = Matrix.Scale(light.size_y / 2, 4, (0, 1, 0)) else: # basically scale_x, but for the y axis (note the last tuple argument) scale_y = Matrix.Scale(light.size / 2, 4, (0, 1, 0)) transform_matrix = transform_matrix.copy() transform_matrix @= scale_x transform_matrix @= scale_y return transform_matrix
Example #17
Source File: light.py From BlendLuxCore with GNU General Public License v3.0 | 5 votes |
def _convert_infinite(definitions, light_or_world, scene, transformation=None): assert light_or_world.luxcore.image is not None try: filepath = ImageExporter.export(light_or_world.luxcore.image, light_or_world.luxcore.image_user, scene) except OSError as error: error_context = "Light" if isinstance(light_or_world, bpy.types.Light) else "World" msg = '%s "%s": %s' % (error_context, light_or_world.name, error) LuxCoreErrorLog.add_warning(msg) # Fallback definitions["type"] = "constantinfinite" # Signal that the image is missing definitions["gain"] = [x * light_or_world.luxcore.gain for x in MISSING_IMAGE_COLOR] return definitions["type"] = "infinite" definitions["file"] = filepath definitions["gamma"] = light_or_world.luxcore.gamma definitions["sampleupperhemisphereonly"] = light_or_world.luxcore.sampleupperhemisphereonly if transformation: infinite_fix = Matrix.Scale(1.0, 4) # TODO one axis still not correct infinite_fix[0][0] = -1.0 # mirror the hdri map to match Cycles and old LuxBlend transformation = utils.matrix_to_list(infinite_fix @ transformation.inverted()) definitions["transformation"] = transformation
Example #18
Source File: SuncgLoader.py From BlenderProc with GNU General Public License v3.0 | 5 votes |
def _load_box(self, node, material_adjustments, transform, parent): """ Creates a cube inside blender which follows the specifications of the given node. :param node: The node dict which contains information from house.json.. :param material_adjustments: Adjustments to the materials which were specified inside house.json. :param transform: The transformation that should be applied to the loaded objects. :param parent: The parent object to which the ground should be linked """ bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0)) box = bpy.context.object box.name = "Box#" + node["id"] box.matrix_world = Matrix.Identity(4) # Scale the cube to the required dimensions box.matrix_world @= Matrix.Scale(node["dimensions"][0] / 2, 4, (1.0, 0.0, 0.0)) @ Matrix.Scale(node["dimensions"][1] / 2, 4, (0.0, 1.0, 0.0)) @ Matrix.Scale(node["dimensions"][2] / 2, 4, (0.0, 0.0, 1.0)) # Create UV mapping (beforehand we apply the scaling from the previous step, such that the resulting uv mapping has the correct aspect) bpy.ops.object.transform_apply(scale=True) bpy.ops.object.editmode_toggle() bpy.ops.uv.cube_project() bpy.ops.object.editmode_toggle() # Create an empty material which is filled in the next step mat = bpy.data.materials.new(name="material_0") mat.use_nodes = True box.data.materials.append(mat) self._transform_and_colorize_object(box, material_adjustments, transform, parent) # set class to void box["category_id"] = LabelIdMapping.label_id_map["void"] # Rotate cube to match objects loaded from .obj, has to be done after transformations have been applied box.matrix_world = Matrix.Rotation(math.radians(90), 4, "X") @ box.matrix_world # Set the physics property of all imported boxes self._set_properties(bpy.context.selected_objects)
Example #19
Source File: pic.py From BlenderTools with GNU General Public License v2.0 | 5 votes |
def _make_common_part(item, index, col_type): scs_root = _get_scs_root(item) if not item.scs_props.locator_collider_centered: if item.scs_props.locator_collider_type == 'Box': offset_matrix = (item.matrix_world @ Matrix.Translation((0.0, -item.scs_props.locator_collider_box_y / 2, 0.0)) @ (Matrix.Scale(item.scs_props.locator_collider_box_x, 4, (1.0, 0.0, 0.0)) @ Matrix.Scale(item.scs_props.locator_collider_box_y, 4, (0.0, 1.0, 0.0)) @ Matrix.Scale(item.scs_props.locator_collider_box_z, 4, (0.0, 0.0, 1.0)))) elif item.scs_props.locator_collider_type == 'Sphere': offset_matrix = (item.matrix_world @ Matrix.Translation((0.0, -item.scs_props.locator_collider_dia / 2, 0.0)) @ Matrix.Scale(item.scs_props.locator_collider_dia, 4)) elif item.scs_props.locator_collider_type in ('Capsule', 'Cylinder'): offset_matrix = (item.matrix_world @ Matrix.Translation((0.0, -item.scs_props.locator_collider_len / 2, 0.0)) @ Matrix.Scale(item.scs_props.locator_collider_dia, 4)) else: offset_matrix = item.matrix_world loc, qua, sca = _convert_utils.get_scs_transformation_components(scs_root.matrix_world.inverted() @ offset_matrix) else: loc, qua, sca = _convert_utils.get_scs_transformation_components(scs_root.matrix_world.inverted() @ item.matrix_world) section = _SectionData("Locator") section.props.append(("Name", _name_utils.tokenize_name(item.name))) section.props.append(("Index", index)) section.props.append(("Position", ["&&", loc])) section.props.append(("Rotation", ["&&", qua])) section.props.append(("Alias", "")) section.props.append(("Weight", ["&", (item.scs_props.locator_collider_mass,)])) section.props.append(("Type", col_type)) return section
Example #20
Source File: pis.py From BlenderTools with GNU General Public License v2.0 | 5 votes |
def _fill_bones_sections(scs_root_obj, armature_obj, used_bones, export_scale): """Creates "Bones" section.""" section = _SectionData("Bones") for bone_name in used_bones: bone = armature_obj.data.bones[bone_name] # armature matrix stores transformation of armature object against scs root # and has to be added to all bones as they only armature space transformations armature_mat = scs_root_obj.matrix_world.inverted() @ armature_obj.matrix_world bone_mat = (Matrix.Scale(export_scale, 4) @ _convert_utils.scs_to_blend_matrix().inverted() @ armature_mat @ bone.matrix_local) section.data.append(("__bone__", bone.name, bone.parent, bone_mat.transposed())) return section
Example #21
Source File: convert.py From BlenderTools with GNU General Public License v2.0 | 5 votes |
def change_to_scs_xyz_coordinates(vec, scale): """Transposes location from Blender to SCS game engine. :param vec: Location (or three floats) :type vec: Vector | list | tuple :param scale: Scale :type scale: Vector :return: Transposed location :rtype: tuple of float """ return vec[0] * scale, (vec[2] * -scale), (vec[1] * scale)
Example #22
Source File: convert.py From BlenderTools with GNU General Public License v2.0 | 5 votes |
def convert_location_to_scs(location, offset_matrix=Matrix()): """Takes a vector or list of three floats and returns its coordinates transposed for SCS game engine. \rIf an "offset_matrix" is provided it is used to offset coordinates. :param location: Location (or three floats) :type location: Vector | list | tuple :param offset_matrix: Offset :type offset_matrix: Matrix :return: Transposed location :rtype: Vector """ scs_globals = _get_scs_globals() return Matrix.Scale(scs_globals.export_scale, 4) @ scs_to_blend_matrix().inverted() @ (offset_matrix.inverted() @ location)
Example #23
Source File: collider.py From BlenderTools with GNU General Public License v2.0 | 5 votes |
def draw_shape_sphere(mat, obj_scs_props, scs_globals): """Draw sphere collider. :param mat: Object matrix 4x4 :type mat: Matrix :param obj_scs_props: SCS Object properties :type obj_scs_props: prop :param scs_globals: global settings :type scs_globals: prop """ if obj_scs_props.locator_collider_centered: shift = 0.0 else: shift = -obj_scs_props.locator_collider_dia / 2 mat1 = mat @ Matrix.Translation((0.0, shift, 0.0)) @ Matrix.Scale(obj_scs_props.locator_collider_dia, 4) sphere_vertices, sphere_faces, sphere_wire_lines = _primitive.get_sphere_data() _primitive.draw_polygon_object(mat1, sphere_vertices, sphere_faces, scs_globals.locator_coll_face_color, obj_scs_props.locator_collider_faces, obj_scs_props.locator_collider_wires, wire_lines=sphere_wire_lines, wire_color=scs_globals.locator_coll_wire_color)
Example #24
Source File: __init__.py From Fluid-Designer with GNU General Public License v3.0 | 5 votes |
def execute(self, context): from . import stl_utils from . import blender_utils from mathutils import Matrix paths = [os.path.join(self.directory, name.name) for name in self.files] scene = context.scene # Take into account scene's unit scale, so that 1 inch in Blender gives 1 inch elsewhere! See T42000. global_scale = self.global_scale if scene.unit_settings.system != 'NONE' and self.use_scene_unit: global_scale /= scene.unit_settings.scale_length global_matrix = axis_conversion(from_forward=self.axis_forward, from_up=self.axis_up, ).to_4x4() * Matrix.Scale(global_scale, 4) if not paths: paths.append(self.filepath) if bpy.ops.object.mode_set.poll(): bpy.ops.object.mode_set(mode='OBJECT') if bpy.ops.object.select_all.poll(): bpy.ops.object.select_all(action='DESELECT') for path in paths: objName = bpy.path.display_name(os.path.basename(path)) tris, tri_nors, pts = stl_utils.read_stl(path) tri_nors = tri_nors if self.use_facet_normal else None blender_utils.create_and_link_mesh(objName, tris, tri_nors, pts, global_matrix) return {'FINISHED'}
Example #25
Source File: transform.py From object_alignment with GNU General Public License v3.0 | 5 votes |
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.matrix_world.translation-loc), l_mat, r_mat, s_mat.inverted()) mx = mathutils_mult((obj.matrix_world.translation-loc), l_mat, r_mat, s_mat.inverted()) m.transform(Matrix.Translation(mx)) obj.matrix_world.translation = loc
Example #26
Source File: transform.py From object_alignment with GNU General Public License v3.0 | 5 votes |
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
Example #27
Source File: armature.py From BlenderExporter with Apache License 2.0 | 5 votes |
def get_matrix(bpyBone, matrix_world): if bpy.context.scene.world.preserveZUpRight == True : SystemMatrix = Matrix.Scale(1, 4, Vector((0, 0, 1))) else : SystemMatrix = Matrix.Scale(-1, 4, Vector((0, 0, 1))) @ Matrix.Rotation(radians(-90), 4, 'X') if bpyBone.parent: return (SystemMatrix @ matrix_world @ bpyBone.parent.matrix).inverted() @ (SystemMatrix @ matrix_world @ bpyBone.matrix) else: return SystemMatrix @ matrix_world @ bpyBone.matrix # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Example #28
Source File: export_datasmith.py From blender-datasmith-export with GNU General Public License v3.0 | 5 votes |
def exp_mapping(node, exp_list): if node.vector_type == 'NORMAL': mapping_type = 'MAPPING_NORMAL' else: node_input_rot = node.inputs["Rotation"] default_rot = node_input_rot.default_value uses_3d_rot = default_rot.x != 0 or default_rot.y != 0 use_2d_node = not node_input_rot.links and not uses_3d_rot if node.vector_type == 'POINT' or node.vector_type == 'VECTOR': if use_2d_node: mapping_type = 'MAPPING_POINT2D' else: mapping_type = 'MAPPING_POINT3D' elif node.vector_type == 'TEXTURE': if use_2d_node: mapping_type = 'MAPPING_TEX2D' else: mapping_type = 'MAPPING_TEX3D' n = Node("FunctionCall", { "Function": op_custom_functions[mapping_type]}) input_vector = get_expression(node.inputs['Vector'], exp_list) input_location = get_expression(node.inputs['Location'], exp_list) input_rotation = get_expression(node.inputs['Rotation'], exp_list) input_scale = get_expression(node.inputs['Scale'], exp_list) n.push(Node("0", input_vector)) n.push(Node("1", input_location)) n.push(Node("2", input_rotation)) n.push(Node("3", input_scale)) return {"expression": exp_list.push(n)}
Example #29
Source File: export_datasmith.py From blender-datasmith-export with GNU General Public License v3.0 | 5 votes |
def exp_tex_noise(socket, exp_list): # default if socket.name == "Fac" function_path = "/DatasmithBlenderContent/MaterialFunctions/Noise" out_socket = 0 if socket.name == "Color": out_socket = 1 n = Node("FunctionCall", { "Function": function_path}) exp_1 = get_expression(socket.node.inputs['Vector'], exp_list) exp_2 = get_expression(socket.node.inputs['Scale'], exp_list) if exp_1: n.push(Node("0", exp_1)) n.push(Node("1", exp_2)) return { "expression": exp_list.push(n), "OutputIndex":out_socket }
Example #30
Source File: util_geometry.py From building_tools with MIT License | 5 votes |
def plane(bm, width=2, length=2): """ Create a plane in the given bmesh """ sc_x = Matrix.Scale(width, 4, (1, 0, 0)) sc_y = Matrix.Scale(length, 4, (0, 1, 0)) mat = sc_x @ sc_y return bmesh.ops.create_grid(bm, x_segments=1, y_segments=1, size=1, matrix=mat)