def adjust_hsv(mesh, vcol, h_offset, s_offset, v_offset, colorize): if mesh.use_paint_mask: selected_faces = [face for face in mesh.polygons if face.select] for face in selected_faces: for loop_index in face.loop_indices: c = Color(vcol.data[loop_index].color[:3]) if colorize: c.h = fmod(0.5 + h_offset, 1.0) else: c.h = fmod(1.0 + c.h + h_offset, 1.0) c.s = max(0.0, min(c.s + s_offset, 1.0)) c.v = max(0.0, min(c.v + v_offset, 1.0)) new_color = vcol.data[loop_index].color new_color[:3] = c vcol.data[loop_index].color = new_color else: vertex_mask = True if mesh.use_paint_mask_vertex else False verts = mesh.vertices for loop_index, loop in enumerate(mesh.loops): if not vertex_mask or verts[loop.vertex_index].select: c = Color(vcol.data[loop_index].color[:3]) if colorize: c.h = fmod(0.5 + h_offset, 1.0) else: c.h = fmod(1.0 + c.h + h_offset, 1.0) c.s = max(0.0, min(c.s + s_offset, 1.0)) c.v = max(0.0, min(c.v + v_offset, 1.0)) new_color = vcol.data[loop_index].color new_color[:3] = c vcol.data[loop_index].color = new_color mesh.update()
def to_node_color(color, from_linear=False): """Gets color ready for assigning to Blender nodes. 1. Sets minimal HSV value attribute for rendering 2. Applies pre gamma correction 3. Returns it as tuple of 4 floats RGBA :param color: color to be converted for usage in node :type color: mathutils.Color | collections.Iterable[float] :param from_linear: should color first be converted from linear space? :type from_linear: bool :return: RGBA as tuple of floats :rtype: tuple[float] """ srgb_color = color if from_linear: srgb_color = linear_to_srgb(color) c = Color( srgb_color[:3] ) # copy color so changes won't reflect on original passed color object c = pre_gamma_corrected_col(c) # set minimal value for Blender to use it in rendering if c.v == 0: c.v = 0.000001 # this is the smallest value Blender still uses for rendering return tuple(c) + (1, )
def set_diffuse(node_tree, color): """Set diffuse color to shader. :param node_tree: node tree of current shader :type node_tree: bpy.types.NodeTree :param color: diffuse color :type color: Color or tuple """ hsv_col = Color(color[:3]) # force diffuse color to be rendered so ambient color can be simulated! if hsv_col.v == 0: hsv_col.v = 0.000001 # this is the smallest value Blender still uses for rendering color = tuple(hsv_col) + (1, ) node_tree.nodes[ Glass.DIFF_COL_NODE].outputs['Color'].default_value = color node_tree.nodes[ Glass.OUT_MAT_NODE].material.diffuse_intensity = hsv_col.v * 0.7 # fix emit color representing ambient. # NOTE: because emit works upon diffuse light we need to fake factors if diffuse drops ambient = node_tree.nodes[ Glass.OUT_MAT_NODE].material.scs_props.shader_attribute_add_ambient node_tree.nodes[Glass.OUT_MAT_NODE].material.emit = (ambient / 10) * ( 1 / hsv_col.v)
def hsv_to_rgb(input, val, i_sub=-1): c = Color(input.default_value[:3]) if i_sub == 0: c.h = val elif i_sub == 1: c.s = val elif i_sub == 2: c.v = val elif i_sub < 0: c.hsv = val return [*c[:], 1.0] # Return RGB values
def set_diffuse(node_tree, color): """Set diffuse color to shader. :param node_tree: node tree of current shader :type node_tree: bpy.types.NodeTree :param color: diffuse color :type color: Color or tuple """ hsv_col = Color(color[:3]) # force diffuse color to be rendered so ambient color can be simulated! if hsv_col.v == 0: hsv_col.v = 0.000001 # this is the smallest value Blender still uses for rendering color = tuple(hsv_col) + (1,) node_tree.nodes[UnlitVcolTex.DIFF_COL_NODE].outputs['Color'].default_value = color
def set_diffuse(node_tree, color): """Set diffuse color to shader. :param node_tree: node tree of current shader :type node_tree: bpy.types.NodeTree :param color: diffuse color :type color: Color or tuple """ hsv_col = Color(color[:3]) # force diffuse color to be rendered so ambient color can be simulated! if hsv_col.v == 0: hsv_col.v = 0.000001 # this is the smallest value Blender still uses for rendering color = tuple(hsv_col) + (1, ) node_tree.nodes[ UnlitVcolTex.DIFF_COL_NODE].outputs['Color'].default_value = color
def mouse_op(direction): if G.mode == "Aspect": factor = 1.1 if direction == "down": factor = 1.0 / factor G.hole.worldScale = Vector( (G.hole.worldScale.x * factor, G.hole.worldScale.y * 1.0 / factor, G.hole.worldScale.z) ) elif G.mode == "Scale": factor = 1.1 if direction == "down": factor = 1.0 / factor G.hole.worldScale = G.hole.worldScale * factor elif G.mode == "Rotate": factor = 3.1415926 * 2 / 360 * 10 # last is degrees per click if direction == "down": factor *= -1.0 G.stim.applyRotation([0.0, 0.0, factor]) elif G.mode == "Temporal": factor = 1.3 if direction == "down": factor = 1.0 / factor G.stim.worldScale = G.stim.worldScale * factor elif G.mode == "Color": factor = 1.1 if direction == "down": factor = 1.0 / factor print("sun", G.sun.color) # G.sun.color[0] *= factor # G.sun.color[1] = 0.5 hsv = Color(G.sun.color) hsv.h *= factor hsv.s = 0.5 hsv.v = 1.0 G.sun.color = (255, 0, 0) print(hsv) elif G.mode == "Mask": factor = 3.1415926 * 2 / 360 * 10 # last is degrees per click if direction == "down": factor *= -1.0 G.hole.applyRotation([0.0, 0.0, factor]) elif G.mode == GK.ZKEY: G.stim.worldPosition = [0, 0, G.stim.worldPosition[2]] G.hole.worldPosition = [0, 0, G.hole.worldPosition[2]]
def to_node_color(color): """Gets color ready for assigning to Blender nodes. 1. Sets minimal HSV value attribute for rendering 2. Applies pre gamma correction 3. Returns it as tuple of 4 floats RGBA :param color: color to be converted for usage in node :type color: mathutils.Color | collections.Iterable[float] :return: RGBA as tuple of floats :rtype: tuple[float] """ c = Color(color[:3]) # copy color so changes won't reflect on original passed color object c = pre_gamma_corrected_col(c) # set minimal value for Blender to use it in rendering if c.v == 0: c.v = 0.000001 # this is the smallest value Blender still uses for rendering return tuple(c) + (1,)
def set_diffuse(node_tree, color): """Set diffuse color to shader. :param node_tree: node tree of current shader :type node_tree: bpy.types.NodeTree :param color: diffuse color :type color: Color or tuple """ hsv_col = Color(color[:3]) # force diffuse color to be rendered so ambient color can be simulated! if hsv_col.v == 0: hsv_col.v = 0.000001 # this is the smallest value Blender still uses for rendering color = tuple(hsv_col) + (1,) node_tree.nodes[Dif.DIFF_COL_NODE].outputs['Color'].default_value = color node_tree.nodes[Dif.OUT_MAT_NODE].material.diffuse_intensity = hsv_col.v * 0.7 # fix emit color representing ambient. # NOTE: because emit works upon diffuse light we need to fake factors if diffuse drops ambient = node_tree.nodes[Dif.OUT_MAT_NODE].material.scs_props.shader_attribute_add_ambient node_tree.nodes[Dif.OUT_MAT_NODE].material.emit = (ambient / 10) * (1 / hsv_col.v)
def paintVerts(self, context, start_point, end_point, start_color, end_color, circular_gradient=False, use_hue_blend=False): region = context.region rv3d = context.region_data obj = context.active_object mesh = obj.data # Create a new bmesh to work with bm = bmesh.new() bm.from_mesh(mesh) bm.verts.ensure_lookup_table() # List of structures containing 3d vertex and project 2d position of vertex vertex_data = None # Will contain vert, and vert coordinates in 2d view space if mesh.use_paint_mask_vertex: # Face masking not currently supported vertex_data = [(v, view3d_utils.location_3d_to_region_2d( region, rv3d, obj.matrix_world @ v.co)) for v in bm.verts if v.select] else: vertex_data = [(v, view3d_utils.location_3d_to_region_2d( region, rv3d, obj.matrix_world @ v.co)) for v in bm.verts] # Vertex transformation math down_vector = Vector((0, -1, 0)) direction_vector = Vector( (end_point.x - start_point.x, end_point.y - start_point.y, 0)).normalized() rotation = direction_vector.rotation_difference(down_vector) translation_matrix = Matrix.Translation( Vector((-start_point.x, -start_point.y, 0))) inverse_translation_matrix = translation_matrix.inverted() rotation_matrix = rotation.to_matrix().to_4x4() combinedMat = inverse_translation_matrix @ rotation_matrix @ translation_matrix transStart = combinedMat @ start_point.to_4d( ) # Transform drawn line : rotate it to align to horizontal line transEnd = combinedMat @ end_point.to_4d() minY = transStart.y maxY = transEnd.y heightTrans = maxY - minY # Get the height of transformed vector transVector = transEnd - transStart transLen = transVector.length # Calculate hue, saturation and value shift for blending if use_hue_blend: start_color = Color(start_color[:3]) end_color = Color(end_color[:3]) c1_hue = start_color.h c2_hue = end_color.h hue_separation = c2_hue - c1_hue if hue_separation > 0.5: hue_separation = hue_separation - 1 elif hue_separation < -0.5: hue_separation = hue_separation + 1 c1_sat = start_color.s sat_separation = end_color.s - c1_sat c1_val = start_color.v val_separation = end_color.v - c1_val color_layer = bm.loops.layers.color.active for data in vertex_data: vertex = data[0] vertCo4d = Vector((data[1].x, data[1].y, 0)) transVec = combinedMat @ vertCo4d t = 0 if circular_gradient: curVector = transVec.to_4d() - transStart curLen = curVector.length t = abs(max(min(curLen / transLen, 1), 0)) else: t = abs(max(min((transVec.y - minY) / heightTrans, 1), 0)) color = Color((1, 0, 0)) if use_hue_blend: # Hue wraps, and fmod doesn't work with negative values color.h = fmod(1.0 + c1_hue + hue_separation * t, 1.0) color.s = c1_sat + sat_separation * t color.v = c1_val + val_separation * t else: color.r = start_color[0] + (end_color[0] - start_color[0]) * t color.g = start_color[1] + (end_color[1] - start_color[1]) * t color.b = start_color[2] + (end_color[2] - start_color[2]) * t if mesh.use_paint_mask: # Masking by face face_loops = [ loop for loop in vertex.link_loops if loop.face.select ] # Get only loops that belong to selected faces else: # Masking by verts or no masking at all face_loops = [loop for loop in vertex.link_loops ] # Get remaining vert loops for loop in face_loops: new_color = loop[color_layer] new_color[:3] = color loop[color_layer] = new_color bm.to_mesh(mesh) bm.free() bpy.ops.object.mode_set(mode='VERTEX_PAINT')
def execute(self, context): mesh = context.active_object.data random.seed(self.random_seed) bpy.ops.object.mode_set(mode='EDIT', toggle=False) bm = bmesh.from_edit_mesh(mesh) bm.faces.ensure_lookup_table() color_layer = bm.loops.layers.color.active # Find all islands in the mesh mesh_islands = [] selected_faces = ([f for f in bm.faces if f.select]) faces = selected_faces if mesh.use_paint_mask or mesh.use_paint_mask_vertex else bm.faces bpy.ops.mesh.select_all(action="DESELECT") while len(faces) > 0: # Select linked faces to find island faces[0].select_set(True) bpy.ops.mesh.select_linked() mesh_islands.append([f for f in faces if f.select]) # Hide the island and update faces bpy.ops.mesh.hide(unselected=False) faces = [f for f in faces if not f.hide] bpy.ops.mesh.reveal() island_colors = {} # Island face count : Random color pairs # Used for setting hue with order based color assignment separationDiff = 1.0 if len( mesh_islands) == 0 else 1.0 / len(mesh_islands) # If we are in isolate mode, this is used to force greyscale isolate = get_isolated_channel_ids( context.active_object.data.vertex_colors.active) for index, island in enumerate(mesh_islands): color = Color((1, 0, 0)) # (0, 1, 1) HSV # Determine color based on settings if self.merge_similar: face_count = len(island) if face_count in island_colors.keys(): color = island_colors[face_count] else: if isolate is not None: v = random.random() color = Color((v, v, v)) island_colors[face_count] = color else: color.h = random.random( ) if self.randomize_hue else self.base_hue color.s = random.random( ) if self.randomize_saturation else self.base_saturation color.v = random.random( ) if self.randomize_value else self.base_value island_colors[face_count] = color else: if isolate is not None: v = index * separationDiff if self.order_based else random.random( ) color = Color((v, v, v)) else: if self.order_based: color.h = index * separationDiff if self.randomize_hue else self.base_hue color.s = index * separationDiff if self.randomize_saturation else self.base_saturation color.v = index * separationDiff if self.randomize_value else self.base_value else: color.h = random.random( ) if self.randomize_hue else self.base_hue color.s = random.random( ) if self.randomize_saturation else self.base_saturation color.v = random.random( ) if self.randomize_value else self.base_value # Set island face colors for face in island: for loop in face.loops: new_color = loop[color_layer] new_color[:3] = color loop[color_layer] = new_color # Restore selection for f in selected_faces: f.select = True bm.free() bpy.ops.object.mode_set(mode='VERTEX_PAINT', toggle=False) return {'FINISHED'}
def draw_highlights(context): st = context.space_data text = st.text # Nothing to draw. if not text: return selr = sorted((text.current_character, text.select_end_character)) curl = text.current_line substr = curl.body[slice(*selr)] # Nothing to find. if not substr.strip(): return if not prefs.case_sensitive: substr = substr.lower() if len(substr) >= prefs.min_str_len and curl == text.select_end_line: scroll_ofs = scroll_offset_get(st) wunits = wunits_get() lheight = int(1.3 * (int(wunits * st.font_size) // 20)) args = context, st, substr, selr, lheight, wunits pts, scrollpts, offset = coords_get(*args) cw = cwidth_get(st) args = lheight, pts, -offset + scroll_ofs glEnable(GL_BLEND) shader_bind() # Draw scroll highlights. if prefs.show_in_scroll: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) uniform_float("color", tuple(prefs.color_scroll)) to_batch("TRIS", to_scroll(lheight, scrollpts, 2)).draw() # Draw solid background. if prefs.show_background: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) colors = tuple(prefs.color_background) if not prefs.use_overlay: glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_SRC_ALPHA) color = Color(colors[:3]) color.v = max(0, color.v * 0.55) color.s = min(1, color.s * 2) colors = color[:] + (1, ) uniform_float("color", colors) to_batch("TRIS", to_tris(*args)).draw() # Draw frames. if prefs.show_frames: glLineWidth(prefs.frame_thickness) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) uniform_float("color", tuple(prefs.color_line)) to_batch("LINES", to_frames(*args)).draw() # Draw underlines. elif prefs.show_underline: glLineWidth(prefs.line_thickness) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) uniform_float("color", tuple(prefs.color_line)) to_batch("LINES", to_lines(*args)).draw() # Draw highlight text if prefs.use_overlay: y_offset = (wunits * cw) // wunits # correct for fonts blf.size(1, int(st.font_size * (wunits * 0.05)), 72) blf.color(1, *prefs.color_text) for co, _, substring in pts: co.y += y_offset + scroll_ofs blf.position(1, *co, 1) blf.draw(1, substring) glDisable(GL_BLEND)