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)
zeffii commented 10 years ago

having access to a sane node_dict is the only reason SN works

zeffii commented 10 years ago

I need to test VectorMath2 a bit more to see if it still preserves functionality. I think not setting that variable as a BoolProperty is what made it necessary to Try : Except the recursive function calls

zeffii commented 10 years ago

things are never as easy as they seem! Unit tests would definitely make me a lot more confident that the things I've kept in VM2 work as they do in VM1

zeffii commented 10 years ago

https://gist.github.com/zeffii/3b7490c3ebf81590e656 -- this should be tested by people other than me at this point. Shall I commit as a WIP node? and keep it WIP until we decide if its good enough or you want to start over.

ly29 commented 10 years ago

I will be busy for a couple of days. I will try to test it. I don't think it can be less stable than the old one... But let's add the noise functions back so it can work as a simple drop in replacement.

zeffii commented 10 years ago

OK, will add them back - made some other minor changes, then I will commit -- I think this is as far as I can take it without changing the recursion functions (i prefer not to, to keep them snappy)

nortikin commented 10 years ago

what kind of test? i downloaded.

nortikin commented 10 years ago

speed?

zeffii commented 10 years ago

This might be a good opportunity to think about writing unit tests for nodes

oh you are making v2 of Viewer? : )

nortikin commented 10 years ago

no, i marked all that connected after MATH2 as 2

nortikin commented 10 years ago

ALL tested with plane 100*100 and one vertex.

old node 'CROSS' and new node 'CROSS 2'

Updated  Vector Math in:0.065
Updated  Vector Math 2 in:0.0632
Updated  Viewer Draw 2 in:0.0177
Updated  Viewer Draw in:0.0178

DOT PRODUCT & DOT PRODUCT 2

Updated  Vector Math in:0.0831
Updated  Viewer text in:0.0296
Updated  Vector Math 2 in:0.0523
Updated  Viewer text 2 in:0.0309

ADD & ADD 2

Updated  Vector Math in:0.0882
Updated  Vector Math 2 in:0.0447
Updated  Viewer Draw 2 in:0.0148
Updated  Viewer Draw in:0.0147

SUB & SUB 2

Updated  Vector Math in:0.0605
Updated  Vector Math 2 in:0.0583
Updated  Viewer Draw 2 in:0.0195
Updated  Viewer Draw in:0.0197

but with 200*100 plane:

Updated  Vector Math in:0.1351
Updated  Viewer Draw in:0.0278
Updated  Vector Math 2 in:0.0862
Updated  Viewer Draw 2 in:0.0281

LENGTH

Updated  Vector Math 2 in:0.0303
Updated  Viewer text 2 in:0.0241
Updated  Vector Math in:0.032
Updated  Viewer text in:0.0242

DISTANCE

Updated  Vector Math in:0.0398
Updated  Viewer text in:0.0244
Updated  Vector Math 2 in:0.0386
Updated  Viewer text 2 in:0.0243

NORMALIZE

Updated  Vector Math in:0.0394
Updated  Viewer Draw in:0.0145
Updated  Vector Math 2 in:0.0363
Updated  Viewer Draw 2 in:0.0147

NEGATE

Updated  Vector Math in:0.0378
Updated  Viewer Draw in:0.0147
Updated  Vector Math 2 in:0.0758
Updated  Viewer Draw 2 in:0.0147

ANGLE bad result

Updated  Vector Math in:0.0446
Updated  Viewer text in:0.0244
Updated  Vector Math 2 in:0.0455
Updated  Viewer text 2 in:0.0242

PROJECT

Updated  Vector Math in:0.0917
Updated  Vector Math 2 in:0.0463
Updated  Viewer Draw 2 in:0.0149
Updated  Viewer Draw in:0.0146

REFLECT bad result

Updated  Vector Math in:0.0505
Updated  Vector Math 2 in:0.0915
Updated  Viewer Draw 2 in:0.0159
Updated  Viewer Draw in:0.0166
zeffii commented 10 years ago

I don't expect substantial performance increase or decrease, yet. So far it is mostly code shuffle in preparation for potential speed increases. I'm glad it's not drastically, order of magnitude slower.

nortikin commented 10 years ago

new regimes ScalarMult

Updated  Vector Math 2 in:0.0408
Updated  Viewer Draw 2 in:0.0148

DiVIDE scalar

Updated  Vector Math 2 in:0.0811
Updated  Viewer Draw 2 in:0.0151
nortikin commented 10 years ago

With SUB it is ok, i just didn't pressed update, but checked some times after. noise and cell noise will be added?

zeffii commented 10 years ago

adding back now.

zeffii commented 10 years ago

interesting, i'm not able to immediately pinpoint why Angle and reflect would be bad results.. They might be at the very end of the logic queue. this does not make me happy.

zeffii commented 10 years ago

current version: with noise back in : https://gist.github.com/zeffii/be6874678d888332e31d

zeffii commented 10 years ago

reused to the same gist, updated code . cut some stupid logic

nortikin commented 10 years ago

yes, angle not works, but reflect works

ly29 commented 10 years ago

What result do you get for the new one, if you plug in a (1,0,0) and (0,1,0)?

zeffii commented 10 years ago

i get [[1.5707963705062866]]

zeffii commented 10 years ago

which is what blender mathutils.Vector outputs

Vector((1,0,0)).angle((0,1,0)) 1.5707963705062866

ly29 commented 10 years ago

= pi/2, which is correct, maybe add and -Degrees or something for simplicity. It would be very strange if that failed.

zeffii commented 10 years ago

Oh, i thought it was a logical failure and the output was [] or. But what should it be.. I think radians is an OK return value. This is what VectorMath v1 returns too.

ly29 commented 10 years ago

And Scalar math

zeffii commented 10 years ago

With these kinds of nodes you don't want any switches at all in the recursion function. Up to now I have left the math code untouched, but this is the next logical step

zeffii commented 10 years ago

i'd just like to know if it does anything strange (not speed wise) just output wise.

zeffii commented 10 years ago

But speed regression in the end is unacceptable.

zeffii commented 10 years ago

I can give two Angle modes..

scalar_out = {
    "DOT":          (lambda u, v: u.dot(v), 2),
    "DISTANCE":     (lambda u, v: (u - v).length, 2),
    "ANGLE RAD":    (lambda u, v: u.angle(v, 0), 2),
    "ANGLE":        (lambda u, v: degrees(u.angle(v, 0)), 2),
    "LEN":          (lambda u: u.length, 1),
    "NOISE-S":      (lambda u: mathutils.noise.noise(u), 1),
    "CELL-S":       (lambda u: mathutils.noise.cell(u), 1)
}
zeffii commented 10 years ago

with that simple change, also the if statements in the recursion can be dropped -- I think.. by supplying the .to_tuple straight away the in the lambda

nortikin commented 10 years ago

ANGLE DEG

zeffii commented 10 years ago

Okay :)

ly29 commented 10 years ago

@nortikin can you the setup that gave the wrong result?

zeffii commented 10 years ago

https://gist.github.com/zeffii/3050b6be8d4928c62dea latest , this should be faster even though it looks ugly

zeffii commented 10 years ago

(i will solve the ugly)

zeffii commented 10 years ago

those .to_tuple() could be converted to [:] if that wrks and is faster

zeffii commented 10 years ago

https://gist.github.com/anonymous/b45e051131cbf6485649 seems slice is a tiny bit faster consistently, also looks less cluttered

zeffii commented 10 years ago

https://gist.github.com/zeffii/f543616227013264243a streamlined a bit. If this is tested and found stable and not slower, I think i'll stop here.

nortikin commented 10 years ago

http://www.pasteall.org/blend/29790 vector field with math. or something like vector field... don't know. just many cases to field. attractors could make sub of vertices, not distances and to increase/decrease vertex position.

ly29 commented 10 years ago

I did some testing of some ideas I have for a while of flattening the final recursive call, saves us many many calls to recurse_fxy that just calls f. Also avoid fullList for longest list matching to optimize for common case of one vector to many. Tested with a lists of 1000:1000 and 1000:1 vectors. Test against recurse_fxy from the latest gist.

fxy 1000:1000: 1.0623891800059937
fxy2 1000:1000: 0.893612664018292
fxy : 1000:1 1.142882157000713
fxy2: 1000:1 0.6401150920137297

It is a bit ugly but could probably be made prettier... https://gist.github.com/ly29/e4d0a0e91a036aa5a0df

zeffii commented 10 years ago

hmm, double speedups are always interesting. Will read carefully after dinner

zeffii commented 10 years ago

if that's faster it's worth using. I can't help but think there's a much simpler and elegant solution we aren't seeing yet.

ly29 commented 10 years ago

Yes I agree. It is really ugly

zeffii commented 10 years ago

my slow ass machine

fxy 1000:1000: 7.979654606940267
fxy2 1000:1000: 6.551423435101391
fxy : 1000:1 8.914787005052318
fxy2: 1000:1 4.505826089628712
zeffii commented 10 years ago

i see your version does an on the spot replacement of the shortest lists, instead of using fullList. I'm starting to think there's a neat opportunity to use generators to populate the final list, and not make intermediate lists, lazy eval.

The rabbit hole is deep and marvellous.

zeffii commented 10 years ago

https://gist.github.com/zeffii/806773f5325cabb96d4d interesting that many of the Vector operations don't need input params as Vector() but accept any iterable of 3 items

nortikin commented 10 years ago

@zeffii that is reason we use data in sverchok not as Vector itself, but as floats and lists, tuples. it makes life easy sometimes.

ly29 commented 10 years ago

The fact that is isn't needed is reason with vector is reason to offload the vector creation as well to the lambda . It also removes the need for 2 separate recurse_fxy

zeffii commented 10 years ago

agreed, will solve.

zeffii commented 10 years ago

how about just

    # vector -> scalar | vector
    def recurse_fx(self, l, f, leve):
        if not leve:
            return f(l)
        else:
            rfx = self.recurse_fx
            t = [rfx(i, f, leve - 1) for i in l]
        return t

   # vector, vector | scalar -> vector | scalar
    def recurse_fxy(l1, l2, f, leve):
        if not leve:
            return f(l1, l2)

        max_obj = max(len(l1), len(l2))
        fullList(l1, max_obj)
        fullList(l2, max_obj)
        return [recurse_fxy(l1[i], l2[i], f, leve-1) for i in range(max_obj)]

for now