sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Surface Outer Loop?

    Scheduled Pinned Locked Moved Developers' Forum
    11 Posts 5 Posters 603 Views 5 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.
    • J Offline
      Jim
      last edited by

      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
      • sdmitchS Offline
        sdmitch
        last edited by

        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
        • Dan RathbunD Offline
          Dan Rathbun
          last edited by

          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
          • Dan RathbunD Offline
            Dan Rathbun
            last edited by

            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

              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
              • Dan RathbunD Offline
                Dan Rathbun
                last edited by

                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
                • sdmitchS Offline
                  sdmitch
                  last edited by

                  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

                    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

                      @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

                        @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

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

                          Advertisement