sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Newbie: Drawing state diagrams with Ruby - would this work?

    Scheduled Pinned Locked Moved Developers' Forum
    16 Posts 8 Posters 2.5k Views 8 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S Offline
      stony999
      last edited by

      Hello,

      I am trying to find a tool for creating state diagrams which shall then be executed externally. And so I would like to know whether my following approach would generally be feasible (I am an experienced Ruby programmer):

      • State diagrams consists of boxes and transitions (lines between boxes)
      • Boxes and Transtions(lines) should be selectable through the menu for drawing
      • Boxes have a fixed size from the beginning (may be changed later)
      • Transitions shall be drawn like simple line and shall be connected to 2 boxes
      • By right klicking on a box or transition I receive my own attributes form, where I can add some 5 to 10 attributes
      • I would like to show 2 attributes of the box and 2 attributes of the transition in the drawing. When moving or changing size, attributes should be moved dynamically
      • After saving the drawing, I would like to analize the drawing:
      • Get attributes of each box
      • Get attributes of each transition
      • see which boxes are connected by which transitions

      My general question is: Is that generally achievable with the current Sketchup version 8? As already mentionned, I am an experienced Ruby programmer. But I have no experience with the combination of Sketchup and Ruby yet, so I do not know about the limits and pitfalls.

      Any Help or suggestion is appreciated.

      Best regards
      Peter

      By the way: Can I disable existing menu items, which I do not need, by Ruby?

      1 Reply Last reply Reply Quote 0
      • Chris FullmerC Offline
        Chris Fullmer
        last edited by

        I think that all sounds do-able.

        You can't remove menu items from SketchUp, but you can make your own menu items, and if you make your own tool class (which it sounds like you will based on what you need to do), you can make your own right click context menu (erasing all default menu items there, and replace them with only menu items you make) - so I guess you can remove right click menu items.

        What is your timeline like for this project?

        Lately you've been tan, suspicious for the winter.
        All my Plugins I've written

        1 Reply Last reply Reply Quote 0
        • S Offline
          stony999
          last edited by

          Thanks for your support. I have guessed 1 month for it.
          I have googled around a bit and have read through some script examples, so I understand a bit more now.
          Some questions I have so far for the connection between boxes:

          • is there a way to bind a group (line+text) to a box, so when a box is moved, the line is stretched and the text is moved?
          • How do I then find the line connection between the boxes? Do I have to investigate on coordinates or is there some kind of relation between box and the line+text group?
          • If I have a group of lines (polygon) + text, how do I then get there?

          Best regards
          Peter

          1 Reply Last reply Reply Quote 0
          • GaieusG Offline
            Gaieus
            last edited by

            Hi Peter and welcome.

            This is not really "Newbie" stuff so I am moving the topic to the Developers Forum (down the road, next to the Corner Bar) before we scare away other newbies.

            Chris (and others) will continue helping there (me not as ruby is Greek to me). Have fun!

            Gai...

            1 Reply Last reply Reply Quote 0
            • J Offline
              Jim
              last edited by

              I'm guessing the appeal of SketchUp to you is that it's scriptable using Ruby. But what else appeals to you? Does SketchUp have the look and feel for the type of diagram you have in mind? Do the state diagrams really require a 3D view? Do you expect to be able to manipulate geometry in SketchUp and update your data? (You can.)

              SketchUp does not have any libraries or algorithms built in for you to use. (There's a few helper method in the Geom module.) SketchUp has some intelligence when it comes to connected geometry, but it's almost certainly not what you want.

              SketchUp has just a handful of Entity types, and they are fairly basic objects. Vertices have positions, Edges are made of 2 Vertices, Faces have 3 or more Edges. Curves are a colletion of Edges (and as such are not "real" curves.) Groups/Components are containers of the basic Entities, and have position, scale, and rotation (via a Transformation matrix.) This is the low-level sort of thing you'll be dealing with.

              However, Entities have uniq id's (as any Ruby object) and can also have user defined attributes. So labeling and finding Entities using attributes is easy, which I think you'll find useful.

              If you want to be able to use the mouse to select objects in order to make connections, you're going to need to write a Tool.

              SketchUp's inputbox implementation has 2 widgets - textbox and dropdown menu. If you need anything more sophisticated than that you'll need to use a WebDialog which inlvolved knowing a minimal amount of html and javascript.

              For entities to be dynamic (move) SketchUp has an Amination class, or a simple timer-based animation can be used. If an Entity needs to change in other ways you may be better of deleting it and re-creating a new version.

              But to answer your question, yes it can be achieved to some degree.

              So group, was that a fair assessment?

              Hi

              1 Reply Last reply Reply Quote 0
              • Dan RathbunD Offline
                Dan Rathbun
                last edited by

                I wonder.. if a Ruby bridge exists for OpenOffice.org OpenDraw (it's sort of a Visio clone.)
                If no Ruby bridge, you'd be stuck using OpenBasic (StarBasic,) or another lang.
                http://api.openoffice.org/
                The page list them as: C++, Java, Python, CLI, StarBasic, JavaScript, & OLE

                Now.. IF Google Layout was connected to a Ruby API .. I'd say that it would be better to work in Layout for 'smart' 2D diagrams. But we are all still waiting for that to happen.

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • TIGT Offline
                  TIG Moderator
                  last edited by

                  @stony999 said:

                  Thanks for your support. I have guessed 1 month for it.
                  I have googled around a bit and have read through some script examples, so I understand a bit more now.
                  Some questions I have so far for the connection between boxes:

                  • is there a way to bind a group (line+text) to a box, so when a box is moved, the line is stretched and the text is moved?
                  • How do I then find the line connection between the boxes? Do I have to investigate on coordinates or is there some kind of relation between box and the line+text group?
                  • If I have a group of lines (polygon) + text, how do I then get there?
                    Best regards
                    Peter

                  To move one object with another you need to link them with paired attributes...
                  I use id=Time.now.to_f+rand as it's likely to always return a unique value.
                  Do we have box1, a line that starts at box1, and then ends on box2.
                  Let's assume each 'box' is an instance of a component.
                  Each 'box' has a unique attribute 'id' set when it's created using box1.set_attribute("Diagram", "id", id)
                  When you draw a line from a 'box' your tool reads the box's id with box1_id=box1.get_attribute("Diagram", "id", nil).
                  Unfortunately an object's data-base id is not kept across sessions so an enduring attribute one needs to be made...
                  If there is a box1_id then the new line you added is given two attributes line.set_attribute("Diagram","start",box1_id) for it's start and then you read the id of box2 and use line.set_attribute("Diagram","end",box2_id)...
                  Now the two boxes and the line are linked behind the scenes.
                  Next you need to make an observer that loads at startup and is applied to all suitable objects [you also need to catch it on a new skp opening etc - there are examples in some of my recent tools].
                  Let's assume this 'entity' observer attaches to instances of certain types of component [like 'box'] - [you would also have another observer watching the appropriate definitions themselves to ensure any new instances of them will get the observer attached as they are added to the model - as they get their 'id' too.]. This observer watches to see if the instance [entity] 'changes' - if it does then it kicks in code that reads its 'id', the model.entities are searched for edges with matching start/end attributes and the start/end vertex of the edge is moved with the box to suit using something like entities.tranform_entities(box.transformation, edge.start)
                  This is an outline only but is how I would approach coding this...

                  TIG

                  1 Reply Last reply Reply Quote 0
                  • TIGT Offline
                    TIG Moderator
                    last edited by

                    Here's a quick half-baked example of making box components and linking them with a line that stretches as a box moves

                    =begin
                    (c) TIG 2011
                    =end
                    require 'sketchup.rb'
                    ###
                    def linkedgetoboxes()
                        model=Sketchup.active_model
                        model.start_operation("linkedgetoboxes")
                        defs=model.definitions
                        ents=model.active_entities
                        cbox=defs.add("Box")
                        cbox.entities.add_edges([1,0,0],[0,1,0],[-1,0,0],[0,-1,0],[1,0,0])
                        tr=Geom;;Transformation.new(ORIGIN)
                        box1=ents.add_instance(cbox,tr)
                        id=Time.now.to_f+rand
                        box1.set_attribute("Diagram","id",id)
                        box1.add_observer($boxEntityObserver)
                        tr=Geom;;Transformation.new(Geom;;Point3d.new(100,0,0))
                        box2=ents.add_instance(cbox,tr)
                        id=Time.now.to_f+rand
                        box2.set_attribute("Diagram","id",id)
                        box2.add_observer($boxEntityObserver)
                        edge=ents.add_line(box1.transformation.origin, box2.transformation.origin)
                        edge.set_attribute("Diagram","start", box1.get_attribute("Diagram","id",nil))
                        edge.set_attribute("Diagram","end", box2.get_attribute("Diagram","id",nil))
                        model.commit_operation
                    end
                    ### adds a new component 'Box', places 2 instances, links them with an edge, 
                    ### if you move a box and the line stretches with it...
                    ###
                    ### Obsever for boxes
                    class BoxEntityObserver < Sketchup;;EntityObserver
                        def onChangeEntity(box)
                            return if not box or not id=box.get_attribute("Diagram","id",nil)
                            org=box.transformation.origin
                            model=Sketchup.active_model
                            ents=model.active_entities
                            ents.to_a.each{|edge|
                              next if not edge.class==Sketchup;;Edge
                              if id==edge.get_attribute("Diagram","start",nil)
                                v=edge.start
                                vec=v.position.vector_to(org)
                                ents.transform_by_vectors([v], [vec]) if vec.length!=0
                              end#if
                              if id==edge.get_attribute("Diagram","end",nil)
                                v=edge.end
                                vec=v.position.vector_to(org)
                                ents.transform_by_vectors([v], [vec]) if vec.length!=0
                              end#if
                            }
                        end
                    end
                    ###
                    def makeBoxEntityObserver()
                        $boxEntityObserver = BoxEntityObserver.new if not $boxEntityObserver
                    end
                    makeBoxEntityObserver()
                    ###
                    
                    
                    

                    TIG

                    1 Reply Last reply Reply Quote 0
                    • Dan RathbunD Offline
                      Dan Rathbun
                      last edited by

                      A few of issues:

                      (1) "Connectors" are likely to cross one another. You need to ensure that when they do, that the crossed line is not broken.

                      (2) How will multi-segment connectors be manipulated (edited.) In AutoCAD, these kind of lines are Polyline entities. Clicking on them, causes "vertice handles" to appear, allowing them to be edited, by grabbing a vertex and simply dragging it to another location. Also (in acad,) the Stretch (by Window Select,) will stretch any polyline that the selection window crossed (if you select by lower-right corner and move the mouse to the upper left.. resulting in a dotted selection window.)

                      (3) Could these "connectors" in Sketchup, themselves be a Dynamic Component ?

                      (4) I assume the diagram will be drawn in Top view, on the XY plane ?

                      I'm not here much anymore.

                      1 Reply Last reply Reply Quote 0
                      • Dan RathbunD Offline
                        Dan Rathbun
                        last edited by

                        Another muse:

                        In Visio and/or OpenDraw, the boxes have "connection points" called (I think,) "glue points" where the "connector lines" snap to.

                        I wonder if in Sketchup, we could create a "glue point" Component or Dynamic Component, that could be embedded as a nested entity, of the Box components, lying along an edge. If a Box edge has only 1 "gluepoint" on an edge, the "gluepoint" would position itself at the edge's midpoint. If there are 2 per edge, the "gluepoints" would space themselves at 1/3 divisons along the edge, and so forth.

                        I'm not here much anymore.

                        1 Reply Last reply Reply Quote 0
                        • TIGT Offline
                          TIG Moderator
                          last edited by

                          The simplest form of connectors could be clines - these are not 'sticky' like 'edges'... OR they could be 1" component lines that scale to suit the distance - requires a different 'resizing' code set but doable... In face all parts 'node-boxes' and 'connecting-lines' [that way you could incorporate text or 'arrowheads' etc] could all be components... that move/stretch together.

                          TIG

                          1 Reply Last reply Reply Quote 0
                          • K Offline
                            kwalkerman
                            last edited by

                            Also, what happens if you have a repeating pattern? Say two boxes are connected in such a way, and the user copies and pastes this pattern a number of times. You would need to be able to re-assign id's to each group of components, in order to maintain referential integrity.

                            This is an interesting application for SU, I can certainly think of a number of uses for it.

                            --
                            Karen

                            1 Reply Last reply Reply Quote 0
                            • S Offline
                              stony999
                              last edited by

                              As posted, I saw the benefit in using sketchup in using the programming language Ruby, which I know best of all languages.
                              I understand now that a lot more has to be done in oder to achieve my goals. So maybe some kind of programmable Visio-like stuff would be better.

                              I think I will give OOO Draw and OOO-Basic a try and see how far I will get with that.

                              Thanks to all for your support.

                              1 Reply Last reply Reply Quote 0
                              • J Offline
                                Jim
                                last edited by

                                I was looking forward to Bezier-based leaders, arrows, and text tags, actually. Maybe I could have been more encouraging.

                                Hi

                                1 Reply Last reply Reply Quote 0
                                • P Offline
                                  Pout
                                  last edited by

                                  Why don't you just send the data through JSON to a htmlpage and use that combined with existing chart creator?
                                  Like this one: http://www.anychart.com/products/anychart/overview/

                                  Should be pretty simple.

                                  1 Reply Last reply Reply Quote 0
                                  • Dan RathbunD Offline
                                    Dan Rathbun
                                    last edited by

                                    @pout said:

                                    Why don't you just send the data through JSON to a htmlpage and use that combined with existing chart creator?
                                    Like this one: http://www.anychart.com/products/anychart/overview/

                                    Should be pretty simple.

                                    Are you in the correct topic, Pout?

                                    AnyChart does not produce diagrams, it produces charts.
                                    And yes it's a minimum of 500 dollars "simple".

                                    Jim had some success using GraphViz, which actually has two examples of state diagrams:

                                    • finite state machine* LR(0) state graph

                                    I'm not here much anymore.

                                    1 Reply Last reply Reply Quote 0
                                    • 1 / 1
                                    • First post
                                      Last post
                                    Buy SketchPlus
                                    Buy SUbD
                                    Buy WrapR
                                    Buy eBook
                                    Buy Modelur
                                    Buy Vertex Tools
                                    Buy SketchCuisine
                                    Buy FormFonts

                                    Advertisement