sketchucation logo sketchucation
    • Login
    Oops, your profile's looking a bit empty! To help us tailor your experience, please fill in key details like your SketchUp version, skill level, operating system, and more. Update and save your info on your profile page today!
    πŸ«› Lightbeans Update | Metallic and Roughness auto-applied in SketchUp 2025+ Download

    Loop.convex? question

    Scheduled Pinned Locked Moved Developers' Forum
    5 Posts 3 Posters 358 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.
    • DavidBoulderD Offline
      DavidBoulder
      last edited by

      I was experimenting with loop.convex? and found that extra co-linear points make a surface fail this test. As a result for example if I had a rectangle that I extrude it up, and then draw a rectangle on the bottom edge of one of the side surfaces that represents a door; the floor which would have otherwise passed the convex test, now fails it. I made a variation on the sample code in the API documentation to demonstrate it. Does anyone know an easy way to catch these cases so they don't fail?

       depth = 100
       width = 100
       model = Sketchup.active_model
       entities = model.active_entities
       pts = []
       pts[0] = [0, 0, 0]
       pts[1] = [width, 0, 0]
       pts[2] = [width, depth, 0]
       pts[3] = [0, depth, 0]
      
       # Add the face to the entities in the model
       face = entities.add_face pts
       loop = face.outer_loop
       status = loop.convex?
       if (status)
         UI.messagebox "Loop is Convex"
       else
         UI.messagebox "Loop is not Convex"
       end
      
       ptsB = []
       ptsB[0] = [200+0, 0, 0]
       ptsB[1] = [200+width/2, 0, 0]
       ptsB[2] = [200+width, 0, 0]
       ptsB[3] = [200+width, depth, 0]
       ptsB[4] = [200+0, depth, 0]
      
       # Add the face to the entities in the model
       face = entities.add_face ptsB
       loop = face.outer_loop
       status = loop.convex?
       if (status)
         UI.messagebox "Loop is Convex"
       else
         UI.messagebox "Loop is not Convex"
       end
      

      --

      David Goldwasser
      OpenStudio Developer
      National Renewable Energy Laboratory

      1 Reply Last reply Reply Quote 0
      • DavidBoulderD Offline
        DavidBoulder
        last edited by

        Kind of a related question. I have a source data file that has clean versions of for example the floor that has only 4 verticies vs 6 (2 extra for the door). An alternative approach is to bring in those verticies, and do a loop.convex? test on them. But it appears I have to make a face before I can make a loop? Any way to do that without actually drawing a face. Otherwise, I can draw and erase a face, but seems like it would slow things down.

        --

        David Goldwasser
        OpenStudio Developer
        National Renewable Energy Laboratory

        1 Reply Last reply Reply Quote 0
        • K Offline
          kyyu
          last edited by

          You could get the vertices and get rid of the ones that form coliner edges. Make a new temporary face and go from there. Not pretty, but works. Maybe some has a better idea?

          Oh, anyone got a simple/elequent way of getting the new vertices set, instead of what I did?

          depth = 100
          width = 100
          model = Sketchup.active_model
          entities = model.active_entities
          
          ptsB = []
          ptsB[0] = [200+0, 0, 0]
          ptsB[1] = [200+width/2, 0, 0]
          ptsB[2] = [200+width, 0, 0]
          ptsB[3] = [200+width, depth, 0]
          ptsB[4] = [200+0, depth, 0]
          
          # Add the face to the entities in the model
          face = entities.add_face ptsB
          
          # Only keep non-colinear vertices
          v = []
          ver = face.outer_loop.vertices
          n = (ver.length - 2)
              v1 = ver[0].position    
              v2 = ver[1].position
              u1 = [(v2.x - v1.x), (v2.y - v1.y), (v2.z - v1.z)].normalize!
              u1_saved = u1
          for i in 1..n do
              v1 = ver[i].position    
              v2 = ver[i+1].position       
              u2 = [(v2.x - v1.x), (v2.y - v1.y), (v2.z - v1.z)].normalize!        
              if u1 != u2 then v.push ver[i] end
              u1 = u2      
          end
              v1 = ver[(ver.length - 1)].position    
              v2 = ver[0].position       
              u2 = [(v2.x - v1.x), (v2.y - v1.y), (v2.z - v1.z)].normalize!        
              if u1 != u2 then v.push ver[(ver.length - 1)] end
              u1 = u2 
          if u1 != u1_saved then v.push ver[0] end
          
          # make new face & loop
          group = entities.add_group
          face2 = group.entities.add_face v
          loop = face2.outer_loop
          status = loop.convex?
          if (status)
             UI.messagebox "Loop is Convex"
          else
             UI.messagebox "Loop is not Convex"
          end
          group.erase!
          
          1 Reply Last reply Reply Quote 0
          • thomthomT Offline
            thomthom
            last edited by

            You could do your own convex function.

            I got a method for getting only the corner vertices of a face:
            http://www.thomthom.net/software/sketchup/tt_lib2/doc/TT/Face.html#corners-class_method
            (Click View Source)

            In my old TT_Lib1 library I had a method for getting the convext shape of a set of points in 2d space. http://forums.sketchucation.com/viewtopic.php?f=180&t=34306&start=15#p302805
            Didier made one for 3d I think. (See later that thread)
            Maybe you can cobble together something from this to your own convex? method?

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

            1 Reply Last reply Reply Quote 0
            • DavidBoulderD Offline
              DavidBoulder
              last edited by

              Thanks for the feedback. The data file that is drawing my geometry in the first place already has a smaller list of verticies that is clean. So I guess that is the best option, going back to that, drawing a temporary face to test, and throwing it away. I don't know how much of a performance hit that will be over testing an existing face. But what I can do is pre-test with the existing face, and then only create a temporary face to test on the ones that initially fail.

              David

              Below is the code I ended up with. My SketchUp objects are drawn from data in an external file. I could have drawn temporary faces for convex test for every surface but decided to do the initial test off of the existing SketchUp faces, and then do a second test on faces that fail the convex test to confirm that they really are non-convex. This second test goes back to the data file, draws a temporary surface, tests it, and throws it away. The data file is already fee of un-necessary stray points.

                             if @hash['NON_CONVEX_SURFACES']
                             face = interior_partition_surfaces[index].entity
                             loop = face.outer_loop
                             status = loop.convex?
                               # if face is convex skip over it
                               if status
                                 next
                               else
                                 # failed first convex test, run second one
                                 pointstemp = interior_partition_surfaces[index].model_object_polygon.points
                                 model = Sketchup.active_model
                                 entities = model.active_entities
                                 facetemp = entities.add_face pointstemp
                                 loop2 = facetemp.outer_loop
                                 status2 = loop2.convex?
                                 # erase facetemp
                                 facetempall = facetemp.all_connected
                                 entities.erase_entities facetempall
                                 if status2
                                   # next statement skips the rest of this if face is convex
                                   next
                                 end
                               end
                             end
              
              

              --

              David Goldwasser
              OpenStudio Developer
              National Renewable Energy Laboratory

              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