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

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。



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

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

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


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が落ちるので程々に
使う使わないは別にして、アドオン作成のお勉強にはなったかな?


【】
SkipSelectMore はこんな感じでどうでしょうか。

import bpy
import bmesh

def skip_select_more(bm):
#選択頂点取得
selects = [v for v in bm.verts if v.select]

#選択範囲拡張
bpy.ops.mesh.select_more()

#インバース選択
bpy.ops.mesh.select_all(action='INVERT')

#選択頂点を再選択
for v in selects:
v.select = True

#インバース選択
bpy.ops.mesh.select_all(action='INVERT')

def execute():
#エディットモードじゃなければ終了
if bpy.context.object.mode != "EDIT":
return {'FINISHED'}

#頂点モードに変更
bpy.context.tool_settings.mesh_select_mode = (True, False, False)

# BMesh の作成
bm = bmesh.from_edit_mesh(bpy.context.active_object.data)

count = 1
for i in range(count):
skip_select_more(bm)


execute()
【Re: タイトルなし】
>名無し さん

ご指摘ありがとうございます、確かにこれなら短くて済みそうですね。
でも、この部分で何やらエラー吐いちゃいますね。

#選択頂点取得
selects = [v for v in bm.verts if v.select]

意味はわかるのですが、何処かで文法間違ってる?
ちょっと調べてみますね。


この記事へコメントする















Mithril

Author:Mithril


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

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

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

07 | 2018/08 | 09
- - - 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コード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。