def SVGTransformScale(params): """ scale SVG transform command """ sx = float(params[0]) sy = float(params[1]) if len(params) > 1 else sx m = Matrix() m = m * m.Scale(sx, 4, Vector((1.0, 0.0, 0.0))) m = m * m.Scale(sy, 4, Vector((0.0, 1.0, 0.0))) return m
def Run(): scene = bpy.context.scene oldActive = scene.objects.active for ob in bpy.data.objects: if ob.type != 'ARMATURE': continue if not ob.select: continue scene.objects.active = ob bpy.ops.object.mode_set(mode='POSE') if OriginBone in ob.data.bones: poseBone = ob.pose.bones[OriginBone] mat = ob.matrix_world * poseBone.matrix loc, rot, scale = mat.decompose() loc.x = 0 loc.y = 0 loc.z = 0 locMat = Matrix.Translation(loc) rotMat = rot.to_matrix().to_4x4() scaleMat = Matrix.Scale(scale[0], 4, (1, 0, 0)) * Matrix.Scale( scale[1], 4, (0, 1, 0)) * Matrix.Scale(scale[2], 4, (0, 0, 1)) poseBone.matrix = locMat * rotMat * scaleMat scene.objects.active = oldActive
def execute(self, context): keywords = self.as_keywords(ignore=("axis_forward", "axis_up", "use_selection", "global_scale", "check_existing", "filter_glob", "use_scene_unit", "use_mesh_modifiers", "batch_mode" )) scene = context.scene Shell = bpy.data.objects.get('Final Splint') #Check for CORK created Shell if not Shell: Shell = bpy.data.objects.get('Splint Shell') if not Shell: self.report({'ERROR'}, 'You have not created your splint yet') return {'CANCEL'} #TODO, maybe give option to export the sweep surface or convex surface data_seq = [Shell] # 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 self.batch_mode == 'OFF': faces = itertools.chain.from_iterable( blender_utils.faces_from_mesh(ob, global_matrix, self.use_mesh_modifiers) for ob in data_seq) stl_utils.write_stl(faces=faces, **keywords) elif self.batch_mode == 'OBJECT': prefix = os.path.splitext(self.filepath)[0] keywords_temp = keywords.copy() for ob in data_seq: faces = blender_utils.faces_from_mesh(ob, global_matrix, self.use_mesh_modifiers) keywords_temp["filepath"] = prefix + bpy.path.clean_name(ob.name) + ".stl" stl_utils.write_stl(faces=faces, **keywords_temp) return {'FINISHED'}
def vec_roll_to_mat3(vec, roll): target = Vector((0, 1, 0)) nor = vec.normalized() axis = target.cross(nor) if axis.dot(axis) > 0.000001: axis.normalize() theta = target.angle(nor) bMatrix = Matrix.Rotation(theta, 3, axis) else: updown = 1 if target.dot(nor) > 0 else -1 bMatrix = Matrix.Scale(updown, 3) rMatrix = Matrix.Rotation(roll, 3, nor) mat = rMatrix * bMatrix return mat
def __init__(self, filepath): """ Initialize SVG loader """ node = xml.dom.minidom.parse(filepath) m = Matrix() m = m * m.Scale(1.0 / 90.0, 4, Vector((1.0, 0.0, 0.0))) m = m * m.Scale(-1.0 / 90.0, 4, Vector((0.0, 1.0, 0.0))) rect = (1, 1) self._context = { 'defines': {}, 'transform': [], 'rects': [rect], 'rect': rect, 'matrix': m, 'materials': {} } super().__init__(node, self._context)
def execute(self, context): fnames = [f.name for f in self.files] if len(fnames) == 0 or not os.path.isfile(os.path.join(self.directory,fnames[0])): self.report({'ERROR'}, 'No file is selected for import') return {'FINISHED'} matrix = axis_conversion(from_forward=self.axis_forward, from_up=self.axis_up) if self.flip_x_axis: matrix = Matrix.Scale(-1, 3, (1.0, 0.0, 0.0)) * matrix conv = RipConversion() conv.matrix = matrix conv.flip_winding = self.flip_winding conv.use_normals = self.use_normals conv.use_weights = self.use_weights conv.filter_unused_attrs = self.filter_unused_attrs conv.filter_unused_textures = self.filter_unused_textures conv.normal_max_int = self.normal_int conv.normal_scale = list(map(self.get_normal_scale, range(3))) conv.uv_max_int = self.uv_int conv.uv_scale = list(map(self.get_uv_scale, range(2))) if self.detect_duplicates: conv.dedup = DuplicateTracker() conv.dedup.hash_missing_textures = not self.notex_duplicates if self.cross_duplicates: conv.dedup.init_duplicate_tables() conv.filter_duplicates = self.skip_duplicates if self.override_attrs: table = {} for tag, prop in self.override_props: vals = getattr(self, prop).split(',') nums = map(int, filter(lambda s: re.fullmatch(r'^\d+$',s), vals)) table[tag] = list(nums) conv.attr_override_table = table riplog = RipLogInfo() if self.use_shaders else None for file in sorted(fnames): rf = RipFile(os.path.join(self.directory, file), riplog) rf.parse_file() if self.use_shaders: rf.parse_shaders() if self.skip_untextured and not rf.has_textures(): continue conv.convert_object(rf, context.scene, file) return {'FINISHED'}
def export(path: str, ob, opts): convert_to_mesh = False if convert_to_mesh: try: data = ob.to_mesh(bpy.context.depsgraph, apply_modifiers=True) except RuntimeError: return {'CANCELLED'} else: data = ob.data.copy() if hasattr(data, 'transform'): global_matrix = (Matrix.Scale(1, 4) @ axis_conversion( to_forward="-Z", to_up="Y").to_4x4()) data.transform(global_matrix) geo = None if isinstance(data, bpy.types.Mesh): me = data geo = export_mesh(path, me) bpy.data.meshes.remove(me) elif isinstance(data, bpy.types.Curve): cu = data geo = export_curve(path, cu) bpy.data.curves.remove(cu) # elif isinstance(data, bpy.types.GreasePencil): # gp = data # geo = export_grease_pencil(path, gp) # bpy.data.grease_pencil.remove(gp) else: print('Unsurpported object type:', data.__class__) # FIXME: Find more static way db = eval(repr(data).split('[')[0]) db.remove(data) return False if not geo: return False if not geo.save(path): return False return True
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
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)
def _create_constraint_on_bone(self, bone): is_first_constraint = not bone.editboneconstraint.constraints.values() if is_first_constraint: initial_matrix = bone.matrix.copy() @ Matrix.Scale(bone.length, 4) bone.editboneconstraint.initial_matrix = flatten_matrix( initial_matrix) constraint = bone.editboneconstraint.constraints.add() constraint.name = self.type constraint.type = self.type constraint.head_tail = 0.0 constraint.influence = 1.0 return constraint
def random_scale_and_rotation(obj, normal, NM_SCN, self_data): loc, rot, scale = obj.matrix_world.decompose() loc = Matrix.Translation(loc) rot = rot.to_euler().to_matrix().to_4x4() rot_add = Euler(Vector((0, 0, math.radians(self_data.rotate_angle)))) rot_add = rot_add.to_matrix().to_4x4() if NM_SCN.use_random_scale: new_scale = uniform(NM_SCN.random_scale_from, NM_SCN.random_scale_to) scale = Matrix.Scale(new_scale, 4) else: scale = Matrix.Scale(self_data.scale_model, 4) # apply rotation by normal if checked "align_by_normal" if NM_SCN.align_by_normal: rot_by_normal = normal.rotation_difference(Vector((0, 0, 1))) rot_by_normal.invert() rot_by_normal = rot_by_normal.to_euler().to_matrix().to_4x4() rot = rot_by_normal @ rot_add else: rot = Euler((0, 0, 0)).to_matrix().to_4x4() rot = rot @ rot_add if NM_SCN.use_random_rotation: x_angle = math.radians(uniform(0, NM_SCN.random_rotation_x)) y_angle = math.radians(uniform(0, NM_SCN.random_rotation_y)) z_angle = math.radians(uniform(0, NM_SCN.random_rotation_z)) rot_rand = Euler(Vector( (x_angle, y_angle, z_angle))).to_matrix().to_4x4() rot = rot @ rot_rand mat_w = loc @ rot @ scale obj.matrix_world = mat_w
def fill_bar(bm, face, prop): """Create horizontal and vertical bars along a face""" if prop.bar_count_x + prop.bar_count_y == 0: return xyz = local_xyz(face) face_center = face.calc_center_median() width, height = calc_face_dimensions(face) # XXX bar width should not exceed window size min_dimension = min( [width / max(prop.bar_count_x, 1), height / max(prop.bar_count_y, 1)]) prop.bar_width = min(prop.bar_width, min_dimension) # -- transform vars transform_space = Matrix.Rotation( -VEC_UP.angle(xyz[1]), 4, xyz[0]) @ Matrix.Translation(-face_center) # -- horizontal depth = face.normal * prop.bar_depth offset = height / (prop.bar_count_x + 1) for i in range(prop.bar_count_x): item_off = Vector((0, 0, -height / 2 + (i + 1) * offset)) transform = Matrix.Translation(depth + item_off) @ Matrix.Scale( prop.bar_width / height, 4, VEC_UP) create_bar_from_face(bm, face, transform, transform_space, -depth) # -- vertical eps = 0.015 offset = width / (prop.bar_count_y + 1) depth = face.normal * (prop.bar_depth - eps) for i in range(prop.bar_count_y): item_off = xyz[0] * (-width / 2 + ((i + 1) * offset)) transform = Matrix.Translation(depth + item_off) @ Matrix.Scale( prop.bar_width / width, 4, xyz[0]) create_bar_from_face(bm, face, transform, transform_space, -depth, True)
def _fill_piece_sections(convex_coll_locators, export_scale): """Fills up "Piece" sections for convex colliders.""" len_vertices = 0 len_faces = 0 piece_sections = [] index = 0 for item in convex_coll_locators: stream_cnt = 0 verts = item.scs_props.get("coll_convex_verts", 0) faces = item.scs_props.get("coll_convex_faces", 0) if verts: stream_cnt += 1 len_vertices += len(verts) len_faces += len(faces) section = _SectionData("Piece") section.props.append(("Index", index)) section.props.append(("Material", 0)) section.props.append(("VertexCount", len(verts))) section.props.append(("TriangleCount", len(faces))) section.props.append(("StreamCount", stream_cnt)) section.props.append(("", "")) # VERTICES if verts: vector_verts = [] for vert in verts: # scs_position = Matrix.Scale(scs_globals.export_scale, 4) * io_utils.scs_to_blend_matrix().inverted() * mat_world * position ## # POSITION scs_position = Matrix.Scale( export_scale, 4) * _convert_utils.scs_to_blend_matrix( ).inverted() * Vector(vert) # POSITION vector_verts.append(Vector(scs_position)) section.sections.append( _pix_container.make_stream_section(vector_verts, "_POSITION", ())) # FACES (TRIANGLES) if faces: # FACE FLIPPING flipped_faces = _mesh_utils.flip_faceverts(faces) section.sections.append( _pix_container.make_triangle_stream(flipped_faces)) index += 1 piece_sections.append(section) return len_vertices, len_faces, piece_sections
def create_locator(PDX_locator, PDX_bone_dict): # create locator and link to the scene new_loc = bpy.data.objects.new(PDX_locator.name, None) new_loc.empty_draw_type = 'PLAIN_AXES' new_loc.empty_draw_size = 0.25 new_loc.show_axis = False bpy.context.scene.objects.link(new_loc) # check for a parent relationship parent = getattr(PDX_locator, 'pa', None) parent_Xform = Matrix() if parent is not None: # parent the locator to a bone in the armature rig = get_rig_from_bone_name(parent[0]) if rig: new_loc.parent = rig new_loc.parent_bone = parent[0] new_loc.parent_type = 'BONE' new_loc.matrix_world = Matrix() # reset transform after parenting # then determine the locators transform transform = PDX_bone_dict[parent[0]] # note we transpose the matrix on creation parent_Xform = Matrix( ((transform[0], transform[3], transform[6], transform[9]), (transform[1], transform[4], transform[7], transform[10]), (transform[2], transform[5], transform[8], transform[11]), (0.0, 0.0, 0.0, 1.0))) # compose transform parts _scale = Matrix.Scale(1, 4) _rotation = (Quaternion( (PDX_locator.q[3], PDX_locator.q[0], PDX_locator.q[1], PDX_locator.q[2])).to_matrix().to_4x4()) _translation = Matrix.Translation(PDX_locator.p) loc_matrix = _translation * _rotation * _scale # apply parent transform (must be multiplied in transposed form, then re-transposed before being applied) final_matrix = (loc_matrix.transposed() * parent_Xform.inverted_safe().transposed()).transposed() new_loc.matrix_world = swap_coord_space( final_matrix) # convert to Blender space new_loc.rotation_mode = 'XYZ' bpy.context.scene.update()
def import_animations(animations,scale = 0.03048, format_filter = {}): scene = bpy.context.scene target = bpy.context.object # just random lazy inspection stuff bpy.debug_anim = animations if target.type != "ARMATURE": raise "Not an armature" if not target.animation_data: target.animation_data_create() bpy.ops.object.mode_set(mode="POSE") print(format_filter) for anim in animations: if len(format_filter) > 0 and len(animations) > 1 and anim.ext not in format_filter: continue action = bpy.data.actions.new(anim.name) target.animation_data.action = action action.use_fake_user = True scene.frame_start = 0 scene.frame_end = len(anim.frames) - 1 pose_bones = [] for node in anim.nodes: pose_bones.append(target.pose.bones[NODE_NAME_PREFIX + node.name]) for f in range(len(anim.frames)): bpy.context.scene.frame_set(f) for n in range(len(anim.frames[f])): frame = anim.frames[f][n] bone = pose_bones[n] T = Matrix.Translation(Vector((frame.pos_x, frame.pos_y, frame.pos_z))* scale) R = Quaternion((frame.rot_w, frame.rot_i, frame.rot_j, frame.rot_k)).inverted().to_matrix().to_4x4() S = Matrix.Scale(frame.scale ,4,(1,1,1)) M = T @ R @ S if not bone.parent: bone.matrix = M else: P = bone.parent.matrix bone.matrix = P @ M bone.keyframe_insert(data_path="location", index=-1) bone.keyframe_insert(data_path="rotation_quaternion", index=-1) scene.frame_set(0) bpy.ops.object.mode_set(mode="OBJECT")
def save_md3(settings): from mathutils import Euler, Matrix, Vector from math import radians starttime = time.clock() # start timer fullpath = splitext(settings.savepath)[0] modelname = basename(fullpath) logname = modelname + ".log" logfpath = fullpath + ".log" if settings.name == "": settings.name = modelname dumpall = settings.dumpall if settings.logtype == "append": log = open(logfpath,"a") elif settings.logtype == "overwrite": log = open(logfpath,"w") elif settings.logtype == "blender": log = bpy.data.texts.new(logname) log.clear() else: log = None ref_frame = settings.refframe if settings.refframe == -1: ref_frame = bpy.context.scene.frame_current message(log, "###################### BEGIN ######################") model = BlenderModelManager(settings.gzdoom, ref_frame) # Set up fix transformation matrix model.fix_transform *= Matrix.Scale(settings.scale, 4) model.fix_transform *= Matrix.Translation(Vector(( settings.offsetx, settings.offsety, settings.offsetz))) rotation_fix = Euler() rotation_fix.z = radians(90) model.fix_transform *= rotation_fix.to_matrix().to_4x4() model.md3.name = settings.name # Add objects to model manager if len(bpy.context.selected_objects) == 0: message(log, "Select an object to export!") else: # If multiple objects are selected, they are joined together for bobject in bpy.context.selected_objects: if bobject.type == 'MESH': model.add_mesh(bobject) elif bobject.type == 'EMPTY': model.add_tag(bobject) model.setup_frames() model.md3.GetSize() print_md3(log, model.md3, dumpall) model.save(settings.savepath) endtime = time.clock() - starttime message(log, "Export took {:.3f} seconds".format(endtime))
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)
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())
def output_camera(scene, node): x_res = (scene.render.resolution_x * scene.render.resolution_percentage) / 100 y_res = (scene.render.resolution_y * scene.render.resolution_percentage) / 100 etree.SubElement(node, 'camera', attrib={ 'width': str(int(x_res)), 'height': str(int(y_res))}) cam_matrix = scene.camera.matrix_world * Matrix.Scale(-1, 4, (0,0,1)) trans = etree.SubElement(node, 'transform', attrib={ 'matrix': matrix_to_str(cam_matrix) }) etree.SubElement(trans, 'camera', attrib={ 'type': 'perspective', 'fov': str((bpy.context.scene.camera.data.angle ) / math.pi * 180) })
def get_nitro_model(export_settings): global model, settings, global_matrix settings = export_settings global_matrix = ( Matrix.Scale(settings['magnification'], 4) @ axis_conversion( to_forward='-Z', to_up='Y', ).to_4x4()) model = NitroModel() model.collect() return model
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 = (0, 0) self._context = {'defines': {}, 'transform': [], 'rects': [rect], 'rect': rect, 'matrix': m, 'materials': {}, 'styles': [None], 'style': None, 'do_colormanage': do_colormanage} super().__init__(node, self._context)
def _load_box(node: Dict[str, Any], material_adjustments: List[Dict[str, str]], transform: Matrix, parent: Entity, label_mapping: LabelIdMapping) -> List[MeshObject]: """ 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 :return: The list of loaded mesh objects. """ box = create_primitive("CUBE") box.set_name("Box#" + node["id"]) # Scale the cube to the required dimensions local2world_mat = 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)) box.set_local2world_mat(local2world_mat) 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 box.new_material("material_0") SuncgLoader._transform_and_colorize_object(box, material_adjustments, transform, parent) # set class to void box.set_cp("category_id", label_mapping.id_from_label("void")) # Rotate cube to match objects loaded from .obj, has to be done after transformations have been applied box.set_local2world_mat( Matrix.Rotation(math.radians(90), 4, "X") @ Matrix( box.get_local2world_mat())) return [box]
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)
def get_matrix(self, tangent, scale_x, scale_y): x = Vector((1.0, 0.0, 0.0)) y = Vector((0.0, 1.0, 0.0)) z = Vector((0.0, 0.0, 1.0)) if self.orient_axis_idx == 0: ax1, ax2, ax3 = x, y, z elif self.orient_axis_idx == 1: ax1, ax2, ax3 = y, x, z else: ax1, ax2, ax3 = z, x, y scale_matrix = Matrix.Scale(1, 4, ax1) @ Matrix.Scale(scale_x, 4, ax2) @ Matrix.Scale(scale_y, 4, ax3) if self.algorithm == 'householder': rot = autorotate_householder(ax1, tangent).inverted() elif self.algorithm == 'track': rot = autorotate_track(self.orient_axis, tangent, self.up_axis) elif self.algorithm == 'diff': rot = autorotate_diff(tangent, ax1) else: raise Exception("Unsupported algorithm") return rot @ scale_matrix
def heatmap_barplot(grid, h=4, width=10, bar_scale=0.9, num_colors=10, colormap=cm.summer, bevel_width=0.015, logarithmic=False): """Create 3D barplot from heatmap grid""" # Logarithmic scale if logarithmic: grid = np.log(grid + 1) # Find maximum value z_max = np.max(grid) n, m = grid.shape bar_width = bar_scale * width / max(n, m) # List of bmesh elements for each color group bmList = [bmesh.new() for i in range(num_colors)] # Iterate over grid for i in range(n): for j in range(m): x, y, z = i / (n - 1), j / (m - 1), grid[i][j] if z > 0.001: bar_height = ((h - bar_width) * z / z_max) + bar_width t = 1 - np.exp(-(z / z_max)/0.2) k = min(int(num_colors*t), num_colors - 1) bm = bmList[k] T = Matrix.Translation(( width*(x - 0.5), width*(y - 0.5), bar_height / 2)) S = Matrix.Scale(bar_height / bar_width, 4, (0, 0, 1)) bmesh.ops.create_cube(bm, size=bar_width, matrix=T*S) objList = [] for i, bm in enumerate(bmList): # Create object obj = utils.bmesh_to_object(bm) # Create material with colormap color = colormap(i / num_colors) mat = utils.simple_material(color[:3]) obj.data.materials.append(mat) objList.append(obj) # Add bevel modifier bevel = obj.modifiers.new('Bevel', 'BEVEL') bevel.width = bevel_width
def build_objects(voxdata): global READ_SURFACES, IMPORT_SCALE, VOXEL_DATA_DIR, VOXEL_DIR_PATH #print('--- create object {} ---'.format(voxdata.volume_name)) #print(' cells: {}'.format(len(voxdata.cells))) # initialize ret = {'volume': None, 'surface': None} # make transform # Z-up and scaling basetrans = Matrix.Rotation(math.pi * 0.5, 4, 'X') * Matrix.Scale( IMPORT_SCALE, 4) # and Volume transform tmpmtrx = voxdata.transform voxtmtrx = Matrix(( (tmpmtrx[0], tmpmtrx[4], tmpmtrx[8], tmpmtrx[12]), (tmpmtrx[1], tmpmtrx[5], tmpmtrx[9], tmpmtrx[13]), (tmpmtrx[2], tmpmtrx[6], tmpmtrx[10], tmpmtrx[14]), (tmpmtrx[3], tmpmtrx[7], tmpmtrx[11], tmpmtrx[15]), )) voxtransform = basetrans * voxtmtrx # Parse data voxspec = VoxDataSpec(voxdata, VOXEL_DIR_PATH) if voxspec.voxel_size == None: # No Volume data return ret # fix file path to relative voxspec.voxel_file_path = "//" + os.path.join(VOXEL_DATA_DIR, voxspec.voxel_file_name) # Create Volume obj = create_voxel_object(voxspec, voxtransform) ret.update(volume=obj) # Create Surface if READ_SURFACES: obj = create_surface_object(voxspec, voxtransform) if obj != None: if ret['volume']: volobj = ret['volume'] obj.matrix_parent_inverse = volobj.parent.matrix_world.inverted( ) obj.parent = volobj.parent ret.update(surface=obj) return ret
def execute(self, context): #Obj export 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 export_obj.save(self, context, **keywords) #Setup export file = open(self.filepath, 'a') file.write("# Part #\n") objects = bpy.data.objects for obj in objects: if obj.type == 'MESH': file.write(obj.name.lower() + '\n') locX = -obj.location.x locY = -obj.location.z locZ = obj.location.y rotX = obj.rotation_euler.x rotY = obj.rotation_euler.z rotZ = -obj.rotation_euler.y file.write(str(round(locX, 2)) + ", ") file.write(str(round(locY, 2)) + ", ") file.write(str(round(locZ, 2)) + "\n") file.write(str(round(rotX, 2)) + ", ") file.write(str(round(rotY, 2)) + ", ") file.write(str(round(rotZ, 2)) + "\n") file.close return {'FINISHED'}
def vec_roll_to_mat3(vec, roll): target = Vector((0, 0.1, 0)) nor = vec.normalized() axis = target.cross(nor) if axis.dot(axis) > 0.0000000001: # this seems to be the problem for some bones, no idea how to fix axis.normalize() theta = target.angle(nor) bMatrix = Matrix.Rotation(theta, 3, axis) else: updown = 1 if target.dot(nor) > 0 else -1 bMatrix = Matrix.Scale(updown, 3) bMatrix[2][2] = 1.0 rMatrix = Matrix.Rotation(roll, 3, nor) mat = rMatrix @ bMatrix return mat
def execute(self, context): self.filepath = bpy.path.ensure_ext(self.filepath, '.xml') from mathutils import Matrix keywords = self.as_keywords(ignore=("axis_forward", "axis_up", "global_scale", "check_existing", "filter_glob")) self.global_matrix = ( Matrix.Scale(self.global_scale, 4) @ axis_conversion( to_forward=self.axis_forward, to_up=self.axis_up).to_4x4()) from . import Exporter e = Exporter(self, context) e.execute() return {'FINISHED'}
def rotate_faces(self, faces, direction, scale_factor, rad_x, rad_y, rad_z): center, vertices = self.calc_center_of_faces(faces) translate = Matrix.Translation(-center) x_loc, y_loc, z_loc = self.local_axes(direction) scale = Matrix.Scale(scale_factor, 4) rot_x = Matrix.Rotation(rad_x, 4, x_loc) rot_y = Matrix.Rotation(rad_y, 4, y_loc) rot_z = Matrix.Rotation(rad_z, 4, z_loc) transform = rot_z @ rot_y @ rot_x @ scale bmesh.ops.transform(self.bmesh_tree, matrix=transform, verts=vertices, space=translate)