sketchucation logo sketchucation
    • Login
    Oops, your profile's looking a bit empty! To help us tailor your experience, please fill in key details like your SketchUp version, skill level, operating system, and more. Update and save your info on your profile page today!
    ⚠️ Important | Libfredo 15.6b introduces important bugfixes for Fredo's Extensions Update

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

    Scheduled Pinned Locked Moved Developers' Forum
    16 Posts 8 Posters 2.7k 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.
    • 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