Closed zeffii closed 10 years ago
Does Eval Knieval exist yet?
Controlling 3D cursor is interesting. It is very temporary like chalk art or grease pencil. Useful to mark position and as pivot.
Dealga, how about a node that "accumulate" point collections per frame? Maybe the Evel Knievel can have spreading effect like wet tissue or burned paper.
Dynamic Paint creator Miikah should be involved...
I am going to upgrade again today, hopefully smoother.
Cheers.
experimenting with it now.
it's just for one line assignments to properties that you would otherwise access via bpy
we can assign colors by this
haven't done extensive testing, can break when in render context -- should be possible to retain control of variables tho..
with multysocket?
like formula node? if i do it will use a different name scheme for variables.
x, y, z, i, j, k, l, m, n
and probably lowercase socket name too, this is just confusing, even in formula node, x vs X
I have a feeling having Eval Knieval 3D Cursor could be useful in the ability to evaluate 2 Faces from 2 different object and then Snap it Together.
This is "Snap Together Tool" in Maya:
Or it can be SN scripted in this case.
Just a thought. This might become a new challenge.
it would be great if the node understood when we want to create an output socket instead of input. For example, if an equal sign placed at the beginning and not the end, this will mean a variable assignment to the output socket
that is good idea so we can get properties in a simple way as well as set them
@kosvor, you read my mind, this will happen it's slightly more involved.
@enzyme69 snapping geometry together based on normals of selected faces makes sense as a regular Addon outside of sverchok. I'm pretty sure i've seen addons that do that exact thing in the past.
the multi_socket and adaptable socket code needs good overhaul to handle more scenarios....
imagine being able to drag a line from the eval string box, to any ui slider and have the node get the property automatically.. like in AE pickwhip
Alright that is fine I will observe the new nodes first so many of them.
I will try to imagine what we can do with node that interactively watches 3D cursor...
@enzyme69 there is addon, https://github.com/Cfyzzz/Scripts 1dscripts, there is 3Dmatch function, anf it do exact that you showed - you select 3 vertices, store side and 3d match any object in object mode to this side
@enzyme69 will be cool if blender could snap to center of polygon, as sverchok do with centers of polygons
https://gist.github.com/zeffii/38ce0903d86e2a6783e0 small progress update.
I'm going to add an Eval Knieval
mode to draw_buttons_ext
, when ticked (default) it will always do the exec()
in a try/except
. This is the safest way to use the node in an exploratory way.
If eval knieval
is unticked it will do the try/except
eval string
or mode
changesbad input on eval knieval
mode will cause blender to crash, potentially.
https://gist.github.com/zeffii/ee0f40ced0acaf458daf still a lot of work to do. Am tempted to not let this auto detect in or out.
nice
Zeffii is rocking the Sverchok ass.
Does it convert euler rotation similar to a 4x4 rotation matrix also?
figuring out a conversion scheme is next.. https://gist.github.com/zeffii/fbc928b0ccc28c1d83aa
it's about time to strip out a few fumbling checks.
I think you can simply stick on .to_matrix()
to a prop that is Euler
, for a 4*4 matrix
Nope, a bit more complicated.
>>> e=Euler((90,0,0),'XYZ')
>>> e.to_matrix()
Matrix(((1.0, 0.0, 0.0),
(0.0, -0.4480736255645752, -0.8939966559410095),
(-0.0, 0.8939966559410095, -0.4480736255645752)))
>>> e.to_matrix().to_4x4()
Matrix(((1.0, 0.0, 0.0, 0.0),
(0.0, -0.4480736255645752, -0.8939966559410095, 0.0),
(-0.0, 0.8939966559410095, -0.4480736255645752, 0.0),
(0.0, 0.0, 0.0, 1.0)))
yeah, as long as it can be evalled :)
Of course it should be radians above also, silly of me to write 90. The same works quaternions also.
.. i like to write about these ideas so I have them more solid in the mind, and you guys can change my mind about things. This is also an attempt to starting documenting the node.
I've added EK to beta nodes, but it's super rough (like a diamond). I've not spent much time breaking it, Maybe opening it up to more people will fuel further iteration. Ultimately there could be several types of eval nodes. The more specific a node is the easier it is to write.. General nodes with lots of features are a great clean way to keep reusing code but require rather lengthy flow control guidance to make sure it's doing what it should be. To the point where most of the code is flow control.
Making in / out modes is one of the first changes that will take place. While auto detecting if the string is intended to assign or be assigned (ie In or Out) works OK, behind the scenes it's not very nice code (at least -- not in my hands). Right now to get a value from bpy the node needs something like (will make output socket)
{x} = bpy.data.objects['Cube'].location
# or..shorthand is just as good
=bpy.data.objects['Cube'].location
# or because i've made some aliases
=objs['Cube'].location
# other aliases are for convenience
c = bpy.context
scene = c.scene
data = bpy.data
objs = data.objects
mats = data.materials
meshes = data.meshes
to get data into bpy, so this takes input sockets
# right now there is no shorthand for the assignment
bpy.data.objects['Cube'].location = {x}
# but you can use aliases
objs['Cube'].location = {x}
objs[1].location = {x}
As long as the string can be evalled.
Right now the node changes colour to inform if the eval / exec was a success. But it is also in that 'un-evalled state' until the first successful eval of the string. This only happens if a node is connected. Lots of logic to think about and i'm not sure this is terribly interesting to read.
Right now the Node assumes you know your way around bpy and know what are legal inputs into properties. So parameters that accept several types of variables, for instance .location
can be passes as a Vector()
or as a 3-tuple
. There's no real way to change props that take Strings...
For output, you can get some interesting results - the Debug Print node is essential to figure out what s going on in the event you don't get what you expect. Output (into Sverchok) understands Matrix
, Vector
and tuple
and I expect to add more but they need to be done by hand by someone once, and then even getting a objs[1].data.vertices
could generate a legal vertices socket. etc. etc.
So i am in favour of having separate nodes for in and out. But sharing a lot of the internals through convenience modules.
Played a bit with it, mostly with out.
For removing all socket in inputs or outputs I've found that .clear()
works much better than a for or a while loop when it comes to handling the recursion problems (got two x output sockets before this)
Got euler and quarternion working, corrected the data level for matrix output to be more sane/normal.
cool! setting up the conversion scheme I think is pretty straightforward at this point. There is a problem with props if they are evaluated to None or 0, the if foo
will choke on those. It's not something i've thought about at any length.
.clear()
is new to me. Double sockets, thought i'd resolved that
that recursion caused by the update events is really tricky sometimes. All the time.
this is interesting territory, but i'll hold back for a while.
A good illustration of what text in node does in sverchok mode. https://github.com/nortikin/sverchok/blob/master/nodes/basic/text.py#L400-L407
I'm closing this for now, but have some thoughts on the future of this beast.
At its core Eval Knieval evaluates and takes or sends data. But my plans are growing for it. Some actions can be described succinctly in one line, by thinking of function calls that could represent recurrent needs. Ideas that could be one line expressions, but are only possible at the moment with multiple lines of code.
For example:
# exec the local text file `func_file`
# ----- this file outputs a string literal with coordinates to an
# ----- internal file called `func_output`
# assign ast.literal_eval( texts(`func_output`).as_string()) to the left side.
=eval_text('func_file', 'func_output')
So what? Well. If I am editing func_file
in my own external editor, then evaluate_text()
could check for changes, import them, and execute that new file. I like to define profile points and shapes programatically (not just Python..any useful language)
Also a function to simply read in from a text file, where I might generate that data entirely externally.
# check for dirty flag, update if dirty
# ast.literal_eval(bpy.data.texts['some_data.ext"].as_string())
=read_text("some_data.ext")
This liberates the creation of this kind of geometric input data, and it can be of dynamic nature. I doubt large datasets will be remotely realtime, but file-system look-up times are getting frighteningly fast now.
something like
def eval_text(node, function_text, out_text, update=True):
texts = bpy.data.texts
# this text should be initiated outside of blender or made external.
# if text on filesystem is modified between updates, reload it and
# re-execute it.
text = texts[function_text]
if update:
# might not even work without ui interact
# if text.is_modified:
fp = text.filepath
with open(fp) as new_text:
text.from_string(''.join(new_text.readlines()))
# at this point text is updated and can be executed.
# could be cached in node.
exec(text.as_string())
# if function_text execed OK, then it has written to texts[out_text]
# This file out_text should exist.
out_data = None
if out_text in texts:
out_data = literal_eval(texts[out_text].to_string())
return out_data
There are ways to use use internal files as modules, this assumes that I don't intend to change the python routine... but I do.
This essentially tells the func_text.py
file inside blender to exec
, and then reads the content in out_file.coords
(internal file) . The 3rd param True
is to force update, it is defaulted to True so a bit redundant in the example..
I think this springboards to other ideas, maybe esoteric. People like to control stuff in crazy ways. Examples will follow, and implementation of read_text
. I think the magic of this is, anything could be in func_text.py
, it could be a http request. udp , os command to call code written in some other language an pipe it to out_file.coords
.
A variation of eval_text
could be eval_local
, where the python file might have references to local files and not write to the blender text files at all, instead it would read direct from disc.
OSC (open sound control) over UDP is already partially written.
in live mode (animation running at 10 fps is enough) execute file in external editor, writes to a local file on disk, if update=True this file is written into blender data.texts too.
I might have a local python file and occasionally build / run the file to overwrite the content in the 'shape.coords' file. Example file below, but could be any language which can write to the filesystem. coffeescript through nodejs.
with open('shape.coords', 'w') as outfile:
n = 100
tw = 15/n # tile_Width
nd = 7/n # nib_distance
# go from 2d to 3d
coords = [-tw,-tw,-nd,-tw, tw, nd, tw, tw, nd, tw,-tw,-nd]
f = [coords[i:i+2] for i in range(0, len(coords)-1,2)]
[g.append(0) for g in f]
#print(f)
outfile.write(str(f))
or
with open('shape.coords', 'w') as outfile:
n = 100
tw = 15/n # tile_Width
nd = 7/n # nib_distance
# go from 2d to 3d
c = [-tw,-tw,-nd,-tw, tw, nd, tw, tw, nd, tw,-tw,-nd]
f = [(c[i], c[i+1], 0) for i in range(0, len(c)-1,2)]
print(f)
outfile.write(str(f))
I just get familiar about this node and 3D cursor is now possessed by Eval Knieval.
controlling Material nodes like color, behaves about as slow as when I do it without eval..by hand.. so I think there's some heavy heavy recursion effects going on inside blender.
I started a help doc:
https://gist.github.com/zeffii/527bd6537357629e173f
mostly warning at the moment. want to get that out of the way.
In Do mode:
do_function(filename_do) with x
In Set modeobjs['Cube'].location
(the node has aliases)
In Get mode:eval_text(filename_do, filename_read, True)
read_text(filename_read, True)
Convenience Aliases for all modes
c = bpy.context
scene = c.scene
data = bpy.data
objs = data.objects
mats = data.materials
meshes = data.meshes
* texts = data.texts
I've decided not to restrict the use of ;
but instead prevent creation of multiple sockets...
ok, got it.
I'm a little bored with the Arc code, so some light entertainment. The node nickname is a play on the name famous American stunt devil. Doing really stupid things in the hope it will impress people. http://en.wikipedia.org/wiki/Evel_Knievel
Sometimes we want to do stupid or dangerous things, and right now there's just SN which is fine but it's overkill for certain things. For example if I wanted to control the 3d cursor, why not have a Node which can take arbitrary sockets in and assign values to whatever string the user inserts into the string field.
This node is like formula2 node, but it is specifically for scene/data properties. It will be a nice exercise in dynamic sockets and error handling. This will happen even if it doesn't end up in Sverchok ;)