FC2ブログ
*admin*entry*file*plugin| 文字サイズ  


以前に公開したアドオンをちょっと改良したのでその紹介です
動作は「選択領域」を基に「一つ飛ばし」で頂点を選択する
というもので、基本的に領域拡大しか出来ませんでした。
あと、ボタンを何度も押す必要があるのでそこの改良です。

データはこちらのページに置いてあります
ここをクリック

改良後の全ソースがこちら


bl_info = {
"name": "Skip Select(Loop)",
"author": "Mithril",
"version": (0, 0, 2),
"blender": (2, 7, 9),
"location": "3DView > Tools > Skip Select > Edit Mode ",
"description": "Loop selection for one skip",
"tracker_url": "http://mithrilproject.blog66.fc2.com/",
"warning": "",
"category": "Tools"}

import bpy
import bmesh
from bpy.props import *

def SkipSelectMore(verts_back):
#Only Edit Mode
if bpy.context.object.mode != "EDIT":return {'FINISHED'}

obj = bpy.context.active_object
bpy.ops.object.mode_set(mode='EDIT')
#Vertex Mord
bpy.context.tool_settings.mesh_select_mode = (True, False, False)
mesh = bmesh.from_edit_mesh(obj.data)

#Get Select Vertex(s)
if ( verts_back == []) :
verts = []
i = 0
for vert in mesh.verts:
if vert.select == True:
verts.append(vert.index)
i = i+1
else :
m = 0
for vert in verts_back:
m += 1

verts = []
i = 0
for vert in mesh.verts:
if (vert.index == verts_back[i]) :
vert.select = True
verts.append(vert.index)
i += 1
if ( i == m ) : break

#Select More
bpy.ops.mesh.select_more()
#Select Inverse
bpy.ops.mesh.select_all(action='INVERT')

#Reselect
k = 0
for v in mesh.verts:
if k == i : break
if v.index == verts[k]:
v.select = True
k = k+1
if k == i : break

#Select Inverse
bpy.ops.mesh.select_all(action='INVERT')

verts_back.clear()

for vert in mesh.verts:
if vert.select == True:
verts_back.append(vert.index)

return verts_back


def SkipSelectLess(verts_back):
#Only Edit Mode
if bpy.context.object.mode != "EDIT":return {'FINISHED'}

obj = bpy.context.active_object
bpy.ops.object.mode_set(mode='EDIT')
#Vertex Mord
bpy.context.tool_settings.mesh_select_mode = (True, False, False)
mesh = bmesh.from_edit_mesh(obj.data)

#Get Select Vertex(s)
if ( verts_back == []) :
verts = []
i = 0
for vert in mesh.verts:
if vert.select == True:
verts.append(vert.index)
i = i+1
else :
m = 0
for vert in verts_back:
m += 1

verts = []
i = 0
for vert in mesh.verts:
if (vert.index == verts_back[i]) :
vert.select = True
verts.append(vert.index)
i += 1
if ( i == m ) : break

#Select More
bpy.ops.mesh.select_more()
#Select Less
bpy.ops.mesh.select_less()

#Reselect
k = 0
for v in mesh.verts:
if k == i : break
if v.index == verts[k]:
v.select = False
k = k+1
if k == i : break

#Select Inverse
bpy.ops.mesh.select_all(action='INVERT')
bpy.ops.mesh.select_all(action='INVERT')

verts_back.clear()

for vert in mesh.verts:
if vert.select == True:
verts_back.append(vert.index)

return verts_back

class UI(bpy.types.Panel):
bl_label = "Skip Select"
bl_space_type = "VIEW_3D"
bl_region_type = "TOOLS"
bl_category = 'Tools'

@classmethod
def poll(self, context):
obj = context.active_object
if obj and obj.type == 'MESH':
return{'FINISHED'}

def draw(self, context):
row = self.layout.row(align=True)
row.operator('skip.select', icon='LATTICE_DATA')
row.enabled = len([o for o in context.selected_objects if o.mode == 'EDIT'])

class Skip_Select(bpy.types.Operator):
bl_idname = "skip.select"
bl_label = "Select (More)"
bl_options = {'REGISTER', 'UNDO'}

repeat_c = IntProperty(name='Repeat',
description='Repeat Count',
min=0,
max=100,
default=0)
count = 0
verts_back = []

## EXECUTE #######
def execute(self, context):

obj = bpy.context.active_object
more = self.repeat_c- self.count
#print(self.count)
#print(self.repeat_c)
#print(more)
#print(obj.data.total_vert_sel)

if ( self.count == 0 ) :
self.repeat_c = 1
more = 1
self.verts_back = []

verts_back = self.verts_back

if ( more == 1 ) :
SkipSelectMore(verts_back)
elif ( more == -1 ) :
SkipSelectLess(verts_back)
elif ( more > 1 ) :
for i in range(more) :
SkipSelectMore(verts_back)
elif ( more < 1 ) :
for i in range(more * -1 ) :
SkipSelectLess(verts_back)

self.verts_back = verts_back
self.count += more
if ( self.verts_back == [] and self.count == 0) :
self.repeat_c = 0
return {'FINISHED'}

### REGISTER ######

def register():
bpy.utils.register_module(__name__)

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

if __name__ == '__main__':
register()



まず最初に「追加のプロパティ」を設定します。


class Skip_Select(bpy.types.Operator):
bl_idname = "skip.select"
bl_label = "Select (More)"
bl_options = {'REGISTER', 'UNDO'}

repeat_c = IntProperty(name='Repeat',
description='Repeat Count',
min=0,
max=100,
default=0)
count = 0
verts_back = []

とりあえずこれで追加だけならできるみたいです。
数値変更は出来ますが特に何も動作はしません。
追加の変数も2つほど入れてます

「count」は「ツールのボタンを押した」時の動作で
「初期化」させるようにしています。

「verts_back」は頂点の一時保管場所として定義


そして、メインの処理がこちら


#Get Select Vertex(s)
if ( verts_back == []) :
verts = []
i = 0
for vert in mesh.verts:
if vert.select == True:
verts.append(vert.index)
i = i+1
else :
m = 0
for vert in verts_back:
m += 1

verts = []
i = 0
for vert in mesh.verts:
if (vert.index == verts_back[i]) :
vert.select = True
verts.append(vert.index)
i += 1
if ( i == m ) : break


結果的に特に大した処理をしているわけではないのですが、
どうも、ボタンを押すのとプロパティを操作するのでは
挙動が異なるらしく同じような処理が出来ませんでした。

「プロパティ」が更新されても「頂点情報が更新されない」
という罠にひかかりまして、それで一時保管場所を作りました
「領域縮小」はただ単に逆の動作になっているだけです。

使うと解かりますが、メッシュの頂点数の上限までやっちゃうと
プロパティの動作では戻らなくなっちゃいます。
このときは一度プロパティを「0」にすると初期化されます

処理速度について
最初に改良していたのはこんな感じで


verts = []
i = 0
for vert in mesh.verts:
for m in verts_back :
if vert.select == True and vert.index == m :
verts.append(vert.index)
i += 1
elif (vert.index == m) :
vert.select = True
verts.append(vert.index)
i += 1


これでも、動作するのですが使ってみるとめっちゃ重いです。
理由は簡単で「全ての頂点情報ひとつひとつ」に対して
「保管されている頂点」全てを照合させているから、
そりゃぁ重くなるよ。で、処理を軽くするために
今のソースになってます。一応「サブディビジョンサーフェス」
「10」の後に更に「2」をかけたぐらいの密度なら
ストレス無く動作します、多分

やりすぎるとBlenderが落ちるので程々に
使う使わないは別にして、アドオン作成のお勉強にはなったかな?


スポンサーサイト

Mithril

Author:Mithril


趣味は主に雑学です。
どうでもいいこと書いてます。

Blenderやプログラムに
ついても書いたりするかも。
私のPC環境はこちら

メールはこちらから↓
mithrilp★yahoo.co.jp
(★を@に変えて下さい)

02 | 2018/03 | 04
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
QRコード