[ADD ON] Vertex slide - Update 04/09/2011


(ValterVB) #1

Script for vertex slide feature.

Move to contrib add-on

Now UNDO work properly.

 
#***********************************************************************
#ver. 1.0.0: -First version
#ver. 1.0.1: -Now the mouse wheel select in continuos mode the next vertex
#            -Add a marker for the vertex to move
#ver. 1.0.2: -Add check for vertices not selected
#            -Some cleanup
#ver. 1.0.3: -Now the movement is proportional to the mouse movement
#             1/10 of the distance between 2 points for every pixel
#             mouse movement (1/100 with SHIFT)
#ver. 1.0.4: all coordinate as far as possible replaced by vectors
#            view3d_utils are used to define length of an edge on screen!
#            partial simplified logic by PKHG
#ver. 1.0.6: Restore continuous slide, code cleanup
#            Correct the crash with not linked vertex
#ver. 1.0.7: Restore shift, and some code cleanup
#ver. 1.0.8: Restore 2 type of sliding with 2 vertex selected
#ver. 1.0.9: Fix for reverse vector multiplication
#ver. 1.1.0: Delete debug info, some cleanup and add some comments
#ver. 1.1.1: Now UNDO work properly
#ver. 1.1.2: Refactory and some clean of the code.
#            Add edge drawing (from chromoly vertex slide)
#            Add help on screen (from chromooly vertex slide)
#ver. 1.1.3: Now work also with Continuos Grab, some clean on code
#ver. 1.1.4: Remove a lot of mode switching in Invoke. It was too slow 
#            with big mesh.
#ver. 1.1.5: Changed Lay out of the Help and the Key for reverse the 
#            movement. Left/Right arrow rather than Pus/Minus numpad
#ver. 1.1.6: Now the vertex movement is always coherent with Mouse movement
#***********************************************************************
 

Now is like I want :slight_smile:

Link to the wiki: http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Modeling/Vertex_Slide2

Download the script from https://svn.blender.org/svnroot/bf-extensions/contrib/py/scripts/addons/
is called: mesh_vertex_slide.py

With 2 vertices selected:
With the mouse wheel you select wich vertex to move (there is an * near the vertex)
Every time you change the vertex, the slide start from the original position.
Hold the left ALT to start the movement from last position, not from original position.
Isn’t necessary that the 2 vertex are linked. You can select any vertex in the mesh. If you select more than two vertices, the script use the two vertes with minor index.

With 1 vertice selected:
With the mouse wheel you select wich edge to use for the slide (there is an * near the vertex to move)
Every time you change the edge, the slide start from the original position.
Hold the left ALT to start the movement from last position, not from original position.

Hold the left SHIFT for slide lower.
Press NumPad - to reverse the movement and press NumPad + to restore it.


(ValterVB) #2

Well, after some feedback on Italian forum, I have changed a lot of thing.

  • Copy and past the script in text editor and run it (ALT P key)
  • Select 1 or 2 vertex
  • Call the operator: press Space bar and type slide, the operator is named Vertex Slide

First case: Only 1 vertex is selected, the mouse wheel is used for seletc the second vertex in the linked vertices.
Second case: 2 vertex are selected, the mouse wheel doesn’t work but if you use the Left ALT key, you exchange the vertex that you must move

Then, move the mouse left/right and you move the vertex along the line that join the 2 selected vertex.

Press the Left SHIFT key and the movement is more slow

Press Left Button Mouse to be confirmed
Press Right Button Mouse or ESC to be cancel.

Feedback are welcome :slight_smile:

TODO: Add to Special menu (W key in edit mode).

Ciao
Valter


import bpy
from bpy.props import IntProperty, FloatProperty, FloatVectorProperty
from mathutils import Vector
def NewCo(v0,v1,t):
    #Equation of the line
    x = v0.x + (v1.x - v0.x) * t
    y = v0.y + (v1.y - v0.y) * t
    z = v0.z + (v1.z - v0.z) * t
    return Vector((x,y,z))
 
class ModalOperator(bpy.types.Operator):
    bl_idname = "vertex.slide"
    bl_label = "Vertex Slide"
    vert_1_index = -1
    vert_1_co = []
    vert_2_index = -1
    vert_2_co = []
    cont = 0
    step = 100
    offset = FloatVectorProperty(name="Offset", size=3)
 
    left_alt=False  #Used for toggle from the first and the second vertex
    shift=False  #Used for toggle from/to normal to/from precision
 
    MouseX=0
    MouseY=0
 
    Vert=[]
    SecondVertIndex=0
 
    def modal(self, context, event):
        if event.type == 'MOUSEMOVE':
            if self.vert_2_index != -1:
                Vertices = bpy.context.object.data.vertices
                bpy.ops.object.mode_set(mode='OBJECT')
                if self.left_alt:
                    Vertices[self.vert_1_index].co =  NewCo(Vertices[self.vert_1_index].co, Vertices[self.vert_2_index].co,(event.mouse_x-self.MouseX)/self.step )
                else:
                    Vertices[self.vert_2_index].co =  NewCo(Vertices[self.vert_2_index].co, Vertices[self.vert_1_index].co,(event.mouse_x-self.MouseX)/self.step )
                self.MouseX=event.mouse_x
                bpy.ops.object.mode_set(mode='EDIT')
            else:
                Vertices = bpy.context.object.data.vertices
                bpy.ops.object.mode_set(mode='OBJECT')
                Vertices[self.vert_1_index].co =  NewCo(Vertices[self.vert_1_index].co, Vertices[self.Vert[self.SecondVertIndex]].co,(event.mouse_x-self.MouseX)/self.step )
                self.MouseX=event.mouse_x
                bpy.ops.object.mode_set(mode='EDIT')
        if event.type == 'WHEELDOWNMOUSE':
            if self.vert_2_index == -1:
                Vertices = bpy.context.object.data.vertices
                self.SecondVertIndex =self.SecondVertIndex+ 1
                if self.SecondVertIndex >= len(self.Vert)-1:
                    self.SecondVertIndex = len(self.Vert)-1
                bpy.ops.mesh.select_all(action='DESELECT')
                bpy.ops.object.mode_set(mode='OBJECT')
                Vertices[self.vert_1_index].select=True
                Vertices[self.Vert[self.SecondVertIndex]].select=True
                bpy.ops.object.mode_set(mode='EDIT')
 
        if event.type == 'WHEELUPMOUSE':
            if self.vert_2_index == -1:
                Vertices = bpy.context.object.data.vertices
                self.SecondVertIndex =self.SecondVertIndex- 1
                if self.SecondVertIndex < 0:
                    self.SecondVertIndex = 0
                bpy.ops.mesh.select_all(action='DESELECT')
                bpy.ops.object.mode_set(mode='OBJECT')
                Vertices[self.vert_1_index].select=True
                Vertices[self.Vert[self.SecondVertIndex]].select=True
                bpy.ops.object.mode_set(mode='EDIT')
 
        elif event.type == 'LEFTMOUSE':
            return {'FINISHED'}
        elif event.type=='LEFT_ALT':
            self.left_alt = not self.left_alt
        elif event.type == 'LEFT_SHIFT':
            if self.step == 100:
                self.step = 1000
            else:
                self.step = 100
        elif event.type in ('RIGHTMOUSE', 'ESC'):  #Restore and exit
            obj = bpy.context.object
            bpy.ops.object.mode_set(mode='OBJECT')
            obj.data.vertices[self.vert_1_index].co = self.vert_1_co
            if self.vert_2_index != -1:
                obj.data.vertices[self.vert_2_index].co = self.vert_2_co
            bpy.ops.object.mode_set(mode='EDIT')
            return {'CANCELLED'}
        return {'RUNNING_MODAL'}
    def invoke(self, context, event):
        #verificare se serve azzerare le variabili self
        if context.object:
            self._initial_mouse = Vector((event.mouse_x, event.mouse_y, 0.0))
            self.MouseX=event.mouse_x
            self.MouseY=event.mouse_y
            obj = bpy.context.object
            bpy.ops.object.mode_set(mode='OBJECT')
            #Store the original coordinates for Cancel
            for vert in obj.data.vertices:
                if vert.select and self.vert_1_index == -1:
                    self.vert_1_index = vert.index
                    self.vert_1_co = Vector((vert.co.x,vert.co.y,vert.co.z))
                elif vert.select and self.vert_2_index == -1 and vert.index != self.vert_1_index:
                    self.vert_2_index = vert.index
                    self.vert_2_co = Vector((vert.co.x,vert.co.y,vert.co.z))
                    break
            bpy.ops.object.mode_set(mode='EDIT')
 
            if self.vert_2_index == -1:
                #Aggiungo solo i vertici collegati
                self.Vert=[] #Verificare se serve
                bpy.ops.mesh.select_more()
                bpy.ops.object.mode_set(mode='OBJECT')
                for vert in obj.data.vertices:
                    if vert.select:
                        if vert.index != self.vert_1_index:
                            self.Vert.append(vert.index)
                bpy.ops.object.mode_set(mode='EDIT')
                bpy.ops.mesh.select_all(action='DESELECT')
                bpy.ops.object.mode_set(mode='OBJECT')
                obj.data.vertices[self.vert_1_index].select=True #Select the original vertex
                obj.data.vertices[self.Vert[0]].select=True
                bpy.ops.object.mode_set(mode='EDIT')
 
            context.window_manager.modal_handler_add(self)
            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, "No active object, could not finish")
            return {'CANCELLED'}
def register():
    bpy.utils.register_class(ModalOperator)
 
def unregister():
    bpy.utils.unregister_class(ModalOperator)
 
if __name__ == "__main__":
    register()


(LiquidApe) #3

Nice start - you should make it so undo works properly as well. I would also recommend putting in the vertex menu instead of specials (ctrl-v).


(ValterVB) #4

Yes CTRL V maybe is better, but I keep this thing at the end…
For UNDO and 2 or 3 other problems that I have saw I hope to post a new version tomorrow.

Ciao
VB


(BlenderHound) #5

Sliding vertices in blender can be a pain and if you will fix this vertex slide as an add-on you will be my hero.
Thanks and keep up the good job.


(ValterVB) #6

BlenderHound, have you tested the script in the second post? I think that now working but I don’t know if the logic is correct for user in the case you have selected only 1 vertex.

I must add some little thing, but, before I want be sure, that the script is working like the users want :slight_smile:


(MmAaXx) #7

grazie Valter!

ITA: Hai provato a partire dallo script di Chromoly?
ENG: Did you try to start from the Chromoly “vertex slide” script ?

anyway doesnt works for me on 36733 vista64 :frowning:

ciao


(ValterVB) #8

CMmAaXx, no I started from scratch.
I’ll working on it this week end. Here you can find some experiment (Italian forum). I have 2 or 3 ideas about how it must working.

anyway doesnt works for me on 36733 vista64

Strange, now I am out for working so I can’t check.

Ciao
VB


(ValterVB) #9

New version: http://projects.blender.org/tracker/index.php?func=detail&aid=27561&group_id=153&atid=467

Select Attachments tab in bottom of the page.

Copy the Python file in 2.57\scripts\addons

Three modes:

  1. In edit mode select two vertices and call the modifier with CTRL V. Move the mouse from left to right and viceversa for move one vertex. With the mouse wheel you can toggle the vertex to move. Hold the Shift key to slowdown the movement.

  2. In edit mode select one vertex and call the modifier with CTRL V. Move the mouse from left to right and viceversa for move the vertex. With the mouse wheel you can change the edge. The movement start from the original position of the selected vertex. Hold the Shift key to slowdown the movement.

  3. In edit mode select one vertex and call the modifier with CTRL V. Press the ALT key and Move the mouse from left to right and viceversa for move the vertex. With the mouse wheel you can change the edge. The movement start from last position of the selected vertex. Hold the Shift key to slowdown the movement.

Left mouse button to confirm, right mouse button to cancel.

Ciao
Valter


(ValterVB) #10

Link to the wiki. The video is with subtitles in Italian and English.

http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Modeling/Vertex_Slide2

Ciao
Valter


(Carrozza) #11

Thanks Valter, this script will come handy.


(ValterVB) #12

Update (04/06/2011):
Add a marker near the vertex that will be move.

With 2 vertices selected:
With the mouse wheel you select wich vertex to move (there is an * near the vertex)
Every time you change the vertex, the slide start from the original position.
Hold the left ALT to start the movement from last position, not from original position.
Isn’t necessary that the 2 vertex are linked. You can select any vertex in the mesh. If you select more than two vertices, the script use the two vertes with minor index.

With 1 vertice selected:
With the mouse wheel you select wich edge to use for the slide (there is an * near the vertex to move)
Every time you change the edge, the slide start from the original position.
Hold the left ALT to start the movement from last position, not from original position.
If you hold left SHIFT, the movement is more accurate (x10)

I will update the wiki more late with a new video.

Link to the wiki: http://wiki.blender.org/index.php/Extensions:2.5/Py/Scripts/Modeling/Vertex_Slide2

Link for the script: http://projects.blender.org/tracker/index.php?func=detail&aid=27561&group_id=153&atid=467


(ValterVB) #13

Fix for crash if you start the operator without selected vertices
Update the wiki page.

Ciao
Valter


(ValterVB) #14

Now the movement of the vertex is more regular, is proportional to the mouse movement.


(Gwenouille) #15

This is just what I needed !

The funny thing is that I planned to do that myself but never found the time to do it :
http://glp.lescigales.org/it/blender/Vertex%20sliding.pdf

That’s a pdf i made to illustrate what i wanted to do: it must be 2 years old !

Well Done Valter VB !

If you want suggestions, I have plenty !


(PKHG) #16

Valter, your script works very fine! Nice!


(ValterVB) #17

Gwenouille, PKHG thanks

If you want suggestions, I have plenty !

Actually I need some help :slight_smile:

I don’t like how I move the vertex. See the video (the blue circle is the mouse pointer)
First part is Vertex slide, I move the mouse a few pixels but the vertex move more, with a movement of 10 pixel I arrive to the second vertex, always, independently of the distance from the point of view.

Second part is the grabber (G Key in edit mode), the vertex follow always the mouse pointer (independently of the distance from the point of view). Naturally only if the movement is perpendicular to the point of view.
I want a movement like the Grapper. If some one can help me :eyebrowlift2:


(PKHG) #18

Idea:
you need the screen coordinates of the vertex (3d to 2d = screen) (seems to be solved)
you need the mouse coordinates (easy in an addon, class I mean …)
moving the mouse one could measure the screen distance (of the mouse has moved) (I think this is easy … old point next point => delta distance)
this distance has to be computed in a delta-location of the 3D vertex (2d to 3d) and applied to the vertex … THIS is what has to be solved

I will see, if I can help … (was busy with such sort of things …)


(ValterVB) #19

Exactly what I thinked :slight_smile: but, there is a but…
If the point of view isn’t perpendicular to the edge the calculate isn’t correct.

See the pic. I need calculate the distance in 2D coordinate from the selected vertex (marked with *) and a point along the blue line at 1 Blender unit of distance. With this I can do what I want. I think that I must use the View matrix. I will do some experiments with API perspective_matrix more late

https://lh6.googleusercontent.com/-01j3BEqH94w/TfOoZzu3tYI/AAAAAAAAAzI/9IpX6Bzcno0/s800/Immagine.jpg


(PKHG) #20

Valter, look at …\scripts\modules\bpy_extras\view3d_utils.py !!! SVN 374**