nortikin / sverchok

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

Geodesic objects #459

Closed PKHG closed 9 years ago

PKHG commented 9 years ago

Some time ago I made the "Geodesic_domes" addon suitable for 2.7* To some degree it could be done in SV too. So I tried using Script 2 (analog to the example of lines https://github.com/nortikin/sverchok/issues/458 Seems to work see: sv_tetrahedron

Two things: First is how do I generate the faces?

    @staticmethod
    def make_faces(*param):
        return [[0,1,2],[0,2,3],[0,1,3],[1,2,3]]
    (<snip>inputs)
    outputs = [("v", "Verts", "make_tetraeder"),
                ("s", "Edges", "make_edges"),]
               #(f","Faces", "make_faces")]  <==== ????? does not work

Second if you know geodesic_domes is it a good idea to build (parts) in SV?

Peter

zeffii commented 9 years ago

@PKHG wrap your code snippets in triple backticks for GitHub conversation, or paste a link to the file

zeffii commented 9 years ago

(f","Faces", "make_faces") , there is no f, use "s"

zeffii commented 9 years ago

see the docs for SN MK 2 : https://github.com/nortikin/sverchok/blob/master/docs/nodes/generator/scripted2.rst

ly29 commented 9 years ago

The example grid gen should provide a good starting point. Very simple https://github.com/nortikin/sverchok/blob/master/node_scripts/SN2-templates/grid.py

If it is a good idea or not depends. It is probably a good way to start understanding sverchok

PKHG commented 9 years ago

Thanks zeffie, will do ''' code ''' on newlines ;-)

AND the link to scripted2.rst should probably given to all beginners (like me ;-) thanks!)

from mathutils import Vector

class TetrahedronScript(SvScriptSimpleGenerator):

    @staticmethod
    def make_tetraeder( top_x, top_y, top_z, scale ):
        vertskeleton=[
              (0.0 + top_x *scale , 0.0 + top_y * scale  , 1.73205080757 + top_z*scale ),
              ( 0.0 , -1.63299316185 , -0.577350269185 ),
              ( 1.41421356237 , 0.816496580927 , -0.57735026919 ),
              ( -1.41421356237 , 0.816496580927 , -0.57735026919 )  ]
        return vertskeleton

    @staticmethod
    def make_edges(*param):
        return  [[0,1],[0,2],[0,3],[1,2],[2,3],[1,3]]

    @staticmethod
    def make_faces(*param):
        return [[0,1,2],[0,2,3],[0,1,3],[1,2,3]]

    inputs = [('s', "top_x", 0),
              ('s', "top_y", 0),
              ('s', "top_z", 0),
              ('s','scale', 0.1)]

    outputs = [("v", "Verts", "make_tetraeder"),
                ("s", "Edges", "make_edges"),
                ("s", "Faces", "make_faces")]

sv_tetrahedron_2

zeffii commented 9 years ago

@PKHG ,it's backticks not apostrophes or quotemarks. under the tilde key probably. If you re-edit your previous message you will see I changed them to backticks and added forced python highlighting

PKHG commented 9 years ago

zeffi, understood and seen ;-)

nortikin commented 9 years ago

@PKHG put @ symbol before nickname

zeffii commented 9 years ago

I want to suggest also to look at SN MK1 (the original version). Just because we now have SN MK2 doesn't mean MK1 is defunct.. Unless you are doing clever stuff using Vectorized input, it is debatable whether SN2 is easier to use than SN1. At the very least there are a lot more SN MK1 scripts to use as example.

By vectorized i mean a node can take (for example)

SN2 allows very powerful reuse of code without writing the 'vectorizing' routine explicitly, but the docs are quite clear about this. SN1 on the other hand doesn't assume to know anything about your inputs and outputs and requires you to explicitly state what you want. In a sense SN1 is less abstract than SN2.

ly29 commented 9 years ago

I of course argue for sn2 ( since I wrote it) but sn1 is equally powerful if course. And perhaps simpler.

Sn2 is more like how I imagine a node should work. Not completely yet.

As a side note, I am thinking about making a sn1 compability template for sn2. Another approach would be to load sn1 or sn2 depending on script type. Oh well for later

zeffii commented 9 years ago

I think we're on the same page, but yeah I do think SN1 is easier for beginners who have no need for vectorization yet.. once comfortable with SN1 switching to SN2 should be an obvious step.

But I too may be biased towards SN1 because I wrote it.

PKHG commented 9 years ago

What and where is SN1??? Is it what is found under node_scripts/templates ???

ly29 commented 9 years ago

yes exactly. It was the first script node for sverchok, docs are https://github.com/nortikin/sverchok/blob/master/docs/nodes/generator/scripted.rst and examples in node_scripts/templates

PKHG commented 9 years ago

Ahhh, again one step further ... using text view Ctrl I .. So got apprentice level 2 ;-)

PKHG commented 9 years ago

nice, understood how to use node_scripts/ (both subdirs ) ;) Somewhere describe for newbies???

Octrahederon as SN2 ..

from mathutils import Vector

class OctrahedronScript(SvScriptSimpleGenerator):

    @staticmethod
    def make_octraeder( top_x, top_y, top_z, scale ):
        #old octraeder
        vertskeleton=[(0.0 + top_x * scale,0.0 + top_y * scale ,1.0 + top_z * scale),
                            (0.0,1.0,0.0),
                            (-1.0,0.0,0.0),
                            (0.0,-1.0,0.0),
                            (1.0,0.0,0.0),
                            (0.0,0.0,-1.0)]
        return vertskeleton

    @staticmethod
    def make_edges(*param):
        edgeskeleton=[[0,1],[0,2],[0,3],[0,4],[1,2],[2,3],[3,4],[4,1],
                            [1,5],[2,5],[3,5],[4,5]]
        return edgeskeleton 

    @staticmethod
    def make_faces(*param):
        faceskeleton =[[0,1,2],[0,2,3],[0,3,4],[0,4,1],[1,2,5],[2,3,5],[3,4,5],[4,1,5]]

        return faceskeleton

    inputs = [('s', "top_x", 0),
              ('s', "top_y", 0),
              ('s', "top_z", 0),
              ('s','scale', 0.1)]

    outputs = [("v", "Verts", "make_octraeder"),
                ("s", "Edges", "make_edges"),
                ("s", "Faces", "make_faces")]
nortikin commented 9 years ago

why staticmethod for scripted node?

zeffii commented 9 years ago

or

class OctrahedronScript(SvScriptSimpleGenerator):

    @staticmethod
    def make_octraeder(top_x, top_y, top_z, scale):
        x = top_x * scale
        y = top_y * scale
        z = 1.0 + top_z * scale

        return [
            (x, y, z), (0., 1., 0.), (-1., 0., 0.),
            (0., -1., 0.), (1., 0., 0.), (0., 0., -1.)]

    @staticmethod
    def make_edges(*param):
        return [
            [0, 1], [0, 2], [0, 3], [0, 4], [1, 2], [2, 3],
            [3, 4], [4, 1], [1, 5], [2, 5], [3, 5], [4, 5]]

    @staticmethod
    def make_faces(*param):
        return [
            [0, 1, 2], [0, 2, 3], [0, 3, 4], [0, 4, 1],
            [1, 2, 5], [2, 3, 5], [3, 4, 5], [4, 1, 5]]

    inputs = [
        ('s', "top_x", 0),
        ('s', "top_y", 0),
        ('s', "top_z", 0),
        ('s', 'scale', 0.1)]

    outputs = [
        ("v", "Verts", "make_octraeder"),
        ("s", "Edges", "make_edges"),
        ("s", "Faces", "make_faces")]

static method allows one to use a class function without first making an instance of the class. it also allows you to drop the self

ly29 commented 9 years ago

In this case it mostly to highlight that it is a good idea to not have any extra variables doing hidden things.

PKHG commented 9 years ago

@ly29 Do not understand your comment ;-( Zeffie, why do you suggest the changing coords ot be made ( the x,y,z?) in this case it is not so much clearer ... Yes in this case the extra variables to be returned are NOW superfluous, agreed.

PKHG commented 9 years ago

Easy transformation form geodesic_domes This is an icosaeder

from mathutils import Vector

class IcohedronScript(SvScriptSimpleGenerator):

    @staticmethod
    def make_icosaeder( top_x, top_y, top_z, scale ):
        return [( 0.0  + top_x * scale , 0.0 + top_y * scale , 0.587785252292 + top_z * scale ),
                ( 0.0 , -0.525731096637 , 0.262865587024 ),
                ( 0.5 , -0.162459832634 , 0.262865565628 ),
                ( 0.309016994375 , 0.425325419658 , 0.262865531009 ),
                ( -0.309016994375 , 0.425325419658 , 0.262865531009 ),
                ( -0.5 , -0.162459832634 , 0.262865565628 ),
                ( 0.309016994375 , -0.425325419658 , -0.262865531009 ),
                ( 0.5 , 0.162459832634 , -0.262865565628 ),
                ( 0.0 , 0.525731096637 , -0.262865587024 ),
                ( -0.5 , 0.162459832634 , -0.262865565628 ),
                ( -0.309016994375 , -0.425325419658 , -0.262865531009 ),
                ( 0.0 , 0.0 , -0.587785252292 )    ]

    @staticmethod
    def make_edges(*param):
        return [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (1, 2), (2, 3),
                (3, 4), (4, 5), (5, 1), (1, 6), (2, 6), (2, 7), (3, 7),
                (3, 8), (4, 8), (4, 9), (5, 9), (5, 10), (1, 10), (6, 7),
                (7, 8), (8, 9), (9, 10), (10, 6), (6, 11), (7, 11), (8, 11),
                (9, 11), (10, 11)]

    @staticmethod
    def make_faces(*param):
        return [[0,1,2],[0,2,3],[0,3,4],[0,4,5],[0,5,1],[1,2,6],[2,6,7],
                [2,3,7],[3,7,8],[3,4,8],[4,8,9],[4,5,9],[5,9,10],[5,1,10],
                [1,10,6],[6,7,11],[7,8,11],[8,9,11],[9,10,11],[10,6,11]]

    inputs = [('s', "top_x", 0),
              ('s', "top_y", 0),
              ('s', "top_z", 0),
              ('s','scale', 0.1)]

    outputs = [("v", "Verts", "make_icosaeder"),
                ("s", "Edges", "make_edges"),
                ("s", "Faces", "make_faces")]
PKHG commented 9 years ago

Have a question There are for each of the hedrons THREE types: Point as top, Edge on top or Face on top. The point top are to be seen above. The three list for vertices, edges and faces are a bit changed ... What I need, so to say, is an input parameter: top a point, top an edge, top an face to decide which lists should be returned . What is an (easy) way, do not like THREE files for each of the three cases per hedron. Peter

zeffii commented 9 years ago

@PKHG use the @ symbol also for my name, and let github autocomplete it. This way I receive notification when you mention me.

regarding clarity, my main point was formatting. What code editing software do you use? Blender Texteditor?. I'm tempted to write a Plugin to do auto pep-8 formatting for the TextEditor.

If you find x y z less clear then..

    @staticmethod
    def make_octraeder(top_x, top_y, top_z, scale):
        top_x *= scale
        top_y *= scale
        top_z = 1.0 + top_z * scale  # precedence unclear
        return [
            (xtop_x, top_y, top_z), (0., 1., 0.), (-1., 0., 0.),
            (0., -1., 0.), (1., 0., 0.), (0., 0., -1.)]

it's a style thing, you might disagree. I put these as separate variables to keep their operations out of the coordinate definition, because they are the only coordinate components which are constructed dynamically. If much higher percentage of coordinates were constructed from variables then I would probably not do this.

It's a preference, there is no right or wrong.

zeffii commented 9 years ago

@PKHG regading multiple versions of the hedrons, consider adding an extra input parameter, int, which you can check against

def make_somehedron(top_x, top_y, top_z, scale, orientation):
    if not (orientation in {0, 1, 2}):
        # some default because we can't dynamically lock
        # min/max on sliders (yet)
        orientation = 0

    # rest of logic
ly29 commented 9 years ago

@PKHG My previous comment wasn't that important, I use staticmethod to re enforce that the method should be stateless (most of time). It is okay with ordinary method with a `self`` argument also.

ly29 commented 9 years ago

I'm working on enum support so you could get have 3 states but the int method is also workable.

PKHG commented 9 years ago

@zeffii Will do so and using int to decide what to do, oh so very easy! Thanks!

PKHG commented 9 years ago

@ly29 OK, if that succeeds, the input would be more readable (in place of 1 or 2 or 3 ..) Waiting for it ;-) Greets Peter

PKHG commented 9 years ago

So, tetraeders in 3 orientation as wel as oactaeders and icosaeders transformed to SV Most upper ... kan be moved in x, y or z direction ;-)

from mathutils import Vector
#PKHG>INFO waiting for ... enum_support
#0 = tetraeder_top, 1 = tetraeder_edge, 2 = tetraeder_face
#3 = octraeder_top, 4 = octraeder_edge, 5 = octraeder_face
#6 = icosaeder_top, 7 = icosaeder_edge, 8 = icosaeder_face
# >8 becomes tetraeder_top
class HedronScript(SvScriptSimpleGenerator):

    @staticmethod
    def make_tetraeder(which, top_x, top_y, top_z, scale ):
        x = top_x * scale
        y = top_y * scale
        z = top_z * scale
        #default tetraeder_top
        vertskeleton=[(0.0 + top_x *scale , 0.0 + top_y * scale  , 1.73205080757 + top_z*scale ),
              ( 0.0 , -1.63299316185 , -0.577350269185 ),
              ( 1.41421356237 , 0.816496580927 , -0.57735026919 ),
              ( -1.41421356237 , 0.816496580927 , -0.57735026919 ) ]
        if which == 1: #tetraeder_edge
            vertskeleton = [( x , -1.41421356237 + y , 1.0 + z ),
                      ( x , 1.41421356237 + y  , 1.0 + z),
                      ( 1.41421356237 , 0.0 , -1.0 ),
                      ( -1.41421356237 , 0.0 , -1.0 )]
        elif which == 2: #tetraeder_face
            vertskeleton = [( -1.41421356237 + x , -0.816496580927 + y , 0.57735026919 + z ),
                            ( 1.41421356237 + x, -0.816496580927 + y , 0.57735026919 + z ),
                            ( x , 1.63299316185 + y , 0.577350269185 + z ),
                            ( 0.0 , 0.0 , -1.73205080757 )]
        elif which == 3: #octraeder_top
            vertskeleton = [(0.0 + top_x * scale,0.0 + top_y * scale ,1.0 + top_z * scale),
                            (0.0,1.0,0.0),
                            (-1.0,0.0,0.0),
                            (0.0,-1.0,0.0),
                            (1.0,0.0,0.0),
                            (0.0,0.0,-1.0)]
        elif which == 4: #octraeder_edge
            vertskeleton = [( 0.0 + x , -0.707106781187 + y, 0.707106781187 + z),
                            ( 0.0 + x , 0.707106781187 + y, 0.707106781187 + z),
                            ( 1.0 , 0.0 , 0.0 ),
                            ( -1.0 , 0.0 , 0.0 ),
                            ( 0.0 , -0.707106781187 , -0.707106781187 ),
                            ( 0.0 , 0.707106781187 , -0.707106781187 )]
        elif which == 5: #octraeder_face
            vertskeleton = [( 0.408248458663 + x , -0.707106781187 + y, 0.577350150255 + z),
                            ( 0.408248458663 + x , 0.707106781187 + y, 0.577350150255 + z),
                            ( -0.816496412728 + x , 0.0 + y, 0.577350507059 + z),
                            ( -0.408248458663 , -0.707106781187 , -0.577350150255 ),
                            ( 0.816496412728 , 0.0 , -0.577350507059 ),
                            ( -0.408248458663 , 0.707106781187 , -0.577350150255 )    ]
        elif which == 6: #icosaeder_top
            vertskeleton=[  ( 0.0 + x , 0.0 + y, 0.587785252292 + z),
                            ( 0.0 , -0.525731096637 , 0.262865587024 ),
                            ( 0.5 , -0.162459832634 , 0.262865565628 ),
                            ( 0.309016994375 , 0.425325419658 , 0.262865531009 ),
                            ( -0.309016994375 , 0.425325419658 , 0.262865531009 ),
                            ( -0.5 , -0.162459832634 , 0.262865565628 ),
                            ( 0.309016994375 , -0.425325419658 , -0.262865531009 ),
                            ( 0.5 , 0.162459832634 , -0.262865565628 ),
                            ( 0.0 , 0.525731096637 , -0.262865587024 ),
                            ( -0.5 , 0.162459832634 , -0.262865565628 ),
                            ( -0.309016994375 , -0.425325419658 , -0.262865531009 ),
                            ( 0.0 , 0.0 , -0.587785252292 )]
        elif which == 7: #icosaeder_edge
            vertskeleton=[  ( x , 0.309016994375 + y, 0.5 + z),
                            ( x , -0.309016994375 + y, 0.5 + z),
                            ( -0.5 , 0 , 0.309016994375 ),
                            ( 0.5 , 0 , 0.309016994375 ),
                            ( -0.309016994375 , -0.5 , 0 ),
                            ( 0.309016994375 , -0.5 , 0 ),
                            ( 0.309016994375 , 0.5 , 0 ),
                            ( -0.309016994375 , 0.5 , 0 ),
                            ( -0.5 , 0 , -0.309016994375 ),
                            ( 0.5 , 0 , -0.309016994375 ),
                            ( 0 , 0.309016994375 , -0.5 ),
                            ( 0 , -0.309016994375 , -0.5 )]
        elif which == 8: #icosaeder_face
            vertskeleton=[  ( -0.17841104489 + x, 0.309016994375 + y , 0.46708617948 + z),
                            ( -0.17841104489 + x , -0.309016994375 + y , 0.46708617948 + z),
                            ( 0.35682208977 + x, y , 0.467086179484 + z ),
                            ( -0.57735026919 , 0.0 , 0.110264089705 ),
                            ( -0.288675134594 , -0.5 , -0.11026408971 ),
                            ( 0.288675134594 , -0.5 , 0.11026408971 ),
                            ( 0.57735026919 , 0.0 , -0.110264089705 ),
                            ( 0.288675134594 , 0.5 , 0.11026408971 ),
                            ( -0.288675134594 , 0.5 , -0.11026408971 ),
                            ( -0.35682208977 , 0.0 , -0.467086179484 ),
                            ( 0.17841104489 , -0.309016994375 , -0.46708617948 ),
                            ( 0.17841104489 , 0.309016994375 , -0.46708617948 )]
        return vertskeleton

    @staticmethod
    def make_edges(which, top_x, top_y, top_z, scale):
        edgeskeleton =   [[0,1],[0,2],[0,3],[1,2],[2,3],[1,3]]
        if which > 2 and which < 6: #octaeder
            edgeskeleton =  [[0,1],[0,2],[0,3],[0,4],[1,2],[2,4],[3,4],[1,3],
                            [1,5],[2,5],[3,5],[4,5]]
            if which == 5:
                edgeskeleton =  [[0,1],[0,2],[0,3],[0,4],[1,2],[2,3],[3,4],[1,4],
                            [1,5],[2,5],[3,5],[4,5]]
        elif which == 6: #icosaeder
            edgeskeleton = [[0,1],[0,2],[0,3],[1,2],[2,3],[3,4],[4,5],[5,1],
                            [1,6],[2,6],[2,7],[3,7],[3,8],[4,8],[4,9],[5,10],
                            [1,10],[6,7],[7,8],[8,9],[9,10],[10,6],[6,11],[7,11],
                            [8,11],[9,11],[10,11]]
        elif which == 7:
            edgeskeleton=[  [0,1],[0,7],[0,2],[1,2],[1,4],[1,5],[1,3],[0,3],
                            [0,6],[2,7],[2,8],[2,4],[4,5],[3,5],[3,9],[3,6],
                            [6,7],[7,10],[7,8],[4,8],[4,11],[5,11],[5,9],[6,9],
                            [6,10],[8,10],[8,11],[9,11],[9,10],[10,11]]
        elif which == 8:
            edgeskeleton = [[0,1],[2,1],[2,0],[0,3],[1,3],[1,4],[1,5],[2,5],[2,6],[2,7],[0,7],
                            [0,8],[3,9],[3,4],[5,4],[5,10],[5,6],[7,6],[7,11],[7,8],[3,8],[4,9],
                            [4,10],[6,10],[6,11],[8,11],[8,9],[9,10],[11,10],[11,9]]
        return edgeskeleton

    @staticmethod
    def make_faces(which, top_x, top_y, top_z, scale):
        faceskeleton =  [[0,1,2],[0,2,3],[0,1,3],[1,2,3]]
        if which > 2 and which < 6: #octaeder
            faceskeleton = [[0,1,2],[0,2,3],[0,3,4],[0,4,1],[1,2,5],[2,3,5],[3,4,5],[4,1,5]]
            if which == 4:
                faceskeleton = [[0,1,2],[0,1,3],[0,2,4],[1,2,5],[1,3,5],[0,3,4],[2,4,5],[3,4,5]]
            elif which == 5:
                faceskeleton = [(0,1,2),(0,3,4),(0,1,4),(1,4,5),(2,1,5),(2,3,5),(0,2,3),(3,4,5)]
        elif which == 6: #icosaeder
            faceskeleton =[[0,1,2],[0,2,3],[0,3,4],[0,4,5],[0,5,1],[1,2,6],
                              [2,6,7],[2,3,7],[3,7,8],[3,4,8],[4,8,9],[4,5,9],
                              [5,9,10],[5,1,10],[1,10,6],[6,7,11],[7,8,11],
                              [8,9,11],[9,10,11],[10,6,11]]
        elif which == 7:
            faceskeleton = [[0,1,2],[0,1,3],[0,2,7],[1,2,4],[1,4,5],[1,3,5],[0,3,6],
                            [0,6,7],[2,7,8],[2,4,8],[3,5,9],[3,6,9],[7,8,10],[4,8,11],
                            [4,5,11],[5,9,11],[6,9,10],[6,7,10],[8,10,11],[9,10,11]]
        elif which == 8:
            faceskeleton = [[2,0,1],[0,1,3],[2,1,5],[2,0,7],[1,3,4],[1,5,4],
                            [2,5,6],[2,7,6],[0,7,8],[0,3,8],[3,4,9],[5,4,10],
                            [5,6,10],[7,6,11],[7,8,11],[3,8,9],[4,9,10],[6,11,10],
                            [8,11,9],[11,9,10]]

        return faceskeleton

#        return [[0,1,2],[0,2,3],[0,1,3],[1,2,3]]

    inputs = [('s', "which", 0),
        ('s', "top_x", 0.1),
        ('s', "top_y", 0.1),
        ('s', "top_z", 0.1),
        ('s','scale', 0.1)]

    outputs = [("v", "Verts", "make_tetraeder"),
                ("s", "Edges", "make_edges"),
                ("s", "Faces", "make_faces")]
zeffii commented 9 years ago

@PKHG a suggest, you could already declare some faux enums at the top of the functions

so instead of elif which == 6: #icosaeder: you might have

ICOSAEDER_v1 = 6
OCTAHEDRON_v1 = 3
OCTAHEDRON_v2 = 4

...
elif which == ICOSAEDER_v1:

probably could declare them as class variables outside of the function too?

elif which == self.ICOSAEDER_v1:

this in order to be more descriptive than a digit

zeffii commented 9 years ago

Cool to have these geometric primitives btw!

PKHG commented 9 years ago

@zeffii sure soon after my nap ;-)

ly29 commented 9 years ago

Nice to see this in action.

PKHG commented 9 years ago

@zeffi Hm, in the clinch with variable, will add comments in place of ...

EDIT, code with comments above (replaced old by new)

zeffii commented 9 years ago

I imagine putting those in the class body should work just fine? let me try :)

PKHG commented 9 years ago

@zeffii does the class need an init ? Do not know ij yet worth while to change , comments are clear, aren't they?

zeffii commented 9 years ago

never hurts to experiment.. these aren't big code exercises :)

zeffii commented 9 years ago

I'm of opinion that if a comment can be replaced by a variable name, it probably should. because then the code becomes it's own commenting system. But this is personal

zeffii commented 9 years ago

As users of SN2 not, because we aren't initializing the class with a state of any kind. but @ly29 can talk clearer about this

ly29 commented 9 years ago

@PKHG The class is actually initialized but you can't have any arguments more than

def __init__(self):
     do_stuff

I have been thinking about making some more templates where you can make your own init kind of function which will be called on each run. But for now I prefer stateless classes for these kinds of things. In general there shouldn't be a need for a that, however I do realize there times when it is needed but for now you have to go deeper for that. Also if you find something that you think should work but doesn't please report it.

ly29 commented 9 years ago

The function that loads the class looks like this. Not a work of art but working. https://github.com/nortikin/sverchok/blob/master/utils/script_importhelper.py

zeffii commented 9 years ago

oh i see, self won't be available in the @staticmethod

zeffii commented 9 years ago

So.. dirty.. but interesting: https://gist.github.com/anonymous/a35f200c87d3b7bbdbd9

zeffii commented 9 years ago

@PKHG How you plan to scale these Coordinates, for now only the first coordinate is scaled?, and I also must admit I don't quite understand what top_x,y,z are really supposed to be doing.. But you aren't finished so I eagerly await :)

zeffii commented 9 years ago

and using numpy for ease :) https://gist.github.com/zeffii/ab813b7c877bdf5d182c

PKHG commented 9 years ago

@zeffii So.. dirty.. but interesting: a35f200c87d3b7bbdbd9 indeed, more or less globals?!

I just realize that scaling the geodesics are symmetric, I think with respect to there 'origin' So, the direction to scale should be (vert-orig) for each vertex ... will try ;-). the top_* are done, to not to have boring objects and in fact because of 'learning' to use the system ;-)

PKHG commented 9 years ago

What an easy excercise with numpy ;-)

from mathutils import Vector
from numpy import matrix as npMatrix
#PKHG>INFO waiting for ... enum_support
#0 = tetraeder_top, 1 = tetraeder_edge, 2 = tetraeder_face
#3 = octraeder_top, 4 = octraeder_edge, 5 = octraeder_face
#6 = icosaeder_top, 7 = icosaeder_edge, 8 = icosaeder_face
# >8 becomes tetraeder_top
class HedronScript(SvScriptSimpleGenerator):

    @staticmethod
    def make_tetraeder(which, top_x, top_y, top_z, scale ):
        x = top_x * scale
        y = top_y * scale
        z = top_z * scale
        #default tetraeder_top
        vertskeleton = (npMatrix([(0.0  , 0.0   , 1.73205080757  ),
              ( 0.0 , -1.63299316185 , -0.577350269185 ),
              ( 1.41421356237 , 0.816496580927 , -0.57735026919 ),
              ( -1.41421356237 , 0.816496580927 , -0.57735026919 ) ])*(1.0 + scale)).tolist()
        #vertskeleton = vertskeleton.tolist()
        if which == 1: #tetraeder_edge
            vertskeleton = (npMatrix([( x , -1.41421356237 + y , 1.0 + z ),
                      ( x , 1.41421356237 + y  , 1.0 + z),
                      ( 1.41421356237 , 0.0 , -1.0 ),
                      ( -1.41421356237 , 0.0 , -1.0 )])*(1.0 + scale)).tolist()
        elif which == 2: #tetraeder_face
            vertskeleton = (npMatrix([( -1.41421356237 + x , -0.816496580927 + y , 0.57735026919 + z ),
                            ( 1.41421356237 + x, -0.816496580927 + y , 0.57735026919 + z ),
                            ( x , 1.63299316185 + y , 0.577350269185 + z ),
                            ( 0.0 , 0.0 , -1.73205080757 )])*(1.0 + scale)).tolist()
        elif which == 3: #octraeder_top
            vertskeleton = (npMatrix([(0.0 + top_x * scale,0.0 + top_y * scale ,1.0 + top_z * scale),
                            (0.0,1.0,0.0),
                            (-1.0,0.0,0.0),
                            (0.0,-1.0,0.0),
                            (1.0,0.0,0.0),
                            (0.0,0.0,-1.0)])*(1.0 + scale)).tolist()
        elif which == 4: #octraeder_edge
            vertskeleton = (npMatrix([( 0.0 + x , -0.707106781187 + y, 0.707106781187 + z),
                            ( 0.0 + x , 0.707106781187 + y, 0.707106781187 + z),
                            ( 1.0 , 0.0 , 0.0 ),
                            ( -1.0 , 0.0 , 0.0 ),
                            ( 0.0 , -0.707106781187 , -0.707106781187 ),
                            ( 0.0 , 0.707106781187 , -0.707106781187 )])*(1.0 + scale)).tolist()
        elif which == 5: #octraeder_face
            vertskeleton = (npMatrix([( 0.408248458663 + x , -0.707106781187 + y, 0.577350150255 + z),
                            ( 0.408248458663 + x , 0.707106781187 + y, 0.577350150255 + z),
                            ( -0.816496412728 + x , 0.0 + y, 0.577350507059 + z),
                            ( -0.408248458663 , -0.707106781187 , -0.577350150255 ),
                            ( 0.816496412728 , 0.0 , -0.577350507059 ),
                            ( -0.408248458663 , 0.707106781187 , -0.577350150255 )    ])*(1.0 + scale)).tolist()
        elif which == 6: #icosaeder_top
            vertskeleton=(npMatrix([  ( 0.0 + x , 0.0 + y, 0.587785252292 + z),
                            ( 0.0 , -0.525731096637 , 0.262865587024 ),
                            ( 0.5 , -0.162459832634 , 0.262865565628 ),
                            ( 0.309016994375 , 0.425325419658 , 0.262865531009 ),
                            ( -0.309016994375 , 0.425325419658 , 0.262865531009 ),
                            ( -0.5 , -0.162459832634 , 0.262865565628 ),
                            ( 0.309016994375 , -0.425325419658 , -0.262865531009 ),
                            ( 0.5 , 0.162459832634 , -0.262865565628 ),
                            ( 0.0 , 0.525731096637 , -0.262865587024 ),
                            ( -0.5 , 0.162459832634 , -0.262865565628 ),
                            ( -0.309016994375 , -0.425325419658 , -0.262865531009 ),
                            ( 0.0 , 0.0 , -0.587785252292 )])*(1.0 + scale)).tolist()
        elif which == 7: #icosaeder_edge
            vertskeleton=(npMatrix([  ( x , 0.309016994375 + y, 0.5 + z),
                            ( x , -0.309016994375 + y, 0.5 + z),
                            ( -0.5 , 0 , 0.309016994375 ),
                            ( 0.5 , 0 , 0.309016994375 ),
                            ( -0.309016994375 , -0.5 , 0 ),
                            ( 0.309016994375 , -0.5 , 0 ),
                            ( 0.309016994375 , 0.5 , 0 ),
                            ( -0.309016994375 , 0.5 , 0 ),
                            ( -0.5 , 0 , -0.309016994375 ),
                            ( 0.5 , 0 , -0.309016994375 ),
                            ( 0 , 0.309016994375 , -0.5 ),
                            ( 0 , -0.309016994375 , -0.5 )])*(1.0 + scale)).tolist()
        elif which == 8: #icosaeder_face
            vertskeleton=(npMatrix([  ( -0.17841104489 + x, 0.309016994375 + y , 0.46708617948 + z),
                            ( -0.17841104489 + x , -0.309016994375 + y , 0.46708617948 + z),
                            ( 0.35682208977 + x, y , 0.467086179484 + z ),
                            ( -0.57735026919 , 0.0 , 0.110264089705 ),
                            ( -0.288675134594 , -0.5 , -0.11026408971 ),
                            ( 0.288675134594 , -0.5 , 0.11026408971 ),
                            ( 0.57735026919 , 0.0 , -0.110264089705 ),
                            ( 0.288675134594 , 0.5 , 0.11026408971 ),
                            ( -0.288675134594 , 0.5 , -0.11026408971 ),
                            ( -0.35682208977 , 0.0 , -0.467086179484 ),
                            ( 0.17841104489 , -0.309016994375 , -0.46708617948 ),
                            ( 0.17841104489 , 0.309016994375 , -0.46708617948 )])*(1.0 + scale)).tolist()
        return vertskeleton

    @staticmethod
    def make_edges(which, top_x, top_y, top_z, scale):
        edgeskeleton =   [[0,1],[0,2],[0,3],[1,2],[2,3],[1,3]]
        if which > 2 and which < 6: #octaeder
            edgeskeleton =  [[0,1],[0,2],[0,3],[0,4],[1,2],[2,4],[3,4],[1,3],
                            [1,5],[2,5],[3,5],[4,5]]
            if which == 5:
                edgeskeleton =  [[0,1],[0,2],[0,3],[0,4],[1,2],[2,3],[3,4],[1,4],
                            [1,5],[2,5],[3,5],[4,5]]
        elif which == 6: #icosaeder
            edgeskeleton = [[0,1],[0,2],[0,3],[1,2],[2,3],[3,4],[4,5],[5,1],
                            [1,6],[2,6],[2,7],[3,7],[3,8],[4,8],[4,9],[5,10],
                            [1,10],[6,7],[7,8],[8,9],[9,10],[10,6],[6,11],[7,11],
                            [8,11],[9,11],[10,11]]
        elif which == 7:
            edgeskeleton=[  [0,1],[0,7],[0,2],[1,2],[1,4],[1,5],[1,3],[0,3],
                            [0,6],[2,7],[2,8],[2,4],[4,5],[3,5],[3,9],[3,6],
                            [6,7],[7,10],[7,8],[4,8],[4,11],[5,11],[5,9],[6,9],
                            [6,10],[8,10],[8,11],[9,11],[9,10],[10,11]]
        elif which == 8:
            edgeskeleton = [[0,1],[2,1],[2,0],[0,3],[1,3],[1,4],[1,5],[2,5],[2,6],[2,7],[0,7],
                            [0,8],[3,9],[3,4],[5,4],[5,10],[5,6],[7,6],[7,11],[7,8],[3,8],[4,9],
                            [4,10],[6,10],[6,11],[8,11],[8,9],[9,10],[11,10],[11,9]]
        return edgeskeleton

    @staticmethod
    def make_faces(which, top_x, top_y, top_z, scale):
        faceskeleton =  [[0,1,2],[0,2,3],[0,1,3],[1,2,3]]
        if which > 2 and which < 6: #octaeder
            faceskeleton = [[0,1,2],[0,2,3],[0,3,4],[0,4,1],[1,2,5],[2,3,5],[3,4,5],[4,1,5]]
            if which == 4:
                faceskeleton = [[0,1,2],[0,1,3],[0,2,4],[1,2,5],[1,3,5],[0,3,4],[2,4,5],[3,4,5]]
            elif which == 5:
                faceskeleton = [(0,1,2),(0,3,4),(0,1,4),(1,4,5),(2,1,5),(2,3,5),(0,2,3),(3,4,5)]
        elif which == 6: #icosaeder
            faceskeleton =[[0,1,2],[0,2,3],[0,3,4],[0,4,5],[0,5,1],[1,2,6],
                              [2,6,7],[2,3,7],[3,7,8],[3,4,8],[4,8,9],[4,5,9],
                              [5,9,10],[5,1,10],[1,10,6],[6,7,11],[7,8,11],
                              [8,9,11],[9,10,11],[10,6,11]]
        elif which == 7:
            faceskeleton = [[0,1,2],[0,1,3],[0,2,7],[1,2,4],[1,4,5],[1,3,5],[0,3,6],
                            [0,6,7],[2,7,8],[2,4,8],[3,5,9],[3,6,9],[7,8,10],[4,8,11],
                            [4,5,11],[5,9,11],[6,9,10],[6,7,10],[8,10,11],[9,10,11]]
        elif which == 8:
            faceskeleton = [[2,0,1],[0,1,3],[2,1,5],[2,0,7],[1,3,4],[1,5,4],
                            [2,5,6],[2,7,6],[0,7,8],[0,3,8],[3,4,9],[5,4,10],
                            [5,6,10],[7,6,11],[7,8,11],[3,8,9],[4,9,10],[6,11,10],
                            [8,11,9],[11,9,10]]

        return faceskeleton

    inputs = [('s', "which", 0),
        ('s', "top_x", 0.1),
        ('s', "top_y", 0.1),
        ('s', "top_z", 0.1),
        ('s','scale', 0.1)]

    outputs = [("v", "Verts", "make_tetraeder"),
                ("s", "Edges", "make_edges"),
                ("s", "Faces", "make_faces")]

@zeffy @ly29

Now the scale is used to scale the object. I new that numpy is a superb Python package and as it was not yet in Blender I succeeded to get it to work in Blender. But now just an import of what on needs and Peter is happy to use it ;-)

zeffii commented 9 years ago

@PKHG , don't type my name, hit @ and press z, and hit enter.

NumPy does ship with most distributions of Blender, as of 2.71. We even made it one of the requirements for Sverchok (See first 10 lines of readme). It is used in the Vector Interpolation node.

But i rename the python folder inside /Blender/2.72/ to _python so blender uses my local py3.4, it has other nice libraries that Blender would never ship with.

And yes, numpy is crazy convenient :+1:

PKHG commented 9 years ago

@zeffii What does renaming /2.72/python to /s.72/_python do exactly? You mean you let your Python (3.4) live there totally? With all personal included libraries?

The example of vector interpolation ... I just do not like pictures as ONLY information ... export json ... is much more convenient (exceptions possible) ;-)

zeffii commented 9 years ago

@PKHG The mathutils.Vector import is also superfluous. You don't use the Vector class in this case, coordinates are mere 3 element iterables.

Renaming python to _python (or deleting it), means blender won't find its own python and will look on the system and path in the obvious places. image

yes, we can use our favourite libraries -- but doing so can make your code less portable to other people's machine as you can imagine. But numpy is distributed with most Blender compiles now, so that's safe (mostly!..)

PKHG commented 9 years ago

@zeffii Not beeing anymore portable if using not in Blender distribution available packages is clear ...