• Login
sketchucation logo sketchucation
  • Login
ℹ️ GoFundMe | Our friend Gus Robatto needs some help in a challenging time Learn More

Reading a file in Ruby

Scheduled Pinned Locked Moved Developers' Forum
17 Posts 5 Posters 1.5k Views
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.
  • W Offline
    wsellers89
    last edited by 18 May 2010, 11:58

    I don't know if this is the right Forum to post this, but can any one tell me how to read in a file of comma separated x-y values in ruby. I am using a Mac Pro if that makes a difference.

    Thanks

    1 Reply Last reply Reply Quote 0
    • C Offline
      Chris Fullmer
      last edited by 18 May 2010, 16:40

      Sure, how much code do you have already? And what would you like to do with the imported data?

      Chris

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

      1 Reply Last reply Reply Quote 0
      • W Offline
        wsellers89
        last edited by 18 May 2010, 17:51

        Just beginning with Ruby. To start off simple, all I would like to do is read in the x,y points from a file and then connect them with a line.

        1 Reply Last reply Reply Quote 0
        • T Offline
          TIG Moderator
          last edited by 18 May 2010, 18:17

          Set your filepath by using UI.openpanel(...) http://code.google.com/apis/sketchup/docs/ourdoc/ui.html#openpanel OR hard-code it in - if you get back-slashes in your path ..\folder\file.dat swap them for forward slashes for other ruby use filepath.tr!("\\","/")
          Then you open the file for reading...
          lines=IO.readlines(filepath)
          Now process the array of lines to get the points as x/y values
          points=[] lines.each{|line| x=line.split(",")[0].to_f y=line.split(",")[1].to_f pt=[x,y] points<< pt }
          You now have an array of points.
          To connect points with 'Lines' use
          model=Sketchup.active_model ents=model.active_entities 0.upto(points.length-2) do |i| ents.add_line(points[i],points[i+1]) end#do
          This is not tested but should form the basis for reading the lines in the file and listing the points and making consecutive points joined with lines...
          🤓

          TIG

          1 Reply Last reply Reply Quote 0
          • C Offline
            Chris Fullmer
            last edited by 18 May 2010, 18:50

            TIG, your last bit there to add the lines from the points could be greatly simplified. Instead of adding each line separately with .add_line, you can use the .add_edges. Replace the last chunk of code with this:

            model = Sketchup.active_model entities = model.active_entities entities.add_edges points

            Chris

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

            1 Reply Last reply Reply Quote 0
            • T Offline
              TIG Moderator
              last edited by 18 May 2010, 19:11

              @chris fullmer said:

              TIG, your last bit there to add the lines from the points could be greatly simplified. Instead of adding each line separately with .add_line, you can use the .add_edges. Replace the last chunk of code with this:
              model = Sketchup.active_model entities = model.active_entities entities.add_edges points
              Chris

              I know but I thought he might want to use the points in other ways to - e.g. close the 'loop'...

              TIG

              1 Reply Last reply Reply Quote 0
              • C Offline
                Chris Fullmer
                last edited by 18 May 2010, 20:59

                I had guesses you probably had a good reson for writing it the way you did. But I thought I'd mention just in case you had just forgotten 💚

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

                1 Reply Last reply Reply Quote 0
                • T Offline
                  TIG Moderator
                  last edited by 18 May 2010, 21:19

                  He could even do
                  face=ents.add_face(points) face.erase!
                  To get a loop quickly with no face ???

                  TIG

                  1 Reply Last reply Reply Quote 0
                  • W Offline
                    wsellers89
                    last edited by 18 May 2010, 23:52

                    Dear TIG and Chris,

                    You both are geniuses and I can't thank you enough for your advice! I am attaching what I pieced together based on your inputs, and from info in the Ruby SketchUp programming examples. I put together a quick input file with the coordinates of a parabola just to test out the code, and it works just fine.

                    I am still not sure of some of the finer points of your discussion (e.g. edges versus lines), but this gets me started. Is there a good reference or tutorials for learning more about Ruby on SketchUp? I am experienced in Fortran and to a less extent C, but I can follow most of the the code. I am not sure what ".to_f" does in the loop to parse out the x,y points and would like to know more.

                    I will attach the simple input file in case you are interested.

                    First we pull in the standard API hooks.

                    require 'sketchup'

                    Show the Ruby Console at startup so we Can

                    see any programming errors we may make.

                    Sketchup.send_action "showRubyPanel:"

                    UI.menu("PlugIns").add_item("LinesFromFile") {
                    UI.messagebox("I'm about to import data")

                    #Set your filepath by using

                    filepath = UI.openpanel("Open Data File", "/Users/sellers
                    ", "*.txt")

                    http://code.google.com/apis/sketchup/do ... #openpanel OR

                    hard-code it in - if you get back-slashes in your path ..\folder\file.dat

                    swap them for forward slashes for other ruby use filepath.tr !("\","/")

                    Then you open the file for reading...

                    lines=IO.readlines(filepath)

                    Now process the array of lines to get the points as x/y values

                    points=[]
                    lines.each{|line|
                    x=line.split(",")[0].to_f
                    y=line.split(",")[1].to_f
                    pt=[x,y]
                    points<< pt
                    }

                    You now have an array of points.

                    To connect points with 'Lines' use

                    model=Sketchup.active_model
                    ents=model.active_entities

                    0.upto(points.length-2) do |i|
                    ents.add_line(points[i],points[i+1])
                    end#do

                    }


                    Simple data for a parabola

                    1 Reply Last reply Reply Quote 0
                    • C Offline
                      Chris Fullmer
                      last edited by 19 May 2010, 00:50

                      I put together a few videos on youtube that describe how I like to work in Ruby in SketchUp. It is designed mostly for people with no other programming knowledge like myself, but anyone can watch. Just don't be surprised if its a little basic - especially the first half of the first video.

                      Anyhow, it is the first 6 videos listed in my video page on Youtube here:

                      The first one goes over how to get started and explains a little bit about how to quickyl test code in SketchUp, and it has one quick code example. Then the other ones all show how to perform various short, but useful tasks in ruby.

                      Chris

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

                      1 Reply Last reply Reply Quote 0
                      • T Offline
                        TIG Moderator
                        last edited by 19 May 2010, 08:29

                        The 'lines' v. 'edges' is clouded by the "lines" of text read from the file too !

                        'Line' and 'Edge' have specific means in SUp's API.
                        The example code reads the file as 'lines' [of text] then processes each 'line' [of text].
                        It then makes an array [list] of points from these and then uses those to add_line(p1,p2) stepping through the array of points in pairs. The ents.add_line method adds one 'Line' - or more correctly an 'Edge' - to the SUp entities collection. Chris pointed out that there is another method ents.add_edges(points) where ALL of the Edges are processed en mass from the array of points.

                        The 'Line' tool in SUp is actually an 'Edge' tool - draw a 'Line' and Select it, get Entity Info > 'Edge' !

                        The term 'Line' within the API has a specific meaning relating to an Edge - edge.line which returns a 2 item array of point and a vector - i.e. an Edge's "Line" tells you where the Edge starts and where it's heading to - which can be useful in getting intersections of an Edge's Line and a Plane etc...

                        Another thing to note is that a 'Curve' in the API is not necessarily 'curved' ! An Arc or Circle is a Curve BUT any set of 'joined' Edges are technically a 'Curve' - a 'Polyline' in most other APIs ! There are free tools to join edges into Curves - e.g. weld.rb - which is useful in extruding smooth surfaces and essential with my EEby.. tools that need you to select Curves - if you are trying to use something other than an 'Arc'...

                        TIG

                        1 Reply Last reply Reply Quote 0
                        • M Offline
                          MartinRinehart
                          last edited by 19 May 2010, 20:23

                          @wsellers89 said:

                          I am experienced in Fortran and to a less extent C, but I can follow most of the the code.

                          In most modern languages there is a loop that loops over each member of a group without need for subscripting (and therefor without chance to mess up by going one too far or one too few). In Ruby it's

                          for member in group do process_member_here end

                          For non-trivial processing its

                          
                          for member in group
                              process_member_here
                          end
                          
                          

                          Your job might go like this:

                          
                          first = true
                          for point in points
                              create_edge( prev, point ) unless first
                              prev = point
                              first = false
                          end
                          
                          

                          You'll see many Rubyists write that this way:

                          
                          ...
                          points.each do |point|
                          ...
                          end
                          
                          

                          My tutorial, beginning in Chapter 11 teaches Ruby and the SketchUp API. It has "Topic" boxes for programming beginners. Programmers such as yourself who know coding essentials, but not Ruby, can just read the topic (for example, "Looping") and, if you know what the topic means, you skip over the box.

                          By the by, Chris's You Tube tutorials are a lot more fun.

                          Author, Edges to Rubies - The Complete SketchUp Tutorial at http://www.MartinRinehart.com/models/tutorial.

                          1 Reply Last reply Reply Quote 0
                          • W Offline
                            wsellers89
                            last edited by 20 May 2010, 01:37

                            Is there a SketchUp API command that would let you extract the beginning and end point (x,y,z) of a selected line or edge?

                            1 Reply Last reply Reply Quote 0
                            • W Offline
                              wsellers89
                              last edited by 20 May 2010, 01:57

                              I think that I found my answer by digging into the SketchUp API documentation. Their examples show the following for the edge.start and the edge.end command. Don't know if there is a more elegant way.

                              edge = Sketchup.active_model.entities.add_line([0,0,0],[100,100,0])
                              vertex = edge.start
                              if (vertex)

                              display a pointer to the Vertex

                              UI.messagebox vertex
                              else
                              UI.messagebox "Failure"
                              end
                              point = vertex.position

                              Let's get the Point3d of the vertex

                              if (point)
                              UI.messagebox point
                              else
                              UI.messagebox "Failure"
                              end

                              vertex = edge.end
                              if (vertex)

                              display a pointer to the Vertex

                              UI.messagebox vertex
                              else
                              UI.messagebox "Failure"
                              end
                              point = vertex.position

                              Let's get the Point3d of the vertex

                              if (point)
                              UI.messagebox point
                              else
                              UI.messagebox "Failure"
                              end

                              1 Reply Last reply Reply Quote 0
                              • C Offline
                                Chris Fullmer
                                last edited by 20 May 2010, 04:01

                                Yup, that is one way to do it. Read all the methods available to the edge class:

                                http://code.google.com/apis/sketchup/docs/ourdoc/edge.html

                                You also have edge.vertices available which will return BOTH vertices in one shot.

                                edge = Sketchup.active_model.entities.add_line([0,0,0],[100,100,0]) vertices = edge.vertices position1 = vertices[0].position position2 = vertices[1].position

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

                                1 Reply Last reply Reply Quote 0
                                • T Offline
                                  TIG Moderator
                                  last edited by 20 May 2010, 10:13

                                  As well as getting the two vertices in order as Chris points out there is
                                  vertex0 = edge.start vertex1 = edge.end point0 = vertex0.position point1 = vertex1.position
                                  I made the 'vertices' just for clarity - of course you can miss defining the vertex and jump straight to the point like start_point = edge.start.position etc...
                                  Also the edge.line defines its start thus start_point = edge.line[0], the [1] would return its vector...
                                  You can extract the x/y/z values direct from a point with x=point.x or turn the point into an array with point.to_a where you can still get the x/y/z or 0/1/2 items - points and 3-item arrays are somewhat interchangeable, but watch for traps - so methods require a point rather than an arrays of arrays are 'sortable' while arrays of points are not [but sets are ?]... 😕

                                  TIG

                                  1 Reply Last reply Reply Quote 0
                                  • Dan RathbunD Offline
                                    Dan Rathbun
                                    last edited by 20 May 2010, 23:27

                                    @wsellers89 said:

                                    Is there a good reference or tutorials for learning more about Ruby on SketchUp?

                                    post moved to this topic: "Ruby Docs"

                                    I'm not here much anymore.

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

                                    Advertisement