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.
    • 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