def draw(self, context): mat = context.material layout = self.layout layout.active = mat.b4w_collision row = layout.row() row.prop(mat, "b4w_use_ghost", text=_("Ghost")) row = layout.row() row.prop(mat, "b4w_collision_id", text=_("Collision ID")) col = layout.column() col.prop(mat, "b4w_collision_margin", text=_("Margin")) phys = context.material.physics # don't use node material split = layout.split() row = split.row() row.prop(phys, "friction") row.prop(phys, "elasticity", slider=True) col = layout.column() col.prop(mat, "b4w_collision_group", text=_("Collision Group")) col = layout.column() col.prop(mat, "b4w_collision_mask", text=_("Collision Mask"))
def draw(self, context): mat = context.material layout = self.layout layout.active = getattr(mat, "b4w_terrain") icon_size = "NONE" icon_color = "NONE" obj = bpy.context.active_object grass_size = mat.b4w_dynamic_grass_size grass_color = mat.b4w_dynamic_grass_color if grass_size != "": icon_size = "ERROR" if grass_color != "": icon_color = "ERROR" if obj.type == "MESH": if check_vertex_color(obj.data, grass_size): icon_size = "GROUP_VCOL" if check_vertex_color(obj.data, grass_color): icon_color = "GROUP_VCOL" row = layout.row() row.prop(mat, "b4w_dynamic_grass_size", text=_("Grass Size (R)"), icon=icon_size) row = layout.row() row.prop(mat, "b4w_dynamic_grass_color", text=_("Grass Color (RGB)"), icon=icon_color)
def start(cls): if not cls.update_server_existed(): cls.server_status = WAIT_RESPONSE cls.server_process = threading.Thread(target=create_server) cls.server_process.daemon = True try: cls.server_process.start() except BaseException as ex: cls.server_status = MAIN_THREAD_START_EXC cls.server_process = None bpy.ops.b4w.server_message( "INVOKE_DEFAULT", message=get_translate(_("Server starting error: ")) + str(ex) ) cls.wait_loop() if cls.server_status == SUB_THREAD_SERVER_EXC: bpy.ops.b4w.server_message( "INVOKE_DEFAULT", message=get_translate(_("Server starting error: ")) + cls.error_message ) if cls.server_status == SUB_THREAD_OTHER_EXC: bpy.ops.b4w.server_message( "INVOKE_DEFAULT", message=get_translate(_("Could not start the server: ")) + cls.error_message ) cls.panel_redraw()
def draw(self, context): layout = self.layout mat = active_node_mat(context.material) split = layout.split() col = split.column() col.prop(mat, "diffuse_color", text="") sub = col.column() sub.active = (not mat.use_shadeless) sub.prop(mat, "diffuse_intensity", text=_("Intensity")) col = split.column() col.active = (not mat.use_shadeless) col.prop(mat, "diffuse_shader", text="") col = layout.column() col.active = (not mat.use_shadeless) if mat.diffuse_shader == 'OREN_NAYAR': col.prop(mat, "roughness") elif mat.diffuse_shader == 'MINNAERT': col.prop(mat, "darkness") elif mat.diffuse_shader == 'TOON': row = col.row() row.prop(mat, "diffuse_toon_size", text=_("Size")) row.prop(mat, "diffuse_toon_smooth", text=_("Smooth")) elif mat.diffuse_shader == 'FRESNEL': row = col.row() row.prop(mat, "diffuse_fresnel", text=_("Fresnel")) row.prop(mat, "diffuse_fresnel_factor", text=_("Factor"))
def draw(self, context): obj = context.object b4w_obj_tags = obj.b4w_object_tags layout = self.layout layout.active = getattr(obj, "b4w_enable_object_tags") col = layout.column() row = col.row() row.prop(b4w_obj_tags, "title", text=_("Title")) row = col.row() row.prop(b4w_obj_tags, "category", text=_("Category")) row = col.row() if b4w_obj_tags.desc_source == "TEXT": icon = "NONE" else: icon = "ERROR" for text in bpy.data.texts: if text.name == b4w_obj_tags.description: icon = "TEXT" break row.prop(b4w_obj_tags, "description", icon=icon) row = col.row() row.label(text=_("Description Source:")) row.prop(b4w_obj_tags, "desc_source", expand=True, text=_("Source"))
def draw(self, context): layout = self.layout is_started = bool(server.B4WLocalServer.server_process) is_waiting_for_shutdown = server.B4WLocalServer.is_waiting_for_shutdown() if is_started: layout.label(text = _("Development server is running.")) elif is_waiting_for_shutdown: layout.label(text = _("Stopping server...")) else: layout.label(text = _("Development server is off.")) if is_started: layout.operator("b4w.stop_server", text=p_("Stop Server", "Operator"), icon="PAUSE") elif not is_waiting_for_shutdown: layout.operator("b4w.start_server", text=p_("Start Server", "Operator"), icon="PLAY") if addon_prefs.has_valid_sdk_path(): if is_started: layout.operator("b4w.open_sdk", text=p_("SDK Index", "Operator"), icon="URL") layout.operator("b4w.open_proj_manager", text=p_("Project Manager", "Operator"), icon="URL") layout.operator("b4w.preview", text=p_("Fast Preview", "Operator"), icon_value=render_engine.custom_icons["b4w_icon"].icon_id) else: row = layout.row() row.label(text = _("Project Manager is unavailable for standalone Blend4Web add-on.")) row = layout.row() row.label(text = _("Remove standalone Blend4Web add-on (if installed) and install Blend4Web SDK."))
def draw(self, context): layout = self.layout psys = context.particle_system pset = particle_get_settings(context) layout.enabled = particle_panel_enabled(context, psys) split = layout.split() col = split.column() col.label(text=_("Emitter Geometry:")) col.prop(pset, "normal_factor") if pset.type == "HAIR": sub = col.column(align=True) sub.prop(pset, "tangent_factor") sub.prop(pset, "tangent_phase", slider=True) col = split.column() col.label(text=_("Emitter Object:")) col.prop(pset, "object_align_factor", text="") layout.label(text=_("Other:")) split = layout.split() if pset.type == "HAIR": col = split.column() if pset.emit_from == 'PARTICLE': col.prop(pset, "particle_factor") else: col.prop(pset, "object_factor", slider=True) col = split.column() col.prop(pset, "factor_random")
def draw(self, context): layout = self.layout base_mat = context.material mat = active_node_mat(base_mat) split = layout.split() col = split.column() col.prop(mat, "b4w_do_not_render", text=_("Do Not Render")) col = split.column() col.active = base_mat.game_settings.alpha_blend not in ["OPAQUE", "CLIP"] col.prop(mat, "b4w_render_above_all", text=_("Render Above All")) row = layout.row() game = context.material.game_settings row.prop(game, "use_backface_culling") row.prop(mat, "use_vertex_color_paint") split = layout.split() col = split.column() col.prop(mat, "b4w_wettable", text=_("Wettable")) col = split.column() col.active = not mat.use_nodes col.prop(mat, "b4w_refractive", text = _("Refractive")) row = col.row() row.active = mat.b4w_refractive row.prop(mat, "b4w_refr_bump", text=_("Refraction Bump"))
def draw(self, context): scene = context.scene layout = self.layout layout.prop(scene, "b4w_cluster_size", text=_("Cluster Size")) layout.prop(scene, "b4w_lod_cluster_size_mult", text=_("LOD Cluster Size Multiplier")) layout.prop(scene, "b4w_lod_smooth_type", text=_("LOD Smooth Transitions")) layout.prop(scene, "b4w_lod_hyst_interval", text=_("Max LOD Hysteresis Interval"))
def draw(self, context): layout = self.layout if server.has_valid_sdk_dir(): is_started = server.B4WLocalServer.get_server_status() == server.SUB_THREAD_START_SERV_OK is_waiting_for_shutdown = server.B4WLocalServer.is_waiting_for_shutdown() allow_actions = server.B4WLocalServer.allow_actions() if is_started: layout.label(text = _("Development server is running.")) elif is_waiting_for_shutdown: layout.label(text = _("Stopping server...")) else: layout.label(text = _("Development server is down.")) if allow_actions: if is_started: layout.operator("b4w.stop_server", text=p_("Stop", "Operator"), icon="PAUSE") elif not is_waiting_for_shutdown: layout.operator("b4w.start_server", text=p_("Start", "Operator"), icon="PLAY") else: layout.label(text = _("Server actions are available in the other Blender instance.")) if is_started: layout.operator("b4w.open_sdk", text=p_("Open SDK", "Operator"), icon="URL") else: layout.label(text = _("Blend4Web SDK was not found."))
def draw(self, context): layout = self.layout obj = context.object col = layout.column() for i, level in enumerate(obj.lod_levels): if i == 0: continue box = col.box() row = box.row() row.prop(level, "object", text="") row.operator("object.lod_remove", text="", icon='PANEL_CLOSE').index = i row = box.row() row.prop(level, "distance") row = row.row(align=True) row.prop(level, "use_mesh", text="") row.prop(level, "use_material", text="") row = col.row(align=True) row.operator("object.lod_add", text=_("Add"), icon='ZOOMIN') row.menu("OBJECT_MT_lod_tools", text="", icon='TRIA_DOWN') row = layout.row() row.prop(obj, "b4w_lod_transition", text=_("Lod Transition Ratio"))
def draw(self, context): layout = self.layout obj = context.object layout.active = obj.b4w_floating row = layout.row() row.prop(obj.b4w_floating_settings, "name", text=_("Floater Name")) row = layout.row() row.prop(obj.b4w_floating_settings, "part", text=_("Part")) if (obj.b4w_floating_settings.part == "MAIN_BODY"): row = layout.row() row.prop(obj.b4w_floating_settings, "floating_factor", text=_("Floating Factor")) row = layout.row() row.prop(obj.b4w_floating_settings, "water_lin_damp", text=_("Water Linear Damping")) row = layout.row() row.prop(obj.b4w_floating_settings, "water_rot_damp", text=_("Water Rotation Damping")) if (obj.b4w_floating_settings.part == "BOB"): row = layout.row() row.prop(obj.b4w_floating_settings, "synchronize_position", TEXT="SYNCHRONIZE BOB POSITION")
def draw(self, context): layout = self.layout lamp = context.lamp layout.prop(lamp, "type", expand=True) if lamp.type == "AREA": layout.label(text=_("Area type is not supported")) else: split = layout.split() col = split.column() sub = col.column() sub.prop(lamp, "color", text="") sub.prop(lamp, "energy") if lamp.type in {'POINT', 'SPOT'}: sub.label(text=_("Falloff:")) sub.prop(lamp, "distance") if lamp.type == 'AREA': col.prop(lamp, "distance") col.prop(lamp, "gamma") col = split.column() col.prop(lamp, "use_specular") col.prop(lamp, "use_diffuse") if lamp.type == "SUN": row = layout.row() row.prop(lamp, "b4w_dynamic_intensity", text=_("Dynamic Intensity"))
def draw(self, context): obj = context.active_object layout = self.layout row = layout.row() row.template_list("B4W_UI_UL_actions_list", "OBJECT_UL_anim_baker", obj, "b4w_anim", obj, "b4w_anim_index", rows=3) col = row.column(align=True) col.operator("b4w.anim_add", icon='ZOOMIN', text="") col.operator("b4w.anim_remove", icon='ZOOMOUT', text="") anim = obj.b4w_anim if anim: anim_index = obj.b4w_anim_index row = layout.row() row.prop_search(anim[anim_index], "name", bpy.data, "actions", text=_("Name")) row = layout.row() row.prop(obj, "b4w_anim_clean_keys", text=_("Optimize Keyframes")) row = layout.row() row.prop(obj, "b4w_use_bpy_anim_baker", text=_("Use Blender's Native Baker")) row = layout.row() row.operator("b4w.animation_bake", text=_("Bake"), icon="REC")
def draw(self, context): layout = self.layout game = context.active_object.game layout.active = game.use_collision_bounds split = layout.split() col = split.column() col.prop(game, "collision_bounds_type", text=_("Bounds")) if game.collision_bounds_type in {"CONVEX_HULL", "TRIANGLE_MESH"}: layout.label(text = _("This collision bounds type is not supported"), icon='ERROR') return row = col.row() row.prop(game, "collision_margin", text=_("Margin"), slider=True) sub = row.row() sub.prop(game, "use_collision_compound", text=_("Compound")) layout.separator() split = layout.split() col = split.column() col.prop(game, "collision_group") col = split.column() col.prop(game, "collision_mask") layout.prop(context.object, "b4w_correct_bounding_offset", text=_("Bounding Box Correction"))
def draw(self, context): layout = self.layout if addon_prefs.has_valid_sdk_path(): is_started = server.B4WLocalServer.get_server_status() == server.SUB_THREAD_START_SERV_OK is_waiting_for_shutdown = server.B4WLocalServer.is_waiting_for_shutdown() allow_actions = server.B4WLocalServer.allow_actions() if is_started: layout.label(text = _("Development server is running.")) elif is_waiting_for_shutdown: layout.label(text = _("Stopping server...")) else: layout.label(text = _("Development server is down.")) if allow_actions: if is_started: layout.operator("b4w.stop_server", text=p_("Stop Server", "Operator"), icon="PAUSE") elif not is_waiting_for_shutdown: layout.operator("b4w.start_server", text=p_("Start Server", "Operator"), icon="PLAY") else: layout.label(text = _("Server actions are available in the other Blender instance.")) if is_started: layout.operator("b4w.open_sdk", text=p_("SDK Index", "Operator"), icon="URL") layout.operator("b4w.open_proj_manager", text=p_("Project Manager", "Operator"), icon="URL") layout.operator("b4w.preview", text=p_("Fast Preview", "Operator"), icon="ZOOM_ALL") else: layout.label(text = _("Blend4Web SDK was not found."))
def draw(self, context): layout = self.layout world = context.world sky = world.b4w_sky_settings layout.prop(context.world.b4w_sky_settings, "render_sky", text=_("Render Sky")) sky_is_active = getattr(sky, "render_sky") row = layout.row() row.active = sky_is_active row.prop(world, "use_sky_paper") row.prop(world, "use_sky_blend") row.prop(world, "use_sky_real") row = layout.row() row.active = sky_is_active row.column().prop(world, "horizon_color") col = row.column() col.prop(world, "zenith_color") row = layout.row() row.prop(sky, "reflexible", text=_("Reflect World")) row = layout.row() row.active = sky.reflexible row.prop(sky, "reflexible_only", text=_("Render Only Reflection")) row = layout.row() row.label("World Background:") row = layout.row() sides = row.split(align=True) sides.operator("b4w.world_background_show") sides.operator("b4w.world_background_hide")
def LOGIC_HT_header_append(self, context): if "BLEND4WEB" in context.scene.render.engine: layout = self.layout.row(align=True) layout.label(_("Not available in Blend4Web. Please use the Node Editor."), icon = 'ERROR') layout.operator( "wm.url_open", text="Logic Editor Documentation", icon='URL', ).url = _("https://www.blend4web.com/doc/en/logic_editor.html")
def INFO_MT_help_draw_new(self, context): if "BLEND4WEB" not in context.scene.render.engine: _INFO_MT_help_draw(self, context) else: layout = self.layout layout.operator("wm.url_open", text=_("Blend4Web Manual"), text_ctxt="*", icon='HELP').url = bpy.app.translations.pgettext_iface( _("https://www.blend4web.com/doc/en/index.html")) layout.operator("wm.url_open", text=_("API Reference"), text_ctxt="*", icon='HELP').url = "https://www.blend4web.com/api_doc/index.html" layout.operator("wm.url_open", text=_("Release Notes"), text_ctxt="*", icon='URL').url = bpy.app.translations.pgettext_iface( _("https://www.blend4web.com/doc/en/release_notes.html")) layout.separator() layout.operator("wm.url_open", text=_("Blend4Web Website"), text_ctxt="*", icon='URL').url = "https://www.blend4web.com" layout.operator("wm.url_open", text=_("Community Forums"), text_ctxt="*", icon='URL',).url = bpy.app.translations.pgettext_iface( _("https://www.blend4web.com/en/forums/")) layout.separator() layout.operator("wm.url_open", text=_("Report a Bug"), text_ctxt="*", icon='URL').url = bpy.app.translations.pgettext_iface( _("https://www.blend4web.com/en/forums/forum/17/")) layout.separator() layout.operator("wm.splash", icon='BLENDER')
def start(cls): if not cls.update_server_existed(): cls.server_status = WAIT_RESPONSE cls.server_process = threading.Thread(target=create_server) cls.server_process.daemon = True #for converting resources on MACOS if sys.platform == "darwin" and not ":/usr/local/bin" in os.environ["PATH"]: os.environ["PATH"] = os.environ["PATH"] + ":/usr/local/bin" try: cls.server_process.start() except BaseException as ex: cls.server_status = MAIN_THREAD_START_EXC cls.server_process = None bpy.ops.b4w.server_message("INVOKE_DEFAULT", message=get_translate(_("Server starting error: ")) + str(ex)) cls.wait_loop() if cls.server_status == SUB_THREAD_SERVER_EXC: bpy.ops.b4w.server_message("INVOKE_DEFAULT", message=get_translate(_("Server starting error: ")) + cls.error_message) if cls.server_status == SUB_THREAD_OTHER_EXC: bpy.ops.b4w.server_message("INVOKE_DEFAULT", message=get_translate(_("Could not start the server: ")) + cls.error_message) cls.panel_redraw()
def draw(self, context): layout = self.layout world = context.world sky = world.b4w_sky_settings layout.prop(context.world.b4w_sky_settings, "render_sky", text=_("Render Sky")) sky_is_active = getattr(sky, "render_sky") row = layout.row() row.active = sky_is_active row.prop(world, "use_sky_paper") row.prop(world, "use_sky_blend") row.prop(world, "use_sky_real") row = layout.row() row.active = sky_is_active row.column().prop(world, "horizon_color") col = row.column() col.prop(world, "zenith_color") col.active = sky_is_active and world.use_sky_blend row.column().prop(world, "ambient_color") row = layout.row() row.prop(sky, "reflexible", text=_("Reflect World")) row = layout.row() row.active = sky.reflexible row.prop(sky, "reflexible_only", text=_("Render Only Reflection"))
def execute(self, context): obj = context.object if not (obj.parent and obj.parent.type == "CAMERA" and obj.b4w_enable_viewport_alignment): self.report({"ERROR"}, _("Wrong object")) return {"FINISHED"} cam_data = obj.parent.data alignment = obj.b4w_viewport_alignment.alignment distance = obj.b4w_viewport_alignment.distance # [top-right, bottom-right, bottom-left, top-left] view_frame = cam_data.view_frame(context.scene) top = view_frame[0][1] bottom = view_frame[1][1] left = view_frame[2][0] right = view_frame[0][0] depth = view_frame[0][2] if alignment == "TOP_LEFT": v = mathutils.Vector((left, top, depth)) elif alignment == "TOP": v = mathutils.Vector((0, top, depth)) elif alignment == "TOP_RIGHT": v = mathutils.Vector((right, top, depth)) elif alignment == "LEFT": v = mathutils.Vector((left, 0, depth)) elif alignment == "CENTER": v = mathutils.Vector((0, 0, depth)) elif alignment == "RIGHT": v = mathutils.Vector((right, 0, depth)) elif alignment == "BOTTOM_LEFT": v = mathutils.Vector((left, bottom, depth)) elif alignment == "BOTTOM": v = mathutils.Vector((0, bottom, depth)) elif alignment == "BOTTOM_RIGHT": v = mathutils.Vector((right, bottom, depth)) if cam_data.type == "PERSP": v = v.normalized() scale = distance / abs(v[2]) v *= scale elif cam_data.type == "ORTHO": v[2] = -distance else: self.report({"ERROR"}, _("Unsupported camera type")) return {"FINISHED"} # convert location in local space to object location mat_inv_parent = obj.matrix_parent_inverse v = mat_inv_parent.inverted_safe() * v obj.location[0] = v[0] obj.location[1] = v[1] obj.location[2] = v[2] return {"FINISHED"}
def init_properties(): bpy.types.WindowManager.b4w_max_shore_distance = bpy.props.IntProperty( name=_("B4W: shoremap max distance"), default=100) bpy.types.WindowManager.b4w_shoremap_texure_size = bpy.props.IntProperty( name=_("B4W: shoremap texture size"), default=128)
def number_but(layout, toggle, number, name, color): row = layout.row(align=True) row.prop(halo, toggle, text=_("")) sub = row.column(align=True) sub.active = getattr(halo, toggle) sub.prop(halo, number, text=name, translate=False) if not color == "": sub.prop(mat, color, text=_(""))
def draw(self, context): tex = context.texture layout = self.layout layout.active = tex.b4w_water_foam layout.prop(tex, "b4w_foam_uv_freq", text=_("UV Frequency")) layout.prop(tex, "b4w_foam_uv_magnitude", text=_("UV Magnitude"))
def register(): bpy.types.Object.b4w_anim =\ bpy.props.CollectionProperty(type=B4W_Anim, name=_("B4W: animation")) bpy.types.Object.b4w_anim_index =\ bpy.props.IntProperty(name=_("B4W: animation index")) bpy.types.Object.b4w_use_bpy_anim_baker =\ bpy.props.BoolProperty(name=_("B4W: use bpy anim baker"), default = False)
def draw(self, context): world = context.world layout = self.layout layout.prop(world, "b4w_use_default_animation", text=_("Apply Default Animation")) row = layout.row() row.active = world.b4w_use_default_animation row.prop(world, "b4w_anim_behavior", text=_("Behavior"))
def draw(self, context): layout = self.layout lmp = context.lamp layout.prop(lmp, "use_shadow", text=_("Shadow")) if lmp.type == "SPOT" or lmp.type == "POINT": row = layout.row() row.active = lmp.use_shadow row.prop(lmp, "shadow_buffer_clip_start", text=_("Clip Start")) row.prop(lmp, "shadow_buffer_clip_end", text=_("Clip End"))
def draw(self, context): tex = context.texture layout = self.layout layout.active = getattr(tex, "b4w_use_map_parallax") row = layout.row() row.prop(tex, "b4w_parallax_scale", text=_("Scale"), slider=True) row.prop(tex, "b4w_parallax_steps", text=_("Steps"), slider=True) row.prop(tex, "b4w_parallax_lod_dist", text=_("Lod Distance"), slider=True)
def draw(self, context): obj = context.object layout = self.layout row = layout.row() row.prop(obj, "b4w_disable_fogging", text=_("Disable Fogging")) row = layout.row() row.prop(obj, "b4w_caustics", text=_("Caustics"))
class B4W_AnimBakerPanel(bpy.types.Panel): bl_label = _("Bake Skeletal Animation") bl_idname = "OBJECT_PT_anim_baker" bl_space_type = "VIEW_3D" bl_region_type = "TOOLS" bl_category = "Blend4Web" @classmethod def poll(self, context): try: ob = context.active_object return (ob.type == 'ARMATURE') except AttributeError: return False def draw(self, context): obj = context.active_object layout = self.layout row = layout.row() row.template_list("B4W_UI_UL_actions_list", "OBJECT_UL_anim_baker", obj, "b4w_anim", obj, "b4w_anim_index", rows=3) col = row.column(align=True) col.operator("b4w.anim_add", icon='ZOOMIN', text="") col.operator("b4w.anim_remove", icon='ZOOMOUT', text="") anim = obj.b4w_anim if anim: anim_index = obj.b4w_anim_index row = layout.row() row.prop_search(anim[anim_index], "name", bpy.data, "actions", text=_("Name")) row = layout.row() row.prop(obj, "b4w_anim_clean_keys", text=_("Optimize Keyframes")) row = layout.row() row.prop(obj, "b4w_use_bpy_anim_baker", text=_("Use Blender's Native Baker")) row = layout.row() row.operator("b4w.animation_bake", text=_("Bake"), icon="REC")
class B4W_CopyNormal(bpy.types.Operator): # copy normal bl_idname = 'object.copy_normal' bl_label = p_('Copy Normal', "Operator") bl_description = _('Copies normal from selected Vertex') bl_options = {"INTERNAL"} def execute(self, context): bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.mode_set(mode="EDIT") prepare(context) obj = context.active_object vert_index = len(context.active_object.data.vertices) if not context.window_manager.b4w_split: check = 0 # inverse selection for h in range(vert_index): if context.active_object.data.vertices[h].select == True: check += 1 if check == 1: for i in range(vert_index): if context.active_object.data.vertices[i].select == True: result = mathutils.Vector() for l in b4w_vertex_to_loops_map[i]: result = result + mathutils.Vector( b4w_loops_normals[l]) result = result / len(b4w_vertex_to_loops_map[i]) context.window_manager.b4w_vn_copynormal = result else: self.report({'INFO'}, _('Please select a single vertex')) return {'FINISHED'} else: for i in range(vert_index): if obj.data.vertices[i].select == True: obj["b4w_select_vertex"] = i break array = b4w_vertex_to_loops_map[obj["b4w_select_vertex"]] ind = array[obj["b4w_select"] % len(array)] context.window_manager.b4w_vn_copynormal = mathutils.Vector( b4w_loops_normals[ind]) return {'FINISHED'}
class B4W_DATA_PT_lamp(LampPanel, Panel): bl_label = _("Lamp") def draw(self, context): layout = self.layout lamp = context.lamp layout.prop(lamp, "type", expand=True) if lamp.type == "AREA": layout.label(text=_("AREA type is not supported"), icon="ERROR") else: split = layout.split() col = split.column() sub = col.column() sub.prop(lamp, "color", text="") sub.prop(lamp, "energy") if lamp.type in {'POINT', 'SPOT'}: sub.label(text=_("Falloff:")) sub.prop(lamp, "falloff_type", text="") if lamp.falloff_type != "INVERSE_SQUARE": row = layout.row() row.label(_("%s type is not supported.") % lamp.falloff_type, icon="ERROR") else: sub.prop(lamp, "distance") col.prop(lamp, "use_sphere") if lamp.type == 'AREA': col.prop(lamp, "distance") col.prop(lamp, "gamma") col = split.column() col.prop(lamp, "use_specular") col.prop(lamp, "use_diffuse") if lamp.type == "SUN": row = layout.row() row.prop(lamp, "b4w_dynamic_intensity", text=_("Dynamic Intensity"))
class B4W_WORLD_PT_world(WorldButtonsPanel, Panel): bl_label = _("World") bl_idname = "WORLD_PT_b4w_world" def draw(self, context): layout = self.layout world = context.world sky = world.b4w_sky_settings layout.prop(sky, "render_sky", text=_("Render Sky")) sky_is_active = getattr(sky, "render_sky") row = layout.row() row.active = sky_is_active row.prop(world, "use_nodes", text=_("Use Nodes (Cycles)")) is_node_world = getattr(world, "use_nodes") row = layout.row() row.active = sky_is_active and not is_node_world row.prop(world, "use_sky_paper") row.prop(world, "use_sky_blend") row.prop(world, "use_sky_real") row = layout.row() row.active = sky_is_active and not is_node_world row.column().prop(world, "horizon_color") col = row.column() col.prop(world, "zenith_color") row = layout.row() row.prop(sky, "reflexible", text=_("Reflect World")) row = layout.row() row.active = sky.reflexible row.prop(sky, "reflexible_only", text=_("Render Only Reflection")) row = layout.row() row.label("World Background:") row = layout.row() sides = row.split(align=True) sides.operator("b4w.world_background_show") sides.operator("b4w.world_background_hide")
class B4W_MATERIAL_PT_diffuse(MaterialButtonsPanel, Panel): bl_label = _("Diffuse") @classmethod def poll(cls, context): mat = context.material engine = context.scene.render.engine return check_material(mat) and (mat.type in { 'SURFACE', 'WIRE' }) and (engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout mat = active_node_mat(context.material) split = layout.split() col = split.column() col.prop(mat, "diffuse_color", text="") sub = col.column() sub.active = (not mat.use_shadeless) sub.prop(mat, "diffuse_intensity", text=_("Intensity")) col = split.column() col.active = (not mat.use_shadeless) col.prop(mat, "diffuse_shader", text="") col = layout.column() col.active = (not mat.use_shadeless) if mat.diffuse_shader == 'OREN_NAYAR': col.prop(mat, "roughness") elif mat.diffuse_shader == 'MINNAERT': col.prop(mat, "darkness") elif mat.diffuse_shader == 'TOON': row = col.row() row.prop(mat, "diffuse_toon_size", text=_("Size")) row.prop(mat, "diffuse_toon_smooth", text=_("Smooth")) elif mat.diffuse_shader == 'FRESNEL': row = col.row() row.prop(mat, "diffuse_fresnel", text=_("Fresnel")) row.prop(mat, "diffuse_fresnel_factor", text=_("Factor"))
def draw(self, context): layout = self.layout ob = context.object split = layout.split() col = split.column() col.prop(ob, "layers") #col.separator() #col.prop(ob, "pass_index") col = split.column() col.label(text="Parent:") col.prop(ob, "parent", text="") sub = col.column() sub.prop(ob, "parent_type", text="") parent = ob.parent if parent and ob.parent_type == 'BONE' and parent.type == 'ARMATURE': sub.prop_search(ob, "parent_bone", parent.data, "bones", text="") sub.active = (parent is not None) if parent and parent.type == "CAMERA": enable_align = ob.b4w_enable_viewport_alignment align = ob.b4w_viewport_alignment layout.prop(ob, "b4w_enable_viewport_alignment", text=_("Viewport Alignment")) row = layout.row() row.active = enable_align row.prop(align, "alignment") row = layout.row() row.active = enable_align row.prop(align, "distance") row = layout.row() row.active = enable_align row.operator("b4w.viewport_alignment_fit")
class B4W_ObjectOutlineSelect(ObjectButtonsPanel, Panel): bl_label = _("Selection and Outlining") bl_idname = "OBJECT_PT_b4w_outline_selectable" bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): obj = context.object is_mesh = obj.type == "MESH" or obj.type == "FONT" \ or obj.type == "META" or obj.type == "SURFACE" return (is_mesh and context.object and context.scene.render.engine in cls.COMPAT_ENGINES) def draw(self, context): obj = context.object layout = self.layout split = layout.split() col = split.column() col.prop(obj, "b4w_selectable", text=_("Selectable")) col = split.column() col.prop(obj, "b4w_outlining", text=_("Enable Outlining")) row = col.row() row.active = obj.b4w_outlining and obj.b4w_selectable row.prop(obj, "b4w_outline_on_select", text=_("Outline on Select")) col.separator() row = col.row() row.active = obj.b4w_outlining row.prop(obj.b4w_outline_settings, "outline_duration", text=_("Duration")) row = col.row() row.active = obj.b4w_outlining row.prop(obj.b4w_outline_settings, "outline_period", text=_("Period")) row = col.row() row.active = obj.b4w_outlining row.prop(obj.b4w_outline_settings, "outline_relapses", text=_("Relapses"))
class B4W_PasteNormal(bpy.types.Operator): # paste normal bl_idname = 'object.paste_normal' bl_label = p_('Paste Normal', "Operator") bl_description = _('Paste normal to selected Vertex') bl_options = {"INTERNAL"} def execute(self, context): bpy.ops.object.mode_set(mode="OBJECT") bpy.ops.object.mode_set(mode="EDIT") obj = context.active_object check_b4w_obj_prop(context) load_loops_normals_into_global_cache(obj) vert_index = len(context.active_object.data.vertices) check = 0 normals_edited = False if not context.window_manager.b4w_split: for h in range(vert_index): if context.active_object.data.vertices[h].select == True: check += 1 if check >= 1: for i in range(vert_index): if context.active_object.data.vertices[i].select == True: n = context.window_manager.b4w_vn_copynormal set_vertex_normal(i, (n[0], n[1], n[2])) normals_edited = True else: self.report({'INFO'}, _('Please select at least one vertex')) else: array = b4w_vertex_to_loops_map[obj["b4w_select_vertex"]] ind = array[obj["b4w_select"]%len(array)] n = context.window_manager.b4w_vn_copynormal b4w_loops_normals[ind] = (n[0], n[1], n[2]) normals_edited = True if normals_edited: bpy.ops.object.mode_set(mode="OBJECT") obj.data.normals_split_custom_set(b4w_loops_normals) bpy.ops.object.mode_set(mode="EDIT") return {'FINISHED'}
class B4W_MATERIAL_PT_rendering_options(MaterialButtonsPanel, Panel): bl_label = _("Rendering Options") @classmethod def poll(cls, context): mat = context.material engine = context.scene.render.engine return (mat and (mat.type in {'SURFACE', 'WIRE', 'HALO'}) and (engine in cls.COMPAT_ENGINES)) def draw(self, context): layout = self.layout base_mat = context.material mat = active_node_mat(base_mat) split = layout.split() col = split.column() col.prop(mat, "b4w_do_not_render", text=_("Do Not Render")) col = split.column() col.active = base_mat.game_settings.alpha_blend not in ["OPAQUE", "CLIP"] col.prop(mat, "b4w_render_above_all", text=_("Render Above All")) row = layout.row() game = context.material.game_settings row.prop(game, "use_backface_culling") row.prop(mat, "use_vertex_color_paint") split = layout.split() col = split.column() col.prop(mat, "b4w_wettable", text=_("Wettable")) split = layout.split() col = split.column() col.prop(mat, "b4w_lens_flares", text=_("Lens Flare")) col = split.column() col.active = not mat.use_nodes col.prop(mat, "b4w_refractive", text = _("Refractive")) row = col.row() row.active = mat.b4w_refractive row.prop(mat, "b4w_refr_bump", text=_("Refraction Bump"))
def shutdown(cls): if cls.server_process is not None: cls.server_status = WAIT_RESPONSE cls.waiting_for_shutdown = True try: if cls.server is not None: cls.server.stop() tornado.ioloop.IOLoop.instance().stop() cls.server_process = None cls.server = None cls.wait_loop() except BaseException as ex: cls.waiting_for_shutdown = False bpy.ops.b4w.server_message( "INVOKE_DEFAULT", message=get_translate(_("Server stopping error: ")) + str(ex)) cls.server_status = MAIN_THREAD_STOP_EXC cls.panel_redraw()
class B4W_DATA_PT_distance(SpeakerPanel, Panel): bl_label = _("Distance") bl_idname = "DATA_PT_b4w_distance" def draw(self, context): spk = context.speaker layout = self.layout layout.active = (getattr(spk, "b4w_behavior") == "POSITIONAL") split = layout.split() col = split.column() col.label(text=_("Volume:")) col.prop(spk, "attenuation") col = split.column() col.label(text=_("Distance:")) col.prop(spk, "distance_max", text=_("Maximum")) col.prop(spk, "distance_reference", text=_("Reference"))
def draw(self, context): layout = self.layout mat = active_node_mat(context.material) if mat.type in {'SURFACE', 'WIRE'}: split = layout.split() col = split.column() sub = col.column() sub.active = not mat.use_shadeless sub.prop(mat, "emit") sub.prop(mat, "ambient") col = split.column() col.prop(mat, "use_shadeless") col.prop(mat, "use_tangent_shading") col.prop(mat, "b4w_double_sided_lighting", text=_("Double-Sided Lighting"))
def draw(self, context): layout = self.layout rd = context.scene.render layout.active = rd.use_simplify split = layout.split() col = split.column() col.label(text=_("Viewport:")) col.prop(rd, "simplify_subdivision", text=_("Subdivision")) col.prop(rd, "simplify_child_particles", text=_("Child Particles")) col = split.column() col.label(text=_("Render:")) col.prop(rd, "simplify_subdivision_render", text=_("Subdivision")) col.prop(rd, "simplify_child_particles_render", text=_("Child Particles")) col.prop(rd, "simplify_shadow_samples", text=_("Shadow Samples")) col.prop(rd, "simplify_ao_sss", text=_("AO and SSS")) col.prop(rd, "use_simplify_triangulate")
class B4W_TEXTURE_PT_envmap(TextureTypePanel, Panel): bl_label = _("Environment Map") tex_type = 'ENVIRONMENT_MAP' def draw(self, context): layout = self.layout tex = context.texture env = tex.environment_map row = layout.row() row.prop(env, "source", expand=True) row.menu("TEXTURE_MT_envmap_specials", icon='DOWNARROW_HLT', text="") if env.source == 'IMAGE_FILE': layout.template_ID(tex, "image", open="image.open") layout.template_image(tex, "image", tex.image_user, compact=True) else: layout.label(text=_("This environment map type is not supported"), icon="ERROR")
class B4W_DATA_PT_camera(CameraButtonsPanel, Panel): bl_label = _("Camera") def draw(self, context): layout = self.layout cam = context.camera layout.label(text=_("Sensor:")) split = layout.split() col = split.column(align=True) if cam.sensor_fit == 'VERTICAL': col.prop(cam, "sensor_height", text=_("Height")) else: col.label(text=_("Unsupported sensor type."), icon="ERROR") col = split.column(align=True) col.prop(cam, "sensor_fit", text=_(""))
class B4W_DATA_PT_cone(SpeakerPanel, Panel): bl_label = _("Cone") bl_idname = "DATA_PT_b4w_cone" def draw(self, context): spk = context.speaker layout = self.layout layout.active = (getattr(spk, "b4w_behavior") == "POSITIONAL") split = layout.split() col = split.column() col.label(text=_("Angle:")) col.prop(spk, "cone_angle_outer", text=_("Outer")) col.prop(spk, "cone_angle_inner", text=_("Inner")) col = split.column() col.label(text=_("Volume:")) col.prop(spk, "cone_volume_outer", text=_("Outer"))
class B4W_ParallaxPanel(TextureTypePanel, Panel): bl_label = _("Parallax") bl_idname = "TEXTURE_PT_b4w_parallax" tex_type = 'IMAGE' def draw_header(self, context): self.layout.prop(context.texture, "b4w_use_map_parallax", text="") def draw(self, context): tex = context.texture layout = self.layout layout.active = getattr(tex, "b4w_use_map_parallax") row = layout.row() row.prop(tex, "b4w_parallax_scale", text=_("Scale"), slider=True) row.prop(tex, "b4w_parallax_steps", text=_("Steps"), slider=True) row.prop(tex, "b4w_parallax_lod_dist", text=_("Lod Distance"), slider=True)
def draw(self, context): layout = self.layout tex = context.texture if not tex.type in SUPPORTED_TEX_TYPES: layout.label(text=_("This texture type is not supported."), icon="ERROR") return False slot = getattr(context, "texture_slot", None) idblock = context_tex_datablock(context) if idblock: layout.template_preview(tex, parent=idblock, slot=slot) else: layout.template_preview(tex, slot=slot) #Show Alpha Button for Brush Textures, see #29502 if context.space_data.texture_context == 'BRUSH': layout.prop(tex, "use_preview_alpha")
class B4W_OperatorSetRecommendedOptions(bpy.types.Operator): bl_idname = "b4w.set_recommended_options" bl_label = p_("Set recommended options", "Operator") bl_description = _('Enable "World Space Shading", switch material mode to "GLSL", switch viewport shading to "Material", switch active camera sensor fit to "Vertical"') bl_options = {"INTERNAL"} def invoke(self, context, event): for scene in bpy.data.scenes: if hasattr(scene.render, "use_world_space_shading"): scene.render.use_world_space_shading = True scene.game_settings.material_mode = "GLSL" # can be any object from the scene if scene.camera and scene.camera.type == "CAMERA": scene.camera.data.sensor_fit = "VERTICAL" for area in bpy.context.screen.areas: if area.type == 'VIEW_3D': for space in area.spaces: if space.type == "VIEW_3D": space.viewport_shade = "MATERIAL" return {'FINISHED'}
class B4WPreviewScene(bpy.types.Operator): bl_idname = "b4w.preview" bl_label = p_("B4W Preview", "Operator") bl_description = _("Preview the current scene in the Blend4Web Viewer") bl_options = {"INTERNAL"} def execute(self, context): root = bpy.context.user_preferences.addons[__package__].preferences.b4w_src_path tmpdir = join(root, "tmp") if not exists(tmpdir): os.mkdir(tmpdir) previewdir = join(tmpdir, "preview") if not exists(previewdir): os.mkdir(previewdir) preferences = addon_prefs.get_prefs() bpy.ops.export_scene.b4w_json(do_autosave = False, run_in_viewer = True, override_filepath=join(previewdir, "preview.json"), save_export_path = False, is_fast_preview=True) correct_resources_path(previewdir) return {"FINISHED"}
class B4W_CollisionMaterial(MaterialButtonsPanel, bpy.types.Panel): bl_label = _("Special: Collision") bl_idname = "MATERIAL_PT_b4w_collision" bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): mat = context.material return (mat and (mat.type in {'SURFACE', 'HALO'}) and context.scene.render.engine in cls.COMPAT_ENGINES) def draw_header(self, context): mat = context.material self.layout.prop(mat, "b4w_collision", text=_("")) def draw(self, context): mat = context.material layout = self.layout layout.active = mat.b4w_collision row = layout.row() row.prop(mat, "b4w_use_ghost", text=_("Ghost")) row = layout.row() row.prop(mat, "b4w_collision_id", text=_("Collision ID")) col = layout.column() col.prop(mat, "b4w_collision_margin", text=_("Margin")) phys = context.material.physics # don't use node material split = layout.split() row = split.row() row.prop(phys, "friction") row.prop(phys, "elasticity", slider=True) col = layout.column() col.prop(mat, "b4w_collision_group", text=_("Collision Group")) col = layout.column() col.prop(mat, "b4w_collision_mask", text=_("Collision Mask"))
class B4W_RenderBloom(RenderButtonsPanel, bpy.types.Panel): bl_label = _("Bloom") bl_idname = "RENDER_PT_b4w_Bloom" bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): self.layout.prop(context.scene, "b4w_enable_bloom", text="") def draw(self, context): scene = context.scene bloom = scene.b4w_bloom_settings layout = self.layout layout.active = getattr(scene, "b4w_enable_bloom") layout.prop(bloom, "adaptive", text=_("Use Adaptive")) if not getattr(bloom, "adaptive"): layout.prop(bloom, "average_luminance", text=_("Average Luminance")) layout.prop(bloom, "key", text=_("Intensity")) layout.prop(bloom, "blur", text=_("Blur")) layout.prop(bloom, "edge_lum", text=_("Edge Luminance"))
def draw(self, context): layout = self.layout psys = context.particle_system pset = particle_get_settings(context) row = layout.row() row.prop(pset, "draw_method", expand=True) row.prop(pset, "show_guide_hairs") if pset.draw_method == 'NONE' or (pset.render_type == 'NONE' and pset.draw_method == 'RENDER'): return path = (pset.render_type == 'PATH' and pset.draw_method == 'RENDER') or pset.draw_method == 'PATH' row = layout.row() row.prop(pset, "draw_percentage", slider=True) if pset.draw_method != 'RENDER' or pset.render_type == 'HALO': row.prop(pset, "draw_size") else: row.label(text=_("")) if pset.draw_percentage != 100 and psys is not None: if pset.type == 'HAIR': if psys.use_hair_dynamics and psys.point_cache.is_baked is False: layout.row().label(text=_("Display percentage makes dynamics inaccurate without baking!")) else: phystype = pset.physics_type if phystype != 'NO' and phystype != 'KEYED' and psys.point_cache.is_baked is False: layout.row().label(text=_("Display percentage makes dynamics inaccurate without baking!")) row = layout.row() col = row.column() col.prop(pset, "show_size") col.prop(pset, "show_velocity") col.prop(pset, "show_number") if pset.physics_type == 'BOIDS': col.prop(pset, "show_health") col = row.column(align=True) col.label(text=_("Color:")) col.prop(pset, "draw_color", text=_("")) sub = col.row(align=True) sub.active = (pset.draw_color in {'VELOCITY', 'ACCELERATION'}) sub.prop(pset, "color_maximum", text=_("Max")) if path: col.prop(pset, "draw_step")
class B4W_TEXTURE_PT_colors(TextureButtonsPanel, Panel): bl_label = _("Colors") bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): tex = context.texture engine = context.scene.render.engine idblock = context_tex_datablock(context) return (tex and tex.type == 'BLEND' and context.scene.render.engine in cls.COMPAT_ENGINES and (isinstance(idblock, ParticleSettings) or isinstance(idblock, Material))) def draw(self, context): layout = self.layout tex = context.texture layout.prop(tex, "use_color_ramp", text=_("Ramp")) if tex.use_color_ramp: layout.template_color_ramp(tex, "color_ramp", expand=True)
def draw(self, context): scene = context.scene layout = self.layout layout.active = getattr(scene, "b4w_use_logic_editor") row = layout.row() row.label(text=_("Active Node Tree:")) row = layout.row(align=True) row.operator('scene.b4w_logic_editor_add_tree', icon='ZOOMIN', text='') row.operator('scene.b4w_logic_editor_remove_tree', icon='ZOOMOUT', text='') icon = 'NODETREE' if scene.b4w_use_logic_editor and not scene.b4w_active_logic_node_tree_new: icon = 'ERROR' row.prop_search(scene, 'b4w_active_logic_node_tree_new', bpy.data, 'node_groups', icon=icon, text='')
class B4W_RenderGlow(RenderButtonsPanel, bpy.types.Panel): bl_label = _("Glow Materials") bl_idname = "RENDER_PT_b4w_GlowMats" bl_options = {'DEFAULT_CLOSED'} def draw(self, context): scene = context.scene glow = scene.b4w_glow_settings layout = self.layout row = layout.row() row.prop(scene, "b4w_enable_glow_materials", text=_("Enable")) panel_active = getattr(scene, "b4w_enable_glow_materials") in {"ON", "AUTO"} row = layout.row() row.active = panel_active row.label(text=_("Small Mask:")) row = layout.row() row.active = panel_active col = row.column() col.prop(glow, "small_glow_mask_coeff", text=_("Intensity")) col = row.column() col.prop(glow, "small_glow_mask_width", text=_("Width")) row = layout.row() row.active = panel_active row.label(text=_("Large Mask:")) row = layout.row() col = row.column() col.prop(glow, "large_glow_mask_coeff", text=_("Intensity")) col = row.column() col.prop(glow, "large_glow_mask_width", text=_("Width")) row = layout.row() row.active = panel_active row.prop(glow, "render_glow_over_blend", text=_("Render Glow Over Transparent Objects"))
class B4W_PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel): bl_label = _("Collision Bounds") @classmethod def poll(cls, context): game = context.object.game rd = context.scene.render return (rd.engine in cls.COMPAT_ENGINES) \ and (game.physics_type in {'STATIC', 'DYNAMIC', 'RIGID_BODY'}) def draw(self, context): layout = self.layout game = context.active_object.game split = layout.split() col = split.column() col.prop(game, "collision_bounds_type", text=_("Bounds")) if game.collision_bounds_type in {"CONVEX_HULL", "TRIANGLE_MESH"}: layout.label(text=_("This collision bounds type is not supported"), icon='ERROR') return row = col.row() row.prop(game, "collision_margin", text=_("Margin"), slider=True) sub = row.row() sub.prop(game, "use_collision_compound", text=_("Compound")) layout.separator() split = layout.split() col = split.column() col.prop(game, "collision_group") col = split.column() col.prop(game, "collision_mask") layout.prop(context.object, "b4w_correct_bounding_offset", text=_("Bounding Box Correction"))
class B4W_OBJECT_PT_levels_of_detail(ObjectButtonsPanel, Panel): bl_label = _("Levels of Detail") bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): obj = context.object is_mesh = obj.type == "MESH" or obj.type == "FONT" \ or obj.type == "META" or obj.type == "SURFACE" is_empty = obj.type == "EMPTY" return ((is_mesh or is_empty) and context.object and context.scene.render.engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout obj = context.object col = layout.column() for i, level in enumerate(obj.lod_levels): if i == 0: continue box = col.box() row = box.row() row.prop(level, "object", text="") row.operator("object.lod_remove", text="", icon='PANEL_CLOSE').index = i row = box.row() row.prop(level, "distance") row = row.row(align=True) row.prop(level, "use_mesh", text="") row.prop(level, "use_material", text="") row = col.row(align=True) row.operator("object.lod_add", text=_("Add"), icon='ZOOMIN') row.menu("OBJECT_MT_lod_tools", text="", icon='TRIA_DOWN') row = layout.row() row.prop(obj, "b4w_lod_transition", text=_("Lod Transition Ratio"))
class B4W_MATERIAL_PT_specular(MaterialButtonsPanel, Panel): bl_label = _("Specular") @classmethod def poll(cls, context): mat = context.material engine = context.scene.render.engine return check_material(mat) and (mat.type in { 'SURFACE', 'WIRE' }) and (engine in cls.COMPAT_ENGINES) def draw(self, context): layout = self.layout mat = active_node_mat(context.material) layout.active = (not mat.use_shadeless) split = layout.split() col = split.column() col.prop(mat, "specular_color", text=_("")) col.prop(mat, "specular_intensity", text=_("Intensity")) col = split.column() col.prop(mat, "specular_shader", text=_("")) col = layout.column() if mat.specular_shader in {'COOKTORR', 'PHONG'}: col.prop(mat, "specular_hardness", text=_("Hardness")) elif mat.specular_shader == 'BLINN': row = col.row() row.prop(mat, "specular_hardness", text=_("Hardness")) row.prop(mat, "specular_ior", text=_("IOR")) elif mat.specular_shader == 'WARDISO': col.prop(mat, "specular_slope", text=_("Slope")) elif mat.specular_shader == 'TOON': row = col.row() row.prop(mat, "specular_toon_size", text=_("Size")) row.prop(mat, "specular_toon_smooth", text=_("Smooth"))
class B4WPreferences(AddonPreferences): # this must match the addon name, use '__package__' # when defining this in a submodule of a python package. bl_idname = os.path.splitext(__name__)[0] b4w_src_path = bpy.props.StringProperty(); b4w_port_number = IntProperty(name=_("Server Port"), default=6687, min=0, max=65535, description=_("Server port number")) b4w_server_auto_start = BoolProperty(name=_("Run development server " "automatically"), default = True, description=_("Run on Startup")) b4w_check_for_updates = BoolProperty(name=_("Check for updates"), default = False, description=_("Check for new addon version")) b4w_enable_ext_requests = BoolProperty(name=_("Enable External Requests"), default = False, description=_("Enable external requests to the server")) b4w_available_for_update_version = bpy.props.StringProperty() b4w_reexport_paths = bpy.props.CollectionProperty( type=B4WReexportPath) b4w_reexport_path_index = IntProperty(default=-1, min=-1) def draw(self, context): layout = self.layout layout.prop(self, "b4w_check_for_updates", text=_("Check For Updates on Startup")) if self.b4w_available_for_update_version: update_available = bpy.app.translations.pgettext_tip(_("Update is available: %s"), "Operator") layout.operator("wm.url_open", text=(update_available % \ (self.b4w_available_for_update_version)), icon='URL').url = DOWNLOADS if has_valid_sdk_path(): layout.label(text = _("Development Server:")) row = layout.row() row.prop(self, "b4w_server_auto_start", text=_("Run on Startup")) row.prop(self, "b4w_port_number") row.prop(self, "b4w_enable_ext_requests") for m in blend4web.init_mess: row = layout.row() row.label(m, icon="ERROR")