• Login
sketchucation logo sketchucation
  • Login
🤑 SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

Surface Outer Loop?

Scheduled Pinned Locked Moved Developers' Forum
11 Posts 5 Posters 603 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.
  • J Offline
    Jim
    last edited by 27 Jan 2013, 15:59

    Any ideas on how to get an ordered list of outer vertices from a surface?

    A surface being a set of faces with possible hidden interior edges and visible outer edges.

    I want to go through the model and create a list of vertices (in order) for each surface in the model.

    Hi

    1 Reply Last reply Reply Quote 0
    • S Offline
      sdmitch
      last edited by 27 Jan 2013, 17:32

      A combination of Select Outer Edges http://sketchucation.com/forums/viewtopic.php?t=20274 and the edge sort routine found in FollowMe and Keep http://sketchucation.com/forums/viewtopic.php?t=16465 should do it.

      Nothing is worthless, it can always be used as a bad example.

      http://sdmitch.blogspot.com/

      1 Reply Last reply Reply Quote 0
      • D Offline
        Dan Rathbun
        last edited by 27 Jan 2013, 17:33

        IDEA: How about creating a Geom::PolygonMesh from the "surface" ?

        The Geom::PolygonMesh class can report hidden edges using a negative value, see it's
        polygons() method.

        I'm not here much anymore.

        1 Reply Last reply Reply Quote 0
        • D Offline
          Dan Rathbun
          last edited by 27 Jan 2013, 20:47

          How about posting some sample surfaces to test with ?

          Here's a shot at it.
          Assume argument surface is an array of Sketchup::Drawingelement subclass objects

            def get_surface_border(surface)
              #
              border = []
              edges  = []
              verts  = []
              #
              t1 = Time.now.to_f
              #
              for f in surface.grep(Sketchup;;Face)
                for e in f.outer_loop
                  edges << e if e.faces.length == 1
                end
              end
              #
              border << edges.pop
              #
              edges.length.times do |n|
                for e in edges
                  border << edges.delete(e) if e.start == border.last.end
                end
              end
              #
              for e in border
                verts << e.start unless verts.include?(e.start)
                verts << e.end unless verts.include?(e.end)
              end
              #
              t2 = Time.now.to_f
              #
              if @@debug
                if edges.empty?
                  puts("All Edges added to border")
                else
                  puts("Edges left over; (#{edges.length})")
                  for e in edges
                    puts("#{e.inspect}")
                    puts("  start( #{e.start.position.x}, #{e.start.position.y}, #{e.start.position.z})")
                    puts("    end( #{e.end.position.x}, #{e.end.position.y}, #{e.end.position.z})")
                  end
                end
                #
                puts("Elapsed Time in secs; #{t1 - t2}")
              end
              #
              return verts
              #
            end # get_surface_border()
          

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • J Offline
            Jim
            last edited by 27 Jan 2013, 21:32

            File has 198 faces, but only 51 surfaces.

            I think I have the surface loops settled - just need to put the edge loop vertices in "loop" order.


            surface-test.skp

            Hi

            1 Reply Last reply Reply Quote 0
            • D Offline
              Dan Rathbun
              last edited by 27 Jan 2013, 22:31

              Never mind lines 9 thru 13, then. I could not tell what you wanted from the meager description in the OP.
              (I assumed the surface edges would bound only 1 face.)

              Something similar to lines 15 thru 26 for sorting.
              (Basically pick an edge, somehow, then find the next edge whose start vertex == the previous one's end vertex.)

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • S Offline
                sdmitch
                last edited by 27 Jan 2013, 22:46

                Unless there is a Sketchup::Surface entity, which doesn't seem to be the case, it would seem to be impossible to isolate the surface from its neighbors. Also since the surfaces are not grouped, the outer_loop edges are shared with the adjacent surface/face and can not be identified using the .face.length==1.

                Dan, your code could work with one tweek. The statement, for e in f.outer_loop needs .edges added to it.

                Nothing is worthless, it can always be used as a bad example.

                http://sdmitch.blogspot.com/

                1 Reply Last reply Reply Quote 0
                • TIGT Offline
                  TIG Moderator
                  last edited by 27 Jan 2013, 23:32

                  It's not impossible - just very convoluted !

                  Pick any face.
                  Find its edges.
                  Discard all edges that are not hidden/soft/smooth.
                  If there are no edges left then it's a lone face.
                  If there are one or more edges remaining then find the faces also using those edges - not including the already 'got' face[s]..
                  These will form part of the 'surface'.
                  Ripple out looking at these faces and their edges in a similar way, collecting the faces that share hidden/soft/smooth edges with them in turn - again not including any faces already 'got'.
                  Eventually you'll have a collection of all faces connected to the first face by 'non-solid' edges - i.e. the faces forming a surface.
                  Now you can get all of the solid-edges that these faces use.
                  Of course some of these solid-edges might not be the surface's 'perimeter' [e.g. a solid edge shared by to faces that are otherwise connected through some non-solid edges and other faces] - these rogues can be discarded simply by looking to see if their faces are all within the faces-collection: all solid-edges that have a face that is not in the surface-set, OR have no other faces will form the surface's perimeter[s].
                  Now go through those and find all connected edges [common vertices] - these edge-sets could be an outer and perhaps one or more 'inner loops'. To order the edge sets into a list on sequential vertices is covered in code like 'weld'... the basis is that you choose an edge in the edge-set and look at its end-vertex, then find the other edge that is in the edge-set that is also using that vertex and then get that edge's other_vertex and so on stepping around, eventually returning to the first edge's start vertex... you have by then assembled an array of ordered vertices in the loop... if you want to establish if the 'loop' of vertices is cw or ccw you'll need to do some vector magic, assembling the angles between the vectors from a set of three vertices in order and their 'cross', from that you can establish if the loop goes cw or ccw ?

                  TIG

                  1 Reply Last reply Reply Quote 0
                  • thomthomT Offline
                    thomthom
                    last edited by 28 Jan 2013, 10:04

                    @jim said:

                    File has 198 faces, but only 51 surfaces.

                    I think I have the surface loops settled - just need to put the edge loop vertices in "loop" order.

                    Maybe you can grab something from TT_Lib2: https://bitbucket.org/thomthom/tt-library-2/src/7a54ed9e11bf31db6fd326476996fc878003402f/TT_Lib2/edges.rb?at=Version%202.7.0

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

                    1 Reply Last reply Reply Quote 0
                    • J Offline
                      Jim
                      last edited by 30 Jan 2013, 23:51

                      @thomthom said:

                      Maybe you can grab something from TT_Lib2: https://bitbucket.org/thomthom/tt-libra ... on%202.7.0

                      Thanks, Thomthom - those work great.

                      Here's the surface code, for those interested in such things.

                      
                          def self.surface_from_face(face)
                            surface = adjacent_faces(face)
                          end
                      
                          def self.adjacent_faces(face, faces_found = [])
                            faces_found << face if faces_found.empty?
                            edges = face.edges
                            edges.each do |edge|
                              if edge.soft? and edge.smooth?
                                faces_to_add = edge.faces - faces_found
                                faces_found.concat(faces_to_add)
                                faces_to_add.each{|f| adjacent_faces(f, faces_found)}
                              end
                            end
                            faces_found
                          end
                      
                          def self.all_surfaces
                            model = Sketchup.active_model
                            if model.selection.length == 0
                              all_faces = model.entities.grep(Sketchup;;Face)
                            else
                              all_faces = model.selection.grep(Sketchup;;Face)
                            end
                            surfaces = []
                            while(all_faces.size > 0)
                              surface = surface_from_face(all_faces[0])
                              surfaces << surface
                              all_faces = all_faces - surface
                            end
                            surfaces
                          end
                      
                      
                      

                      Hi

                      1 Reply Last reply Reply Quote 0
                      • thomthomT Offline
                        thomthom
                        last edited by 31 Jan 2013, 08:34

                        Here's my variant: http://sketchucation.com/forums/viewtopic.php?f=180&t=41211#p365380
                        Would be interesting to profile them.

                        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
                        1 / 1
                        • First post
                          1/11
                          Last post
                        Buy SketchPlus
                        Buy SUbD
                        Buy WrapR
                        Buy eBook
                        Buy Modelur
                        Buy Vertex Tools
                        Buy SketchCuisine
                        Buy FormFonts

                        Advertisement