Open ly29 opened 9 years ago
vectorization on some level. main levels of vectorizations - objects and their values. we ned convention
as a model for generating mesh data I still really like SN1's simplicity, but it's rubbish not the most convenient as a modifier of incoming nested data, am quite happy not to bring SN1 to Redux. (potentially a loader to hoist the sv_main function as a class member of a class proper would be interesting to code )
@zeffii Yeah I also like SN1 and osl more style more.
@nortikin please explain a bit more about your thoughts here, vectorization is a main concern of course and most nodes shouldn't have to support it.
@ly29 inputs as [1,2,3][1,2] have to produce two objects with three and two vertices i.e., and it have to occure on all nodes, plus 1 level is objects level, have to be defined by default and deal with objects in all nodes. it is rules
@nortikin Yes, that is one of the main issues that we to fix. The names of things might change a bit but such things will be possible by default, always, for all nodes.
We could even have multiple forms for writing nodes as long as they can describe themselves properly. But a standard form is better.
Some nodes (minority) would be really short to describe because they are essentially Effects. Take Remove Doubles or Intersect Edges, nodes like that could be described in an eval/exec form like
from svrx_base_modules import intersect_verts_edges
inputs("verts") # this named input is special and will always generate a V input
inputs("edges") # now StringProperty, probably we should call it NestedPropery, or IndicesProperty
a, b = intersect_verts_edges("verts", "edges")
outputs("verts", a)
outputs("edges", b)
Remove doubles:
from svrx_base_modules import remove_doubles
inputs("verts")
inputs("edges")
inputs("faces")
distance = ui_slider("distance", dict(default=0.0001, min=0.0))
a, b, c = remove_doubles("verts", "edges", distance)
outputs("verts", a)
outputs("edges", b)
outputs("faces", c)
or
from svrx_base_modules import remove_doubles
v = inputs("verts")
e = inputs("edges")
f = inputs("faces")
distance = ui_slider("distance", dict(default=0.0001, min=0.0))
a, b, c = remove_doubles([v, e, f], [distance])
outputs("verts", a)
outputs("edges", b)
outputs("faces", c)
or even more common
from svrx_base_modules import remove_doubles
v, e, f = inputs("verts", "edges", "faces")
distance = ui_slider("distance", dict(default=0.0001, min=0.0))
a, b, c = remove_doubles([v, e, f], [distance])
outputs("verts", a)
outputs("edges", b)
outputs("faces", c)
or taking that abstraction further by using Mesh to mean verts, edges, faces
from svrx_base_modules import remove_doubles
# 'mesh' would auto inflate to `verts, edges, faces` sockets
v, e, f = inputs("mesh")
distance = ui_slider("distance", dict(default=0.0001, min=0.0))
a, b, c = remove_doubles([v, e, f], [distance])
outputs("mesh", [a, b, c])
here intersect_verts_edges
and remove_doubles
can be defined with zero knowledge of where they're called from..
Then i start to think adding the UI can be a separate file...or section in the same file
from svrx_base_modules import remove_doubles
v, e, f = inputs("mesh")
svrx_prop1 = StringProperty(name='prop1')
svrx_prop2 = IntProperty(name='prop2')
params = [svrx_prop1, svrx_prop2]
def draw(self, context):
... # optional, will draw props in order of appearance in params list.
a, b, c = remove_doubles([v, e, f], params)
outputs("mesh", [a, b, c])
a good time to rethink the naming convention of our socket types. StringsSocket
needs to go.
StringsSocket
is out for sure.
the whole getting data from socket paradigm has to go I think, the node execution unit should be called with the relevant data, for its execution type.
The socket is an indication of data type, not a guarantee unless we enforce type safety on top of python which to me, doesn't seem worth it.
I general I would like to store the blender properties in the socket, not in the node, but this has some limitations so am not sure about it. The problem of course being the we would have to generate a new socket type for each case of say limits in the float property. I wish properties could be individually adjusted with default/min/max etc
I general I would like to store the blender properties in the socket,
right i get ya!
Socket Types
For now I think pynodes are workable but writing our own nodes thing would be a nice challenge.
can we not combine Matrix/Euler/Quaternion as TransformsConstructs
, where the socket/stream has a mode. (just wondering if the separation is needed.. )
I think Curve data would be great too, 10 socket types isn't too bad.. I think @nortikin had objections to raising the socket count?
Node -> Dict
and Dict -> Node
Ideally this should be two parts, one being the blender properties ui location, dimension, the other being the properties of the node as relevant to sverchok execution.
@zeffii A certain amount of sockets is needed I think, the other approach to having many socket types is too have one socket for everything which isn't a good option. I don't think we should enforce type safety however, if you want use color data as vertex locations go ahead.
I don't think we should enforce type safety however, if you want use color data as vertex locations go ahead.
yeah, this fuzzy logic has many positive uses, and it mirrors the behaviour of the shader node trees
exactly
I also think we should copy the socket naming convention from the rest of blender i.e. Name
instead of name
, that being more controversial I understand.
about names - propose tolimit names lenght to 5-6 maximum 8 in Grasshopper there are 1-letter names wich is not cozy, better to inform user in 4 characters, he will understand. Vers Edgs Pols Mats (it is better to stay with its name but put there Euler and quaternion i guess) Float Int Obj Curv Str Bmesh ID (with explanation - it is blender ids) Color and additionaly short: Norm Tang Centr Mask Index Vdonor Vrecip
Have to admit we need basic sockets to be defined, not to use verts+pols in one node and bmesh or obj in other. it should be some kind of basic data-paradigm. If we use bmesh as second basic in hierarhy than obj have to have switch or something like converter we have to have in any case. more types more probllems. Obj and ID can they be combined? And bmesh can be used instead of verts and polygons? we can use bmesh in general cases on modifiers and analyzers, list functions and others, but when generating or work with lowlevel data we need decompose object to bmesh (obviouse it is basic socket) and matrix and than to vertices and polygons and edges and than vertices to digits.
Sorry for many characters
the problem of matrix generator and matrix deform node is not obviouse for user - second float socket for rotation can eat vertex (or vector wich is second problem how to name).
Or we can add Vers in socket class as we do with dot and number of objects, than we have not headake how to name, but have to define behaviour of labeling - in node name Vers
becomes Vers.
in labe but name Norm
becomes VersNorm.
in label for example, or node-creator's name Centr
becomes VersCentr.12
now we have to collect all issues to mind-map, because it helps a lot, at least for me.
On UI I prefer proper names or sensible shortnames. I think 'vers' is not the best. 'verts' is one letter extra and actually means something in English. Similarly with Edges
what's the problem with the extra e? I think the 8 letter max is good, but trying to make shortnames to save one letter if it's already under 8 characters is not so pretty.
you know English better anyway, let it bee. :+1:
polys
, bm
, VNorm
, FNorm
but agreed that simply one letter like grasshopper is a bit too economical :)
it would be awesome if socket nipples had a hover state which could trigger a tooltip for that socket, I haven't seen that anywhere, in blender , but would be handy.
https://gist.github.com/nortikin/eace3b46e85c585b06a0 this has to be in one node (not formula shape node, but make surface from two vertices sequences)
@zeffii even not imagin how. OpenGL popups?
I think is 8 shorter max than needed, for example in one of the most used nodes a socket is called Displacement. Anyway I can live with 8 but agree with @zeffii about clarity.
tooltips would be nice.
@nortikin While such node is needed let us keep this discussion on a more fundamental level
i'm not fussy about going over 8 characters, if it's acceptable for standard Blender nodes, as @ly29 mentions 'Displacement' is 12 and i've never considered that too long. After a while of using new nodes your brain doesn't really read them any more, it works more on position (if the node isn't dynamically naming sockets )
about fuzzy sockets, I think Matrix
socket should accept and implicitly convert Locations / Vectors to a Translate Matrix
, this would allow convenient
rather than
Such conversion rules should be supported.
@ly29
I wish properties could be individually adjusted with default/min/max etc
yeah, this is such a pain, but perhaps it is possible to simply assign a dynamically added Property to a node along the lines of
some_prop = IntProperty(min=0, max=20, step=2)
#later
stored_value = copy.copy(self.some_prop)
del self.some_prop
self.some_prop = IntProperty(min=0, max=40, step=4)
self.some_prop = stored_value
del
is not supported
@zeffii again, rna, not id, maybe node can have id property on fly? oh, no it cannot, for sure
@ly29 material socket with texture assigned to it? we can make unwrap with python, maybe someone wish to assign material and unwrap exact polygon of bmesh (when we decompose bmesh to vertices polygons we lost unwrap layout data and others how to solve?)
I was under the impression that if you have a list of edges from obj.data.edges
, say like edges [0,1,4,5,6,10], and then take a bm
representation of obj.data
, the edges on indices of bm.edges
are not the same as obj.data.edges
, the only shared data are bm.verts
and obj.data.vertices
, bm itself seems to just mangle them for speed reasons. (But ! I do recall seeing a sort function in the bmesh code)
@nortikin I think we might work with bmesh for that.
might but appears several ways to deal to sverchok - first is usual low level, second is bmesh, third objects and scene. Or maybe whan we edit in low level than bmesh not deleted during layout but updated its data - changed vertices - making ensure lookup table and output it? so every bmesh decomposition must meet node called change bmesh data
? it becomes difficult but not see how to deal in other way with bmesh.
or we deal with data as container with bmesh
,matrix
,verts
,edges
,polygons
,textures
,materials
etc. and pipeline of processing layout only change some part of it even if it is not presented as bmesh socket? so from start to end we deal with object containing bmesh? not sure, because we can devide one mesh to parts and how than?
allready problem is how to view bmesh and change it after viewing, we need get it from scene again, it must not happend
after adding any verts + edges + face manually to a bm we must call bm.<type>.ensure_lookup_table()
, i'm not positive it is needed excplicitly when doing a bmesh.ops
operation
Some of the problems you see I don't see. However it is not the stage I am at the moment. I think some things will resolve themselves, some will not however. But then we try to solve them then, incrementally.
guys, we also need vector socket that will have: [x,y,z][dx,dy,dz] and optionally dx,dy,dz can be normalized vector but additionally we can add strength or capasity of each vector in length single value so plain list will consists of 7 numbers [x,y,z,dx,dy,dz,c,...] we can teach viewers to display them (Jimmy Gunnavan asked long ago).
but dx, dy, dz can be inferred at calculation time, it can be a simple separate additional structure for np_Mesh to produce when asked. Storing that information explicitely and allways is not necessary. If we have a node that uses deltas then it can call a function and store all the result to the np_mesh.delta_vectors array
or something.
or make it possible to push an array of deltas at any time onto np_Mesh, same with 'weight' (capacity) w. Separate stream included in np_Mesh.
who knows what else will be needed - vertex colors can be coded just like thhat, so additional dictionaries needed extremely, maybe globally it will cover curve type of data -with addtional handles to knots, so you will have additionally two lists with identical looku table for level 2,3,4... so level 1 wil only lookup as 3 or 1 or 2 numbers depends on what we need. for one object one lookup table wich will decrease memory usage. cool.
Function annotations seems perfect for type info... https://docs.python.org/3/tutorial/controlflow.html#function-annotations
def f(a : int = 2, b: float = 3.0) -> (float, float):
return b, b*a
>>> import inspect
>>> f.__annotations__
{'b': <class 'float'>, 'a': <class 'int'>, 'return': (<class 'float'>, <class 'float'>)}
>>> sig = inspect.signature(f)
>>> str(sig)
"(a:int=2, b:float=3.0) -> (<class 'float'>, <class 'float'>)"
Furthermore in 3.5, will have to review a bit soonish. https://docs.python.org/3/library/typing.html
import numpy as np
def linspace(start : float = 0.0, stop : float = 1.0, count : int = 10) -> ("linspace", np.array):
return np.linspace(start, stop, num)
Something like this could be a complete node for simple cases, like node scripts. Annotations are amazing (not really but a very nice feature). UI could be generated from this. Of course this isn't enough for every node but could go a long way.
@zeffii It would make script node mk1 clearer.
yeah, I would like to commit to doing a massive overhaul of mk1. Looking back at it it seems massively bloated. I'd like to think that I could do better, after a year and half :)
But unfortunately my mother has been seriously ill for a few months and will be operated on tomorrow for the n-th time ... the outcome of which will greatly influence how much time I can commit to this.. and how clear i'll be able to think.
I am sorry to hear about your mother. Take care.
I have been busy lately but I want to boot strap this now, the ideas have been brewing in my head. Yeah, we do learn a lot. Have to get into it again, want at least try some of them out.
I like the fact the fact that with this we could basically have an OSL like simplicity.
Thanks @ly29 . Difficult times, but I do like the distractions and it's why i've been coding in the open a bit more again.
I'm interested to see a less complicated back-end for SN MK1, and wouldn't feel obliged to retain any form of backwards compatibility, scripts should be easy to convert as and when they are needed. Afterall the interface is what would change, the work-code mostly remains unchanged.
Having some typed interface, is kind of what sn mk1 already has, but making it explicit is something i'm all for. (Even if we have to allow custom data types... float vs list..vs np array etc :)
This isn't a finished model.
How should this be accomplished?
Let us at looks some different models to create nodes.
SN1
SN2
Basically there are more or less identical, as I see the most easily inspectable one with types etc is more complex SN2.
What I propose is a python class that provides a functional unit that can be executed on individual pieces of the mesh.