nortikin / sverchok

Sverchok
http://nortikin.github.io/sverchok/
GNU General Public License v3.0
2.24k stars 233 forks source link

Vector Math (multiply by scalar?) #214

Closed zeffii closed 10 years ago

zeffii commented 10 years ago

it's been puzzling me for a while, but where is this?

vector * scalar
vector * (1/scalar)
ly29 commented 10 years ago

Not done yet, please consider doing it. It requires some re factoring of vector math node, which it should probably get anyway... Also we could remove the restrictions for the usual math node and change output type there.

ly29 commented 10 years ago

can be done with formula 2 node actually. which is why havn't gone back an redone vector math node, even though it needs some love. scalar-formula

zeffii commented 10 years ago

Yeah, that works -- but let's make it a proper member of the Vector Math node anyway. OK i will read the vector math node first.

I like the idea of letting the regular math node do vector input, first I'll need to take time to parse this node :)

ly29 commented 10 years ago

just removing type checks should let scalar math node to scalar multiply, then the output have be adjusted of course... To match the different numbers require some structuring of input for nontrivial cases, better give to vector math node.

zeffii commented 10 years ago

I think people will expect to find it in the Vector math node

zeffii commented 10 years ago

I've digested most of this Vector Math node now, interesting read! I think if we go deep with re-factoring it will be dificult to read or extend. It looks deceptively similar, but is different in subtle ways -- I think this might be one reason why it is not already factored.

I've done some minor re-factoring and wonder what exception we are hoping to catch in the try / except. inside update

not tested yet, just optical compilation: https://gist.github.com/zeffii/410985a5c5852c65ff97

ly29 commented 10 years ago

`try`` It hides some errors that occurs on empty input, not really a good solution...

It needs some major changes, it is built on the assumption: one or two vector inputs and scalar or vector output. It needs a new recursive function for the scalar case I think.

ly29 commented 10 years ago

Or offload the responsibility of creating vectors and do .to_tuple to the functions that know that instead of setting the self.scalar_output

zeffii commented 10 years ago

I have some of it working already

zeffii commented 10 years ago

I think it might be best to make it a VectorMath v2 node, I don't want to worry about breaking existing layouts.

ly29 commented 10 years ago

That sounds like good idea, then you can leave out the noise functions since they exit in the noise node now.

zeffii commented 10 years ago

https://gist.github.com/zeffii/83f98b5adde48fd0321d yes, I see that recursive fxy and fxy2 can be merged -- but this might be at the cost of a few cycles every recursion.. ( code still untested btw, still making sense of it)

ly29 commented 10 years ago

The monster of a node. Something seemingly simple creates such amounts of code...

zeffii commented 10 years ago

yeah, hotswapping operation types while retaining connected sockets....brrrrrrrr

ly29 commented 10 years ago

This can be removed if we adress output with index instead of name... Some better way of getting the function also... ChainMap?

if self.outputs and self.outputs[0].links:
...
SvSetSocketAnytype(self,self.outputs[0].name,out)

https://gist.github.com/zeffii/83f98b5adde48fd0321d#file-node_vectormath2-py-L223-L260

ly29 commented 10 years ago

I'll leave that to you, feel a bit guilty for making such a mess to cleanup.

zeffii commented 10 years ago

I was just about to say, this is fantastic to stomp around in. like a kid who gets to jump in a puddle of water for the first time. The puddle is clear, but has strange shapes.

ly29 commented 10 years ago

I am glad you enjoy it. Also the mess in this node made me hold off with the Matrix Math node, which is bad needed.

zeffii commented 10 years ago

funkydonkey https://gist.github.com/zeffii/b4641e399f2af4890801 step2: sit back and think

zeffii commented 10 years ago

image vectorized too

enzyme69 commented 10 years ago

thanks for the example, this should be useful breadcrumbs for eager learners.

zeffii commented 10 years ago

I have a fair understanding of the node now, at least the part I changed. Code style will have to wait till i've tested that it's still 1:1

ly29 commented 10 years ago

Actually no, back to the drawing board.

ly29 commented 10 years ago

Okay missed one detail. Now it correct. What surprises me the most is that the lambda is slightly quicker than the function... Also note the potential in using numpy for at least these cases.

user   0.8943787679891102
Vector 0.2233484220050741
Lambda 0.22744644398335367
Numpy  0.03995985598885454

https://gist.github.com/ly29/c2b714b91b068ac9d914

ly29 commented 10 years ago

In the current structure of creating vector for each function call. Where we create Vector for each function call, note how bad numpy is used the wrong way.

>>> test()
user   0.0768065839947667
Vector 0.06031997298123315
Lambda 0.06056222500046715
Numpy  2.192653567995876

https://gist.github.com/ly29/64ef0392acecbb49d0a2

ly29 commented 10 years ago

The numbers aren't comparable between the two cases, just within them.

zeffii commented 10 years ago

getting closer: https://gist.github.com/zeffii/f47befebfb5f2401d94a

zeffii commented 10 years ago

regarding numpy, yeah -- it's no use trying to leverage numpy without also thinking entirely in Array or Vector idioms. Just like coding in R or Matlab, using explicit loops is not only more code but also objectively slower. The downside, it looks almost nothing like python :)

zeffii commented 10 years ago

interesting results from test-vector.py there @ly29

zeffii commented 10 years ago

very interesting indeed.

ly29 commented 10 years ago

It is actually.

Also a change like this, each operations is responsible for the Vector creation itself.

lambda v: Vector(v).length
lambda u: Vector(u).normalized().to_tuple()

removes the need for

            if self.scalar_output_socket:
                return w
            else:
                return w.to_tuple()
nortikin commented 10 years ago

i have slower mashine...

user   0.07525480200001766
Vector 0.06521201499981544
Lambda 0.06416013800026121
Numpy  3.0802752950003196
ly29 commented 10 years ago

Try other one also @nortikin

nortikin commented 10 years ago
user   0.921621745000266
Vector 0.3146120689998497
Lambda 0.3254137699996136
Numpy  0.06899542500013922
zeffii commented 10 years ago

image

zeffii commented 10 years ago

current state: close https://gist.github.com/zeffii/f47befebfb5f2401d94a it feels a bit lighter to read now.

i've noticed that even with the existing vector_math node, the change in inputs isn't reflected immediately in the UI, and not noticable until one drags from a socket or some other way cause an update to the node. @ly29, @nortikin any pro-tips?

ly29 commented 10 years ago

update=mode_switch in the enum. And then we can separate out the mode switch code from update(self).

zeffii commented 10 years ago

image

ah yes, update_mode

zeffii commented 10 years ago

https://gist.github.com/zeffii/f47befebfb5f2401d94a

ly29 commented 10 years ago

The update function is feels much better now. We (you :) can simplify further I think. But getting the socket logic out of there feels really good.

zeffii commented 10 years ago

The mode_change is what is was called in ListRangeInt -- so for consistency I used that name. Yeah, i'll chip away at it some more.

zeffii commented 10 years ago

i'm pretty sure https://github.com/nortikin/sverchok/blob/master/node_VectorMath.py#L55 should be a BoolProperty

zeffii commented 10 years ago

https://gist.github.com/zeffii/3b7490c3ebf81590e656 I think this works now, (i have to set that variable as a BoolProperty or there is undefined scope )

ly29 commented 10 years ago

Yeah it is really broken. Script node does something similar

zeffii commented 10 years ago

yep, That needs to be fixed.

ly29 commented 10 years ago

But it works but not good.

self.in_sockets

https://github.com/nortikin/sverchok/blob/master/node_Script.py#L301

zeffii commented 10 years ago

I know about the SN usage, i'm surprised that works at all, but I think it has somehting to do with the scope still containing the references to the content in self.in_sockets, self.out_sockets all the way up to self.create_or_update_sockets -- I can remove the Class variables, and pass in_sockets, out_sockets to self.create_or_update_sockets as arguments.

Had i realized class variables can only reliably be of the types provided in bpy.props this could have been avoided.

ly29 commented 10 years ago

The same for me when I wrote Vector Math, also the same that makes that work. Also why spent so much effort on getting node_id to work, for many things it is simply needed.

zeffii commented 10 years ago

These ' funky ' things only come to light when we have deeper knowledge of nodes we didn't code ourselves :)

ly29 commented 10 years ago

Yeah, and then the whole undo stability not being able to reference the scene inside callbacks etc...