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

    Determine if edge would split face

    Scheduled Pinned Locked Moved Developers' Forum
    6 Posts 4 Posters 1.0k Views 4 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.
    • G Offline
      Garry K
      last edited by

      I start with hundreds of faces and hundreds of edges. The faces are in one group and the edges are in another group.

      The first image shows 1 face and 1 edge where the edge is coplanar with face.
      I want to end up with 2 faces just like the second image.

      I could get make a copy of the array of vertices that make up the face and then add the 2 points that make up the edge and then run fit_plane_to_points and check to see if the resultant plane is equal to the plane of the face.

      If it passes then I would need to figure out how to calculate the 2 new vertices that are on the second image.

      Any shortcuts or ideas on a better method? Is there a way to quickly throw out edges that aren't close?


      edge and face.png


      2 faces.png

      1 Reply Last reply Reply Quote 0
      • jolranJ Offline
        jolran
        last edited by

        If 2D, sweepline-sort, perhaps with binary search Array and sort by X or Y.
        Boundingbox from faces could be used as bounds..
        I suppose the faces bounds coordinates would have to be sorted as well, not making it optimal..

        If 3D I don't know. Faces could be standing straight up and sweepline would miss it..

        Even if you sort roughly, you are gonna cut down the calculations a lot.
        n faces * n edges is a bad algorithm. But for 100 edges and faces you shouldent get such a hit anyhow ?

        1 Reply Last reply Reply Quote 0
        • fredo6F Offline
          fredo6
          last edited by

          Possibly, you create a copy of the Group of Edges into the Group of faces, and then explode it. Sketchup would normally divide the faces for the edges which are coplanar to them. Then you erase the lonely edges (i.e. not attached to a face).

          If you need to do that algorithmically, then, you can divide the global bounding box containing the group of edges and the group of faces into a 3D grid (for instance 20 x 20 x 20), as a set of BoundingBox objects. Then you can once mark each BB-cube with the faces and edges with respect to the conditions:

          • a face has one vertice in the BB-cube or an edge intersecting the BB-cube
          • an edge has one vertex in the BB-cube or intersects the BB-cube
            These tests are normally fast, since based on built-in methods of BoundingBox.

          Then you process each cube with its attached edges and faces. In principle, this should help to reduce the total number of tests.

          By the way, you must keep track of all edges coplanar with a face, even those not splitting faces, because they can subsequently create sub-faces when associated with other coplanar edges.

          Edges and Faces intersections.png

          Fredo

          1 Reply Last reply Reply Quote 0
          • jolranJ Offline
            jolran
            last edited by

            @unknownuser said:

            If you need to do that algorithmically, then, you can divide the global bounding box containing the group of edges and the group of faces into a 3D grid (for instance 20 x 20 x 20), as a set of BoundingBox objects. Then you can once mark each BB-cube with the faces and edges with respect to the conditions:

            • a face has one vertice in the BB-cube or an edge intersecting the BB-cube
            • an edge has one vertex in the BB-cube or intersects the BB-cube
              These tests are normally fast, since based on built-in methods of BoundingBox.

            I really like this idea.

            Edit: removed nonsence I previously posted, missread the algorithm. Looping egdes and faces is only needed once to mark BB. Although one would have to loop each boundingbox per entity (worst case) to find the correct BB to attach to ? So to many bounding box divisions arent to ones advantage ?
            20 X 20 X 20 = 8000 boundingboxes.
            Edgeintersect boundingbox is presumably a Point in volume calculation ?
            Meaning for each vertice first test if in rectangle X/Y(4 tests) then if inside Z (2 tests).
            6 tests X 2 vertices (worst case) leads to a worst case of 96 000 tests per edge..

            Solution might be to add double sweepline approach in boundingbox ranges. Per each BB column first test if egde fall within X and Y, and then proceed. If so then proceed in columns ( each BB in z-axis ). But maybe this is what you had in mind already but forgot to mention. I might be stating the obvious..

            1 Reply Last reply Reply Quote 0
            • sdmitchS Offline
              sdmitch
              last edited by

              @garry k said:

              I start with hundreds of faces and hundreds of edges. The faces are in one group and the edges are in another group.

              The first image shows 1 face and 1 edge where the edge is coplanar with face.
              I want to end up with 2 faces just like the second image.

              Any shortcuts or ideas on a better method? Is there a way to quickly throw out edges that aren't close?

              Name the edge group "edges" and the face group "faces". Select both then execute this code. Of course this a simplistic example but I have no idea how complex the edges and faces maybe. If you would care to post a model, version<=2014 for me,

              mod = Sketchup.active_model
              ent = mod.active_entities
              sel = mod.selection
              egrp = sel.grep(Sketchup;;Group).select{|g|g.name=='edges'}[0]
              edges = egrp.entities.grep(Sketchup;;Edge)
              fgrp = sel.grep(Sketchup;;Group).select{|g|g.name=='faces'}[0]
              faces = fgrp.entities.grep(Sketchup;;Face)
              et = egrp.transformation; ft = fgrp.transformation; new_pts = []
              for f in faces
               ctr = f.bounds.center.transform(ft)
               vec = f.normal.transform(ft); f_plane = f_line =[ctr,vec]
               for e in edges
                next unless e.start.position.transform(et).on_plane? f_plane
                next unless e.end.position.transform(et).on_plane? f_plane
                spt,vec=e.line; spt.transform!(et); vec.transform!(et); e_line=[spt,vec]
                pts = Geom.closest_points e_line,f_line
                next unless e.bounds.contains?(pts[0].transform(et.inverse))
                if f.classify_point(pts[0].transform(ft.inverse))==1
                 new_pts << mod.raytest([pts[0],vec.reverse])[0].transform(ft.inverse)
                 new_pts << mod.raytest([pts[0],vec])[0].transform(ft.inverse)
                end
               end
              end
              1.step(new_pts.length-1,2) {|i| fgrp.entities.add_line(new_pts[i-1],new_pts[i])}
              
              

              Split face.gif

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

              http://sdmitch.blogspot.com/

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

                Thanks guys - this gives me some good direction. I like Sam's strategy where he makes use of the raytest.

                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