User Tools

Site Tools


blender

This is an old revision of the document!


Blender

cushion

source : https://www.youtube.com/watch?v=MLUnfE4FcOY

  • Unordered List Itemcube
  • s z
  • loop cuts hor 30
  • loop cut vert 1
  • physics → cloth → change preset to silk
  • collision → quality 4
  • enable self collision
  • field weights → gravity 0
  • add a “force field” (make sure its placed in the center of the cube)
  • strength 150
  • start animation and stop when enough
  • apply the cloth modifier
  • remove the force field

dae cleaner

import bpy
 
def decimate():
    for obj in bpy.data.objects:
        if obj.type == 'MESH':
            bpy.context.scene.objects.active = obj
            bpy.ops.object.modifier_add(type="DECIMATE")
            mod_name = bpy.context.object.modifiers[-1].name
            bpy.context.object.modifiers[mod_name].decimate_type = 'DISSOLVE'
            bpy.ops.object.modifier_apply(apply_as = 'DATA', modifier=mod_name)
 
def recenter_origin():
    bpy.context.scene.cursor_location = (0.0,0.0,0.0)
    for obj in bpy.data.objects:
        if obj.type == 'MESH':
            obj.select = True
    #bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')
    bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
 
def set_layers():
    for obj in bpy.data.objects:
        if obj.type == 'MESH':
            bpy.context.scene.objects.active = obj
            if obj.parent.name == "group_0":
                if obj.name[0:5] == "group":
                    bpy.context.object.layers[1] = True
                elif obj.name[0:8] == "instance":
                    bpy.context.object.layers[2] = True
            if obj.parent.name[0:8] == "instance":
                bpy.context.object.layers[3] = True
            if (obj.parent.name[0:5] == "group") and (obj.parent.name != "group_0"):
                bpy.context.object.layers[4] = True
            bpy.context.object.layers[0] = False
 
def unparent_all():
    bpy.ops.object.select_all(action='DESELECT')
    for obj in bpy.data.objects:
        bpy.context.scene.objects.active = obj
        if bpy.context.active_object.parent != None:
            obj.select = True
    bpy.ops.object.parent_clear(type='CLEAR_KEEP_TRANSFORM')
 
def select_all(status=True):
    #bpy.ops.object.select_all(action='SELECT')
    #bpy.ops.object.select_all(action='DESELECT')
    for obj in bpy.data.objects:
        obj.select = status
 
def hide_all(status=True):
    for obj in bpy.data.objects:
        bpy.context.scene.objects.active = obj
        bpy.context.object.hide = status
 
def remove_duplicates():
    unparent_all()
    bpy.ops.object.select_all(action='DESELECT')
    datas = {}
    for obj in bpy.data.objects:
        if obj.type == 'MESH':
            bpy.context.scene.objects.active = obj
            actual = bpy.context.scene.objects.active 
            if actual.data.name not in datas:
                datas[actual.data.name] = [obj.name]
            else:
                datas[actual.data.name].append(obj.name)
    #print(datas)
    for values in datas:
        length = len(datas[values])
        if length > 1:
            print(values, length, sep=':')
            to_delete = sorted(datas[values])[1:length]
            for value in to_delete:
                bpy.data.objects[value].select = True
                bpy.ops.object.delete()
 
        #if length == 6:
        #    print(datas[values])
        #print(values, datas[values][0].split('_')[1], sep=" : ")
        #print(to_delete)
 
print("== Decimation Start ==")
print(bpy.data.scenes['Scene'].statistics())
 
remove_duplicates()
decimate()
recenter_origin()
 
print("== Decimation End ==")
print(bpy.data.scenes['Scene'].statistics())

shortcuts

Camera

Shortcut Function Notes
ctrl+alt+0align camera to view

Interface

http://www.blendertips.com/hotkeys.html

Shortcut Function Notes
ctrl + up/dow arrowsshow / hide full screen panel
keypad 1/3/7change view

Beziers

Shortcut Function Notes
vset handle type
alt+cclose

Edit mode

Shortcut Function Notes
aselect all / deselect all
bbox select
bbbrush select
ggrab (translate)
rrotate
sscale
x/y/zusing axis
shift + x/y/zuse 2 axis except the one selected (ex : shift + z = use x+y)
xx/yy/zzuse local axis
ctrl + lselect linked elements
pseparate items
jjoin item
hhide
alt + hshow all
fcreate a face

Utils

Shortcut Function Notes
ctrl + ttracking mode to align camera to an object
alt + gclear coordinates
shift + c3D Cursor to origin

Blender gmaps

sources

installation

renderdoc
C:\Windows\System32\cmd.exe /c "SET RENDERDOC_HOOK_EGL=0 && START "" ^"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe^" --disable-gpu-sandbox --gpu-startup-dialog"
renderdoc blender addon

meshlab

procedure

capture
  • run renderdoc
  • go to “file/inject into process”
  • run chrome using the shortcut and see the alert
  • get the alert “process id” and use “refresh” in renderdoc to see the process and then push “inject” button (bottom right)
  • click on the “ok” button on the chrome alert
  • chrome should display numbers on the top left
  • go to google maps and set to satellite and 3d
  • explore the place with zooming and turn around the buildings
  • go to renderdoc and use “capture after” 5 seconds
  • go to chrome and move the 3d view and then it will hang shortly (it has been captured)
  • go to renderdoc to see the capture
  • right click and save the rdc file
  • use import rdc file inside blender
optimizing mesh
  • remove unuseful items
  • select all the items and join them (ctrl+j)
  • “edit mode” and “merge by distance”
optimize uv map
  • duplicate the item and disable the first one
  • remove the materials using this script :

import bpy

C = bpy.context

for i in range(0,len(C.object.material_slots)):
    C.object.active_material_index = 1
    bpy.ops.object.material_slot_remove()

bpy.ops.object.mode_set(mode = 'EDIT') 
bpy.ops.mesh.select_all(action = 'SELECT')
bpy.ops.object.material_slot_assign()
bpy.ops.object.mode_set(mode = 'OBJECT')

  • export selection as obj
  • go to meshlab
  • “file/import mesh”
  • select mesh
  • go to “filters / texture / parametrization : trivial per-triangle”
  • set “texture dimension” to 8192 and click “apply”
  • go to “render / show uv tex map” to see the result
  • “file / export mesh”
  • uncheck “vert / normal” and “face / color” so keep “wedge / texcoord”
  • go back to blender
  • delete the object
  • import obj
bake the new texture
  • select the imported mesh
  • go to “shader editor”
  • add a new material
  • add an “image texture” node (do not connect it)
  • create a new texture with 8192px size
  • change renderer to “cycles” (set device to “cpu”)
  • go to “bake” tab and select “bake type” as “diffuse”
  • under “influence”, disable “direct” and “indirect”
  • check “selected to active”
  • “ray distance” to 0.1
  • “output margin” 1px
  • select image texture node in shader editor
  • select disbled mesh and then select imported mesh (using ctrl to set the last one as active)
  • click “bake”
  • wait
  • connect the image node
  • rename the new texture and export it from the image editor

blender utils

blender 2.8 get names

import bpy
 
def getNames():
    selection_names = bpy.context.selected_objects
    for i in selection_names:
        print(i.name)
getNames()

blender 2.8 custom join

import bpy
   
def customJoin():
    # convert to single user
    bpy.ops.object.make_single_user(type='SELECTED_OBJECTS', object=True, obdata=True, material=False, animation=False)
    # get selection
    selected_objects = bpy.context.selected_objects
   
    # do the job
    for o in selected_objects:
        if o.type != 'EMPTY':
            # set active
            bpy.context.view_layer.objects.active = o
     
            # convert to mesh
            if o.type in  ['CURVE', 'FONT']:
                bpy.ops.object.convert(target='MESH')
     
            # apply modifiers
            for mod in o.modifiers:
                bpy.ops.object.modifier_apply(modifier = mod.name)
     
            # get the object's name
            object_name = o.name
     
            # get group
            if object_name in o.vertex_groups:
                group = o.vertex_groups[object_name]
            else:
                group = o.vertex_groups.new(name = object_name)
     
            # get vertices
            verts = []
            for vert in o.data.vertices:
                verts.append(vert.index)
     
            # assign vertices to group
            group.add(verts, 1.0, 'REPLACE')
 
    # join to a single object
    bpy.ops.object.join()
     
customJoin()

2.79 groups

import bpy

def giveGroup(groupname=""):
    selected = bpy.context.selected_objects
    for item in selected:
        bpy.context.scene.objects.active = item
        bpy.ops.object.group_link(group='veranda')

#giveGroup("veranda")

def giveMaterial(materialname=""):
    selected = bpy.context.selected_objects
    for item in selected:
        bpy.context.scene.objects.active = item
        bpy.context.object.active_material.name = materialname

giveMaterial("vitre")

addon template

import bpy

bl_info = {
    "name": "my test addon",
    "author": "jojo",
    "version": (1,0),
    "blender": (2,83,0),
    "category": "Object",
    "location": "Operator Search",
    "description": "More monkeys!!",
    "warning" : "",
    "doc_url": "",
    "tracker_url": ""
}

class MESH_OT_monkey_grid(bpy.types.Operator):
    """Let's spread some joy"""
    bl_idname = "mesh.monkey_grid"
    bl_label = "Monkey Grid"
    bl_options = {'REGISTER', 'UNDO'}

    count_x: bpy.props.IntProperty(
        name="X",
        description="Number of monkeys in the x direction",
        default=3,
        min=1,soft_max=10
    )
    count_y: bpy.props.IntProperty(
        name="Y",
        description="Number of monkeys in the y direction",
        default=2,
        min=1,soft_max=10
    )
    size: bpy.props.FloatProperty(
        name="Size",
        description="Size of each monkey",
        min=0,max=1
    )

    @classmethod
    def poll(cls, context):
        if context.area.type == 'VIEW_3D':
            return True
        return False

    def execute(self, context):
        for idx in range(self.count_x * self.count_y):
            x = idx % self.count_x
            y = idx // self.count_x
            bpy.ops.mesh.primitive_monkey_add(
                size=self.size,
                location=(x, y, 1))
        return {'FINISHED'}

class VIEW3D_PT_monkey_grid(bpy.types.Panel):
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "Monkeys"
    bl_label = "Grid"

    def draw(self, context):
        self.layout.operator('mesh.monkey_grid',
            text='Default grid',
            icon='MONKEY')
        props = self.layout.operator('mesh.monkey_grid',
            text='Big grid',
            icon='MONKEY')
        props.count_x = 10
        props.count_y = 10
        props.size = 0.8

def register():
    bpy.utils.register_class(MESH_OT_monkey_grid)
    bpy.utils.register_class(VIEW3D_PT_monkey_grid)

def unregister():
    bpy.utils.unregister_class(MESH_OT_monkey_grid)
    bpy.utils.unregister_class(VIEW3D_PT_monkey_grid)

Simple button

source : https://blenderartists.org/t/calling-a-function-from-a-button/616752/7

import bpy



class SimpleOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        self.report({'INFO'}, "Button clicked!")
        return {'FINISHED'}


def draw_func(self, context):
    layout = self.layout
    layout.operator("object.simple_operator")
    

def register():
    bpy.utils.register_class(SimpleOperator)
    bpy.types.VIEW3D_HT_header.prepend(draw_func)


def unregister():
    bpy.utils.unregister_class(SimpleOperator)
    bpy.types.VIEW3D_HT_header.remove(draw_func)


if __name__ == "__main__":
    register()

bl_info = {
    "name": "Exploded Bake",
    "category": "Render",
}


import bpy


class ExplodedBake(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Exploded Bake"
    bl_idname = "OBJECT_PT_exploded_bake" # follow Blender convention for id names
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"
    
    def draw(self, context):
        layout = self.layout
        obj = context.object
        
        row = layout.row()
        row.prop(obj, "name")
        
        row = layout.row()
        row.operator("button.explode")


class buttonExplode(bpy.types.Operator):
    bl_idname = "button.explode" # translates to C-name BUTTON_OT_explode
    bl_label = "Button text"

    def execute(self, context):
        #self.report({'INFO'}, "Hello world!")
        print("hello")
        return {'FINISHED'}
    
    
# (un-)register entire module, so you don't need to add every class here...
def register():
    bpy.utils.register_module(__name__)


def unregister():
    bpy.utils.unregister_module(__name__)


if __name__ == "__main__":
    register()

import bpy

class SEBMAS_PROP_move_origins(bpy.types.PropertyGroup):

    def update_function(self, context):
        if self.move_origin_toggle:
            bpy.context.scene.tool_settings.use_transform_data_origin = True
            bpy.context.scene.tool_settings.snap_elements = {'VERTEX'}
        else:
            bpy.context.scene.tool_settings.use_transform_data_origin = False
            bpy.context.scene.tool_settings.snap_elements = {'INCREMENT'}
        return

    bpy.types.WindowManager.move_origin_toggle = bpy.props.BoolProperty(
        default = False,
        update = update_function)

class SEBMAS_PT_tools_move_origin(bpy.types.Panel):
    bl_category = "Tool"
    bl_context = ".objectmode"  # dot on purpose (access from topbar)
    bl_label = "SebMas"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'

    def draw(self, context):
        self.layout.prop(context.window_manager,
            'move_origin_toggle',
            text="Move origin",
            toggle=True,
            icon='MONKEY')

classes = (
    SEBMAS_PT_tools_move_origin,
)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)

if __name__ == "__main__":
    register()

bounding box

Select an object and then :

import bpy;
ob = bpy.data.scenes.active.objects.active;
ob.getData(mesh=True).verts.extend(ob.getBoundBox(0))
the object needs to dont have any “transformation”

blender.1644236959.txt.gz · Last modified: by 127.0.0.1