Page Menu
Home
Search
Configure Global Search
Log In
Files
F9303
Vert_pin.py
Public
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Fabian Fricke (frigi)
Nov 13 2013, 2:01 PM
Size
14 KB
Subscribers
None
Vert_pin.py
View Options
#!BPY
"""
Name: 'Vertex pin'
Blender: 248a
Group: 'Mesh'
Tooltip: 'Pins vertices while editing'
"""
__author__
=
"Fabian Fricke"
__url__
=
(
"frigi.designdevil.de"
)
__version__
=
"0.9"
__email__
=
[
"frigi.f@googlemail.com"
]
__bpydoc__
=
"""\
Important:
This script has potential to completely crash Blender (especially on more complex meshes)!
Always save your work before using it!
General information:
You have to enable Script Links in order to be able to use this script.
The script uses a vertex group called "PinGroup" to determine which vertices are pinned.
This vertex group is completely handeled by the script itself and the interface provides all
necessary tools to modify it. It's not advised to use Blender's own vertex group panel.
The script supports vertex weights.
A value of 1 means completely static vertices; 0 means no pinning at all.
If your mesh is too heavy to allow the script to rum smoothly you can disable the realtime mode
by toggling the "rt" button off. You then need to exit editmode to apply the pinning.
By default the Vertex group "PinGroup" will not be deleted when exiting the script in order to
preserve your modifications. If you still want the script to automatically delete the group upon
quitting you have to enable the "d" button in the lower right corner.
"""
# --------------------------------------------------------------------------
# Vert pin.py
# Copyright Fabian Fricke 2009
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
import
Blender
from
Blender
import
Scene
,
Mesh
,
Window
,
Draw
,
Text
import
bpy
import
BPyMessages
import
string
######################################################
# Vars
######################################################
scriptName
=
"Vert pin.py"
activeMesh
=
0
save
=
0
groupSave
=
0
clear
=
0
pin
=
Draw
.
Create
(
0
)
realtime
=
Draw
.
Create
(
1
)
weight
=
Draw
.
Create
(
1.0
)
delete
=
Draw
.
Create
(
0
)
floatPrec
=
5
#decimal places used to check if old and new vert coordinates are different
######################################################
# Functions
######################################################
#________________________________________________________________________________________________
def
avoidEmptyCrash
():
# avoids crashes caused by empty/not existing vert group/Blender Text
# if somebody manually deleted the vert group while script is running a new one is created to avoid a crash
HandleGroup
()
if
not
groupSave
:
me
.
addVertGroup
(
"PinGroup"
)
# avoid crash if nothing was assigned to the group yet
is_editmode
=
Window
.
EditMode
()
if
is_editmode
:
Window
.
EditMode
(
0
)
me
.
assignVertsToGroup
(
"PinGroup"
,
[],
0
,
Mesh
.
AssignModes
.
REPLACE
)
# basically does nothing except avoiding the crash
is_editmode
=
Window
.
EditMode
(
1
)
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
HandleText
():
global
VDict
,
save
if
save
==
0
:
VDict
=
Text
.
New
(
"VertDict"
)
SaveVertPos
()
print
"VertDict text created"
save
=
1
else
:
Text
.
unlink
(
VDict
)
VDict
=
Text
.
New
(
"VertDict"
)
SaveVertPos
()
print
"VertDict text updated"
if
pin
.
val
:
if
realtime
.
val
:
ob_act
.
addScriptLink
(
scriptName
,
"ObDataUpdate"
)
else
:
ob_act
.
addScriptLink
(
scriptName
,
"ObjectUpdate"
)
else
:
ob_act
.
clearScriptLinks
()
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
HandleGroup
():
global
groupSave
groupSave
=
0
for
g
in
me
.
getVertGroupNames
():
if
g
==
"PinGroup"
:
groupSave
=
1
break
else
:
groupSave
=
0
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
SaveVertPos
():
global
clear
HandleGroup
()
if
not
groupSave
:
me
.
addVertGroup
(
"PinGroup"
)
is_editmode
=
Window
.
EditMode
()
if
is_editmode
:
Window
.
EditMode
(
0
)
for
vi
in
me
.
getVertsFromGroup
(
"PinGroup"
):
VDict
.
write
(
str
(
vi
)
+
"
\n
"
)
VDict
.
write
(
str
(
me
.
verts
[
vi
]
.
co
.
x
)
+
"
\n
"
)
VDict
.
write
(
str
(
me
.
verts
[
vi
]
.
co
.
y
)
+
"
\n
"
)
VDict
.
write
(
str
(
me
.
verts
[
vi
]
.
co
.
z
)
+
"
\n
"
)
if
is_editmode
:
Window
.
EditMode
(
1
)
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
CheckVertPos
():
global
floatPrec
VDict
=
Text
.
Get
(
"VertDict"
)
VertDict
=
{}
for
i
in
range
(
0
,
VDict
.
getNLines
()
-
1
,
4
):
# -1 to cancel out the last line which is empty and using step 4 to only get the vert indices
Vindex
=
int
(
string
.
join
(
VDict
.
asLines
(
i
,
i
+
1
),
''
)
)
Vcoords
=
[]
Vcoords
.
append
(
float
(
string
.
join
(
VDict
.
asLines
(
i
+
1
,
i
+
2
),
''
)
))
# x
Vcoords
.
append
(
float
(
string
.
join
(
VDict
.
asLines
(
i
+
2
,
i
+
3
),
''
)
))
# y
Vcoords
.
append
(
float
(
string
.
join
(
VDict
.
asLines
(
i
+
3
,
i
+
4
),
''
)
))
# z
VertDict
[
Vindex
]
=
Vcoords
for
vt
in
me
.
getVertsFromGroup
(
"PinGroup"
,
1
):
for
i
in
VertDict
:
if
vt
[
0
]
==
i
:
for
v
in
me
.
verts
:
if
i
==
v
.
index
:
if
round
(
VertDict
[
i
][
0
],
floatPrec
)
-
round
(
v
.
co
.
x
,
floatPrec
)
!=
0
:
v
.
co
.
x
=
(
round
(
VertDict
[
i
][
0
],
floatPrec
)
*
vt
[
1
]
)
+
(
round
(
v
.
co
.
x
,
floatPrec
)
*
(
1.0
-
vt
[
1
]
)
)
if
round
(
VertDict
[
i
][
1
],
floatPrec
)
-
round
(
v
.
co
.
y
,
floatPrec
)
!=
0
:
v
.
co
.
y
=
(
round
(
VertDict
[
i
][
1
],
floatPrec
)
*
vt
[
1
]
)
+
(
round
(
v
.
co
.
y
,
floatPrec
)
*
(
1.0
-
vt
[
1
]
)
)
if
round
(
VertDict
[
i
][
2
],
floatPrec
)
-
round
(
v
.
co
.
z
,
floatPrec
)
!=
0
:
v
.
co
.
z
=
(
round
(
VertDict
[
i
][
2
],
floatPrec
)
*
vt
[
1
]
)
+
(
round
(
v
.
co
.
z
,
floatPrec
)
*
(
1.0
-
vt
[
1
]
)
)
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
Assign
():
if
not
groupSave
:
me
.
addVertGroup
(
"PinGroup"
)
is_editmode
=
Window
.
EditMode
()
if
is_editmode
:
Window
.
EditMode
(
0
)
vertList
=
[]
for
v
in
me
.
verts
:
if
v
.
sel
:
vertList
.
append
(
v
.
index
)
me
.
assignVertsToGroup
(
"PinGroup"
,
vertList
,
weight
.
val
,
Mesh
.
AssignModes
.
REPLACE
)
is_editmode
=
Window
.
EditMode
(
1
)
if
vertList
!=
[]:
HandleText
()
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
Remove
():
HandleGroup
()
if
groupSave
:
is_editmode
=
Window
.
EditMode
()
if
is_editmode
:
Window
.
EditMode
(
0
)
vertList
=
[]
for
v
in
me
.
verts
:
if
v
.
sel
:
vertList
.
append
(
v
.
index
)
me
.
removeVertsFromGroup
(
"PinGroup"
,
vertList
)
is_editmode
=
Window
.
EditMode
(
1
)
if
vertList
!=
[]:
HandleText
()
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
Select
():
is_editmode
=
Window
.
EditMode
()
if
is_editmode
:
Window
.
EditMode
(
0
)
for
vi
in
me
.
getVertsFromGroup
(
"PinGroup"
):
me
.
verts
[
vi
]
.
sel
=
1
is_editmode
=
Window
.
EditMode
(
1
)
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
Deselect
():
is_editmode
=
Window
.
EditMode
()
if
is_editmode
:
Window
.
EditMode
(
0
)
for
vi
in
me
.
getVertsFromGroup
(
"PinGroup"
):
me
.
verts
[
vi
]
.
sel
=
0
is_editmode
=
Window
.
EditMode
(
1
)
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
Clear
():
global
clear
is_editmode
=
Window
.
EditMode
()
if
is_editmode
:
Window
.
EditMode
(
0
)
me
.
removeVertGroup
(
"PinGroup"
)
me
.
addVertGroup
(
"PinGroup"
)
is_editmode
=
Window
.
EditMode
(
1
)
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
Delete
():
HandleGroup
()
if
groupSave
and
delete
.
val
:
is_editmode
=
Window
.
EditMode
()
if
is_editmode
:
Window
.
EditMode
(
0
)
me
.
removeVertGroup
(
"PinGroup"
)
is_editmode
=
Window
.
EditMode
(
1
)
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
main
():
global
me
,
ob_act
,
activeMesh
sce
=
bpy
.
data
.
scenes
.
active
ob_act
=
sce
.
objects
.
active
if
not
ob_act
or
ob_act
.
type
!=
'Mesh'
:
BPyMessages
.
Error_NoMeshActive
()
return
else
:
activeMesh
=
1
is_editmode
=
Window
.
EditMode
()
if
is_editmode
:
Window
.
EditMode
(
0
)
me
=
ob_act
.
getData
(
mesh
=
1
)
if
Blender
.
bylink
:
CheckVertPos
()
else
:
Draw
.
Register
(
gui
,
event
,
button_event
)
if
is_editmode
:
Window
.
EditMode
(
1
)
#________________________________________________________________________________________________
######################################################
# GUI
######################################################
EV_BT_Pin
=
1
EV_TG_Realtime
=
2
EV_NU_Weight
=
3
EV_BT_Assign
=
4
EV_BT_Remove
=
5
EV_BT_Select
=
6
EV_BT_Deselect
=
7
EV_BT_Clear
=
8
EV_BT_Quit
=
9
EV_TG_Delete
=
10
#________________________________________________________________________________________________
def
gui
():
global
gui_tg_pin
,
gui_tg_realtime
,
gui_nu_weight
,
gui_tg_delete
gui_tg_pin
=
Draw
.
Toggle
(
"Pin"
,
EV_BT_Pin
,
5
,
85
,
100
,
25
,
pin
.
val
,
"Toggle pin/unpin"
)
gui_tg_realtime
=
Draw
.
Toggle
(
"rt"
,
EV_TG_Realtime
,
105
,
85
,
20
,
25
,
realtime
.
val
,
"update in realtime (disable for larger meshes)"
)
gui_nu_weight
=
Draw
.
Number
(
"Weight:"
,
EV_NU_Weight
,
5
,
65
,
120
,
20
,
weight
.
val
,
0
,
1
,
"Vertex weight used when assigning"
)
gui_bt_assign
=
Draw
.
PushButton
(
"Assign"
,
EV_BT_Assign
,
5
,
45
,
60
,
20
,
"Assigns selected vertices to
\"
PinGroup
\"
"
)
gui_bt_remove
=
Draw
.
PushButton
(
"Remove"
,
EV_BT_Remove
,
65
,
45
,
60
,
20
,
"Removes selected vertices from
\"
PinGroup
\"
"
)
gui_bt_select
=
Draw
.
PushButton
(
"Select"
,
EV_BT_Select
,
5
,
25
,
60
,
20
,
"Selects vertices belonging to
\"
PinGroup
\"
"
)
gui_bt_deselect
=
Draw
.
PushButton
(
"Desel."
,
EV_BT_Deselect
,
65
,
25
,
60
,
20
,
"Deselects vertices belonging to
\"
PinGroup
\"
"
)
gui_bt_clear
=
Draw
.
PushButton
(
"Clear"
,
EV_BT_Clear
,
5
,
5
,
60
,
20
,
"Clears
\"
PinGroup
\"
and deletes weights"
)
gui_pb_quit
=
Draw
.
PushButton
(
"Quit"
,
EV_BT_Quit
,
75
,
5
,
35
,
15
,
"Exits the script"
)
gui_tg_delete
=
Draw
.
Toggle
(
"d"
,
EV_TG_Delete
,
110
,
5
,
15
,
15
,
delete
.
val
,
"Delete
\"
PinGroup
\"
upon exit"
)
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
event
(
evt
,
val
):
if
evt
in
[
Draw
.
QKEY
,
Draw
.
ESCKEY
,
Draw
.
XKEY
]:
if
save
==
1
:
Text
.
unlink
(
VDict
)
print
"VertDict text deleted"
ob_act
.
clearScriptLinks
()
Delete
()
Draw
.
Exit
()
#________________________________________________________________________________________________
#________________________________________________________________________________________________
def
button_event
(
evt
):
if
evt
==
EV_BT_Pin
:
pin
.
val
=
gui_tg_pin
.
val
if
pin
.
val
:
avoidEmptyCrash
()
# enable pinning
HandleText
()
else
:
ob_act
.
clearScriptLinks
()
# no scriptlink -> no pinning
#----------------------------------------------------
if
evt
==
EV_TG_Realtime
:
if
gui_tg_realtime
.
val
!=
realtime
.
val
:
realtime
.
val
=
gui_tg_realtime
.
val
ob_act
.
clearScriptLinks
()
if
realtime
.
val
:
ob_act
.
addScriptLink
(
scriptName
,
"ObDataUpdate"
)
else
:
ob_act
.
addScriptLink
(
scriptName
,
"ObjectUpdate"
)
#----------------------------------------------------
if
evt
==
EV_NU_Weight
:
weight
.
val
=
gui_nu_weight
.
val
#----------------------------------------------------
if
evt
==
EV_BT_Assign
:
avoidEmptyCrash
()
Assign
()
#----------------------------------------------------
if
evt
==
EV_BT_Remove
:
avoidEmptyCrash
()
Remove
()
#----------------------------------------------------
if
evt
==
EV_BT_Select
:
avoidEmptyCrash
()
Select
()
#----------------------------------------------------
if
evt
==
EV_BT_Deselect
:
avoidEmptyCrash
()
Deselect
()
#----------------------------------------------------
if
evt
==
EV_BT_Clear
:
avoidEmptyCrash
()
Clear
()
#----------------------------------------------------
if
evt
==
EV_BT_Quit
:
if
save
==
1
:
Text
.
unlink
(
VDict
)
print
"VertDict text deleted"
ob_act
.
clearScriptLinks
()
Delete
()
Draw
.
Exit
()
#----------------------------------------------------
if
evt
==
EV_TG_Delete
:
delete
.
val
=
gui_tg_delete
.
val
#________________________________________________________________________________________________
######################################################
# Execution
######################################################
if
__name__
==
'__main__'
:
main
()
if
activeMesh
:
# avoid crash is no mesh is active
HandleGroup
()
if
not
groupSave
:
me
.
addVertGroup
(
"PinGroup"
)
File Metadata
Details
Mime Type
text/x-python
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
3c/18/682c2025f6d087bad2e4c8a186eb
Event Timeline
Log In to Comment