Visual location script with object snapping

Hello,
I have modified Mariano’s (most excelent) visual location script to include snapping, and changing origin. You can use the last selected object as the origin. also, if you move any object within a short distance (adjustable), inline with the origin it will snap to it. For example if selected object is at z = 1, then all other objects moved after script is run, to between 0.5 and 1.5 will snap to 1.

I was thinking this will be mostly helpful for architecture.
This is also my first attempt at any scripting besides game engine.

Can I modify this script which is copyright by Mariano, under GPL? in the top bit it says I can? I dont understand the licensing too well. I would like to develop it more, and include on-screen options. (edit - now included)

Anyway, I hope it’s helpful to someone. The added coding is probably a bit messy. here’s my version.

Update - download current version at http://dazzler77.googlepages.com/snapping.py

Very nice little script indeed. Would be kewl if it worked at the vertex level, also diagonal snapping could be useful (if your planning to add more features). :wink:

Can’t wait till I have time to play around with python+blender. :cool:

I need help to create a GUI for this script!!

  1. I have tried adding this code. please help - what is wrong? I get the error: TypeError: ‘module’ object is not callable
from Blender.BGL import *
glClear(GL_COLOR_BUFFER_BIT)
glRasterPos2d(8, 103)
Text("Visual location: modified:")

Button("Select start", EVENT_SELECT, 100, 10, 80, 18)

def bevent(evt):
    if (evt == EVENT_SELECT):
        Blender.sel = Scene.GetCurrent().getActiveObject().getLocation()    
Register(bevent)
  1. I also don’t understand how you can get the glClear(GL_COLOR_BUFFER_BIT) to operate on the scripts window and not the 3d window.

  2. what is the difference between the code inside:
    script_text = “”" … “”"
    …and the code outside of it? (does inside mean 3d window?) do you actually need script_text = ??

  3. To define a buttion, do you have to use “def bevent(evt)” or “defevent(evt)”? do these events have to be registered? ie. Register bevent?

I also updated the script so you can now choose a vertex as origin, and you can snap objects to the closest vertex, as well as the center, but only when moving objects in object mode. When I get the GUI working I will add edit mode snapping. (and post results)
(Thanks for those suggestions)

Update - got the gui working, added snap to vertex

download at http://dazzler77.googlepages.com/snapping.py

instructions:

  1. Select a object or a vertex the hit “select origin”
  2. Select a destination object or vertexes that you want to snap to x, y or z.

To snap to an object’s centre ,select all verticies when in edit mode.

To allow snapping for one or more verticies, select them in edit mode. This also will stop centre snapping from working. In this mode, make sure there is no object rotation or scale (alt-r, alt-s to clear)

If no vertexes are selected for an object, it will not snap.
Also, to prevent snapping, you can set the tolerence to 0.

That’s it. If you wish to help me, I still need to know a formula for obtaining a vertex’s global coordinates so I can add edit mode snapping. Also, a formula for finding the average location of selected verticies. (I am having trouble doing basic math (multiply/divide) on coordinates. I can’t multiply a coordinate with an integer.

Next task is I will add snap to a grid based on the origin as the starting point. (eg so you can move an object to exacly (eg 2 units) from another.

I appreciate any feedback / requests.

Convert the integer to a float before performing the operation.

eh, a coordinate is three numbers, in a list:

[0,0,0]

so you can’t just multiply by an int, python has no idea how to multiply one number by three,

so use a loop:


for i in coordinate:  # for each number (x, y, z) in the coordinate, represented as i
    i = i * number     # multiply it by your int


you can also change an it to a float by using:
number = float(number)

Thanks for your comments jonathank and jesethemid. It has really helped heaps. I think i’m starting to get the hang of it - but lots of learning to go. I am now able to get the average coordinates of the selected verticies in a mesh. Pls try my script if you like.

one more question: what formula will get the actual coordinates of a vertex, with size and rotation? do you multiply the coordinate with some value?

Hmmm interesting script any chance of getting it to work with armature bones in pose mode ???

now that would be cool :slight_smile:

update: now works in edit mode using x,y and z buttons.

for example if one face (3 or 4 verticies) are selected, and you press the X button, the centre of those verticies will move to the new location on the X axis. The geometry of the face will remain intact.

still haven’t implemented scale and rotation, so use ctrl - alt - a to apply scale and rotation first. When I get this worked out, I will try to apply it with pose mode.

sweet that would be wicked when it works with pose mode :slight_smile:

Question on converting between global an local coordinates:

How do you move a vertice by a value along a global axis? (regardless of the object’s rotation/scale/parenting)

eg move vertice by 2 units on the X global axis?

I know that to find the global coordinates of the vertice, you multiply the local 4D coordinates by the object.matrixWorld. How do you use global coordinates (eg 2,0,0) to get the equivalent local coordinates?

In other words, how do you move a vertice by an amount in global coordinates?

functioncurve, when I figure this out, I should be able to add pose mode in.

OK. i’ve solved my own question. you multiply global coords by object.getInverseMatrix() to get local equivalent.

Script update Starting to work quite well…

now works independant of an object’s scale/rotation. In edit mode select 1 or more verticies, and press x, y, or z to snap it to the selected origin, global coordinates.

Don’t know if it works with child objects yet.
Measurements are currently only between object centres.
also note: in edit mode, have to tab out and back in to edit mode to update display if you’ve selected different verticies (only affects display lines)

and I haven’t forgotten: pose mode…

(ed: to download script, follow the link at the top of this thread)

Totally awesome script! Thanks. As you said; great for architecture!! :smiley:

I have posted a different version of the script: http://dazzler77.googlepages.com/linestest.blend

only works on object mode, but you can have multiple sources, and it acts more like guides in 2d programs.

I can’t get pose mode working, mainly because I can’t tell which bone is selected.

I would like to get some capabilities like sketchup, like when you extrude (push/pull) a face, and click on another face, it snaps to that location. I guess to do that would be to intercept mouse presses to find out which face somehow was selected… and I’m still yet to learn python properly :wink:

If I call the script I get an error: “ImportError: No module named Snap”.

ogoe

If I call the script I get an error: “ImportError: No module named Snap”.

Sorry, I just realised I created a module and had it in my scripts folder. I will update this into the blend file when I get home, in about 7 hours.

It’s fixed now. I have included the module in the blend file (snap.py) but you don’t need it. if it doesn’t work, make sure the script is used in the scriptlink buttons and set to “redraw”