sketchucation logo sketchucation
    • Login
    πŸ€‘ SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

    Curved surfaces with Ruby

    Scheduled Pinned Locked Moved Developers' Forum
    8 Posts 3 Posters 951 Views 3 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.
    • A Offline
      alexmojaki
      last edited by

      Hi,

      I'm trying to understand how to work with curved surfaces in SU using Ruby. I'd like to, for example, get an array of face objects that make up a surface. The API documentation seems very poor as it says that Faces are flat polygons, but when I select the outside of a cylinder, the Ruby console tells me it's a Face object. I tried using add_faces_from_mesh, but it just splits the surface into one of the component faces and the remaining surface, and returns 0.

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

        Make a cylinder.
        Have View > Hidden Geometry OFF.
        Pick the curved part.
        It selects as one object.
        Entity Info says it's a 'Surface'.

        Deselect it.
        Have View > Hidden Geometry ON.
        You can now see the facets making the surface.
        Pick a facet.
        Entity Info says it's a 'Face'.

        Faces that share common edge, where those edges are 'smooth' are part of a surface.
        Within Sketchup when hidden geometry is 'off' these select as a single object, take materials as a single thing etc...

        Within Ruby a 'surface' is not very much accessible.
        Its faces and edges etc are.
        There is one 'trick' surface using selections...
        selection.is_surface?
        This determines if the selection contains only all of the faces that are part of a single curved surface. Returns:
        True if the selection contains all of the faces that belong to a single curved surface.
        False if the selection does not contain all of the faces that belong to a single curved surface.

        Since a surface's faces are all connected and their shared edges are smooth? you can devise ways of getting all of the faces in a surface from one face in that surface...
        What is the intention of your code ?

        TIG

        1 Reply Last reply Reply Quote 0
        • A Offline
          alexmojaki
          last edited by

          @tig said:

          Since a surface's faces are all connected and their shared edges are smooth? you can devise ways of getting all of the faces in a surface from one face in that surface...
          What is the intention of your code ?

          I'd like to know:

          All the points/vertices that make the surface.
          All the normals of the faces that make up the surface.

          I also want to be able to take a set of points and project them onto the surface, or rather find the intersection point between a ray and the surface.

          Your suggestion about connected faces is a bit vague. I would still need to be able to get one of the faces in the surface (without help from the user) and I don't know what makes an edge 'smooth'.

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

            Starting at the end...
            Iterate the faces.
            edges=face.edges
            Iterate the edges
            edge.smooth? >> true or false
            An edge can also have .soft? and .hidden? true/false.
            To find all of the faces connected to a selected_face use
            connected_faces=selected_face.all_connected.find_all{|e|e.is_a?(Sketchup::Face)}
            To find all faces connected to the selected_face that are have a smooth edge and are thereby part of a common 'surface' you need to iterate the connected_faces in turn and their edges, testing for edge.smooth? and if so add that face to an array (which you kick off with surface=[selected_face]) unless it's already there, like surface<<face unless surface.include?(face) assuming a test tells us it has a smooth common edge. As you collect faces then face=surface[-1] so you keep moving out from the first face until no more faces are available/connected-smoothly...
            How are you 'getting' the face ? You say you don't want help from the user, BUT there must be some clue to 'get' it πŸ˜•
            If the user is preselecting it and hidden-geometry is off then that selection consists of all connected faces anyway ? So then selection.to_a should be 'all connected faces' ??

            Once you have the faces then their vertices are easy to collect.
            verts=[] faces.each{|f|verts<<f.vertices} verts.flatten.uniq!
            The array 'verts' is now all of the vertices used by the faces.

            Similarly the normals
            normals=[] faces.each{|f|normals<<f.normal}

            If you make the surface as a group then
            ray=model.raytest(point, vector)
            returns nil for a miss OR an array of a point and an array of what's been hit.
            To check that the hit is on the group use ray[1].include?(group) which is true if the containing groups is hit.
            A typical hit 'ray' might be something like [point3d, [group,face]]
            The hit 'point' is ray[0]

            TIG

            1 Reply Last reply Reply Quote 0
            • A Offline
              alexmojaki
              last edited by

              @tig said:

              selection.to_a should be 'all connected faces' ??

              THAT's what I needed! Thanks! I should have probably spotted that before, but I made a silly mistake in my experimentations with the console and got myself thinking that when I selected a surface, Ruby thought the whole thing was just one face.

              1 Reply Last reply Reply Quote 0
              • thomthomT Offline
                thomthom
                last edited by

                If you want to get a Surface - identical to how SketchUp defines with - when Entity Info display Surface - based on faces connected by soft+smooth edges when this snippet works: http://forums.sketchucation.com/viewtopic.php?f=180&t=41211#p365381

                Thomas Thomassen β€” SketchUp Monkey & Coding addict
                List of my plugins and link to the CookieWare fund

                1 Reply Last reply Reply Quote 0
                • A Offline
                  alexmojaki
                  last edited by

                  @thomthom said:

                  If you want to get a Surface - identical to how SketchUp defines with - when Entity Info display Surface - based on faces connected by soft+smooth edges when this snippet works: http://forums.sketchucation.com/viewtopic.php?f=180&t=41211#p365381

                  Awesome! That snippet was exactly what I needed and it works great. Also glad to understand what soft and smooth edges are.

                  Thanks a lot!

                  1 Reply Last reply Reply Quote 0
                  • thomthomT Offline
                    thomthom
                    last edited by

                    @alexmojaki said:

                    Also glad to understand what soft and smooth edges are.

                    For a detailed breakdown of what each property does (soft and smooth has very distinct functions) check out this article: http://www.thomthom.net/thoughts/2012/06/soft-vs-smooth-vs-hidden-edges/

                    Thomas Thomassen β€” SketchUp Monkey & Coding addict
                    List of my plugins and link to the CookieWare fund

                    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