• Login
sketchucation logo sketchucation
  • Login
πŸ€‘ 30% Off | Artisan 2 on sale until April 30th Buy Now

[Plugin] 2dBoolean ver1.3.1 beta UPDATE 20 dec 2013

Scheduled Pinned Locked Moved Plugins
88 Posts 8 Posters 48.8k 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.
  • T Offline
    TIG Moderator
    last edited by 29 Aug 2011, 19:19

    NO !
    Each tested pair of points for an edge just tells us that the related edge must go if they fail on some grounds, or if it the result is just 'iffy' then re-test for the midpoint and if that fails then off the edge goes into the edges2go array; and when all edges are examined fully you do edges2go.flatten! to remove duplicates [just in case there are any! there shouldn't be] and then use edges2go[0].parent.entities.erase_entities(edges2go)... πŸ˜•

    TIG

    1 Reply Last reply Reply Quote 0
    • J Offline
      jolran
      last edited by 29 Aug 2011, 19:30

      @unknownuser said:

      NO !

      Clear enough πŸ˜„

      Ok, I will continue with this method. You showed me some new moves there I haven't tried.

      1 Reply Last reply Reply Quote 0
      • T Offline
        TIG Moderator
        last edited by 29 Aug 2011, 19:36

        Also why not look at it this alternative way?
        You use the original selected group; or if it's an instance then add that to a new group and immediately explode the instance. Now either way you now have a group to use.
        Use group.entities.intersect_with() using the the group.entities for the results, with a new transformations [0,0,0], and the object to intersect being ((face.edges)+face).
        Now test all of the group.entities edges for being on the originally selected 'face' as already outlined...
        Any lines not on the face get erased.
        Now it's possible that some faces in the group might still remain over holes in the face...
        To find and remove those examine each face within group.entities [let's called each 'tface'].
        Test the following point pt=tface.bounds.center.project_to_plane(face.plane)
        for being on the 'face' [but not in a hole!]... It will fail if it's one of the faces over a 'hole' in 'face' - if so add the tface to a 'faces2go' array.
        When all faces are tested use faces2go[0].parent.entities.erase_entities(faces2go).
        Now the last step is to check for any un-faced edges left after these unwanted faces were removed... group.entities.to_a.each{|e|e.erase! if e.class==Sketchup::Edge and not e.faces[1]}...
        NOW we should have things sorted ???

        TIG

        1 Reply Last reply Reply Quote 0
        • J Offline
          jolran
          last edited by 29 Aug 2011, 20:04

          I have to call it a day. Been at it since morning without any results. Your new approach here give me hope. πŸ‘

          I will sleep on it and try this tomorrow.

          Thanks for helping me out TIG. πŸ˜„

          1 Reply Last reply Reply Quote 0
          • T Offline
            TIG Moderator
            last edited by 30 Aug 2011, 13:17

            My alternative way is a bit simpler.
            Here it is reiterated.
            Select face and group or instance.
            Run tool.
            Tool sorts out the parts: one face and one group/instance.
            If it's an instance it's grouped and exploded and that group is used.
            Now you
            tr=Geom::Transformation.new() group.entities.intersect_with(true,tr,group.entities,tr,true,(face.edges+[face]))
            You then then collect all of the edges in the group.
            Make an array - edges2go=[]
            Test each edge in turn.
            pts=edge.start.position
            then
            pte=edge.end.position
            against face.classify_point(pts) etc
            If one point is 'on the face' [and not in a hole] AND the other point is 'on the face' [and not in a hole] OR it's on a face's edge OR on a vertex then that edge is OK.
            If both of these points are NOT 'on the face' [and not in a hole] AND NOT on a face's edge AND NOT on a face's vertex, then it's
            edges2go << edge.
            If both points are on one of the face's edges or vertices then it could be either 'on' or 'off' face; so we must test the edge's midpoint ( mid=pts.offset(edge.line[1], edge.length/2)) to see if that's 'on the face' [not in a hole] OR on a face's edge OR on a vertex - IF it is any of these then it's OK as it's spanning a convex corner and is all 'on face', otherwise it's off to edges2go << edge again, as it's spanning a concave corner - either within a 'hole' or an internal L-shape and falls outside of the face !
            You then erase all of these unwanted edges [any connected faces go with them] with
            group.entities.erase_entities(ents2go)
            There should be no 'stray lines' left by this method and this allows loose unfaced edges to be in the group and remain [trimmed to the face edges if needed]...

            This simpler idea can then be applied to the main hatching tool tool.
            We get the hatch/crosshatch parameters.
            We iterate through selected faces in turn.
            A new 'hatch' group is made that will become bigger than each face bounds... lines are added to form the hatch/crosshatch [in the plane of the face], all of these lines are then intersected_with the 'face'. Each of the edge's two points are again tested with face.classify_point() [and midpoint if questionable] to make an array of unwanted ones to remove.

            πŸ€“

            TIG

            1 Reply Last reply Reply Quote 0
            • J Offline
              jolran
              last edited by 30 Aug 2011, 14:06

              Wow, TIG! Will be interesting to test your new approach.

              BTW:

              @unknownuser said:

              tr=Geom::Transformation.new()
              group.entities.intersect_with(true,tr,group.entities,tr,true,(face.edges+[face]))
              You then then collect all of the edges in the group.
              Make an array - edges2go=[]
              Test each edge in turn.
              pts=edge.start.position
              then
              pte=edge.end.position
              against face.classify_point(pts) etc

              Isent this what I'm doing already? Except (face.edges+[face)] is a group(gp3) for me?
              Or did I misunderstand you? Anyway, that may not be of relevance for fixing the problem.

              I think the main problem is that, after the collection of points "outside" face I have been using if edge.used_by? point to select and erase the edges. Passing on the point as argument. (In reality point gets converted to vertices). That way I can never erase an edge if it's not used by "something".

              I guess your way is to tell Sketchup. If point is on edge? Put that edge in the "erase" array. Is that correct?

              This all have to be done in an iterator, right? With some conditionals inside the iterator. I spent all day yesterday to find suitable API methods to fit the need, but really need some IF, NOT and OR statements? Or am I wrong here in my assumption?
              I guess the iterator will be faster if the statements are made outside..

              I will try those things and pt=tface.bounds.center.project_to_plane(face.plane) and the edge.midpoint test as well.

              Again, thanks a lot!

              1 Reply Last reply Reply Quote 0
              • J Offline
                jolran
                last edited by 30 Aug 2011, 16:49

                Wait. I think I got it backwards, TIG..

                I was looking in the API, and the closest thing to compare an point on edge was, point3d on_line.
                What I could see.

                Then realized, maybe you meant that there should be only 1 iteration, in edge.array?

                Iterate through edge.array, do the tests. If true or false(depending on the test) then edges2go << edge ?

                After that, erase arrays entitiesedges2go?

                Is it something like that what you had in mind, TIG?

                1 Reply Last reply Reply Quote 0
                • T Offline
                  TIG Moderator
                  last edited by 30 Aug 2011, 16:57

                  NO, NO, NO! πŸ˜’
                  When you do face.classify_point(pt) you get ONE of a list of possible results:
                  http://code.google.com/apis/sketchup/docs/ourdoc/face.html#classify_point
                  The list is

                  0: Sketchup::Face::PointUnknown (indicates an error),
                  1: Sketchup::Face::PointInside (point is on the face, not in a hole),
                  2: Sketchup::Face::PointOnVertex (point touches a vertex),
                  4: Sketchup::Face::PointOnEdge (point is on an edge),
                  16: Sketchup::Face::PointOutside (point outside the face or in a hole),
                  32: Sketchup::Face::PointNotOnPlane (point off the face's plane). So if the result of either of the vertex.position points is Sketchup::Face::PointInside then it's OK.
                  If either are Sketchup::Face::PointOutside it has to GO!
                  If both are Sketchup::Face::PointOnVertex OR Sketchup::Face::PointOnEdge then it might be OK - you test for the midpoint etc and if it's Sketchup::Face::PointOutside it has to GO!...
                  πŸ˜•
                  Iterate the edges just once and collect all that fail; then erase them en mass...

                  TIG

                  1 Reply Last reply Reply Quote 0
                  • E Offline
                    EarthMover
                    last edited by 30 Aug 2011, 17:06

                    @tig said:

                    NO, NO, NO! πŸ˜’
                    🀣

                    Tough on your students as all great masters are! I'm just picturing the huge face palm from a steamed but brilliant TIG as he has to constantly communicate with us "less brained" folk. πŸ˜„ Seriously, though your patience and constant help is much appreciated. I've been trying to follow both threads with you and Joel going back and forth and I'm starting to pick up a little of what is going on, although it's still all over my head.

                    3D Artist at Clearstory 3D Imaging
                    Guide Tool at Winning With Sketchup
                    Content Creator at Skapeup

                    1 Reply Last reply Reply Quote 0
                    • T Offline
                      TIG Moderator
                      last edited by 30 Aug 2011, 17:14

                      I need my dinner and a drink! πŸ˜„

                      TIG

                      1 Reply Last reply Reply Quote 0
                      • J Offline
                        jolran
                        last edited by 30 Aug 2011, 17:44

                        @unknownuser said:

                        NO, NO, NO!

                        πŸ˜„ I think I explained the question poorly. SWEnglish at it's worst. Haven't you seen the Swedish chef in the Muppet show?

                        I know about http://code.google.com/apis/sketchup/do%20...%20sify_point Im already using it in the code πŸ˜‰

                        The question was. Only 1 iteration?

                        If you have looked at my code you see that I first collect edge.start, edge.end and edges. THEN I collect the points outside the face. After that I collect edges that are connected to those vertices. So all in all 3 iterators for just 1 purpose.

                        What I meant about point3d on_line, was that WHEN I was looking at that method in the API I realized I should use 1 iterator, NOT that I should use point 3d on_line. That's a whole different matter πŸ˜„

                        Earthmover wrote:

                        @unknownuser said:

                        Seriously, though your patience and constant help is much appreciated.

                        You bet! I'm deeply greatful.

                        Therefore Here Ya go!


                        dry-martini2.jpg

                        1 Reply Last reply Reply Quote 0
                        • T Offline
                          TIG Moderator
                          last edited by 30 Aug 2011, 18:17

                          No... try to simplify your code. πŸ˜„
                          I'm trying to suggest a streamlined approach, that both faster and 'easier to get your head around'.
                          After the intersecting etc... edges will be split by every edge of the face and then these possibly split edges will either fall 'on' the face, 'off' the face, OR with both vertices on the face's perimeters...
                          Collect all of the edges inside the group.
                          Check each edge in turn, looking at its two vertices' positions and seeing where they are 'on' the face.
                          Some edges are clearly 'on' - some are clearly 'off'... from testing a vertex.position in the face.classy_point() method... There are several possible results but careful interpretation will prove VERY useful...
                          If there are questionable edges [with both vertices on the face's edges or face's vertices] you can check if that edge is 'spanning' a convex or concave corner. If it's 'concave' the midpoint of the edge is not on the face so it has to be erased later on...
                          So just do the tests as I described... and make an array of 'edge-failures'.
                          Once you've been through all of the edges in the group you can then erase the array of edge-failures 'en mass'.
                          Done - the group is trimmed to every perimeter of the face - including its 'holes'.
                          Because faces need edges they'll also go with the 'removed edges'.
                          this is much simpler... πŸ˜„

                          TIG

                          1 Reply Last reply Reply Quote 0
                          • J Offline
                            jolran
                            last edited by 30 Aug 2011, 18:41

                            @unknownuser said:

                            I'm trying to suggest a streamlined approach

                            I will try to do my best. I think I know now what you mean. If I do it right, I think we will see some speed improvements as well.

                            Finally time to do some coding, been preoccupied with bunch of boring things today.

                            Off to work πŸ˜„

                            1 Reply Last reply Reply Quote 0
                            • J Offline
                              jolran
                              last edited by 30 Aug 2011, 20:02

                              Well I think we are back to par with this method!

                              And it seams a whole lot faster. Haven't tried on heavy geometry. But It really feels faster.

                              It seams to erase edges as it should be. And on the + side edges inside holes get's erased, which is really good.

                              Actually point outside is all you need. I don't think there is any need to test on every scenario?

                              I've set up the iterator like this. Where gp2edge is edge.array and comparefaces are the face to be used in classify point.
                              Names will get shorter later on. I think it's good when workin on the code to have explaining names..

                               gp2edge.to_a.each{|edge| 
                                            comparefaces.to_a.each{|face| 
                              	   
                              	                    if face.classify_point(edge.start)==Sketchup;;Face;;PointOutside and              
                                                         face.classify_point(edge.end)==Sketchup;;Face;;PointOutside
                              					       
                              						   gp2ptogo << edge
                              				       
                              					   end
                              	                    
                              						if face.classify_point(edge.start.position.offset(edge.line[1], edge.length/2))==Sketchup;;Face;;PointOutside
                              				           
                              						   gp2ptogo << edge
                              				      
                              					  end
                              				
                              				} 
                                          }
                              

                              Now if we could just get rid of the faces in the holes. I'm gonna try pt=tface.bounds.center.project_to_plane(face.plane) and see what happends....

                              1 Reply Last reply Reply Quote 0
                              • T Offline
                                TIG Moderator
                                last edited by 30 Aug 2011, 21:31

                                Testing for one of the vertex 'points outside' the face will remove most unwanted edges... BUT imagine this... in a face's hole you have an intersected line drawn across if from one edge to the other, you don't want that line BUT neither of the vertices test 'outside' because they are both on the face's edges or vertices... so they pass... just as if they were the perimeter to the form... BUT my suggestion will find these - test the edge's midpoint for being 'on the face' or on a face's edge if it is then it's NOT in a hole so we keep it [i.e. it's a perimeter edge or a line spanning from one edge to another across the face itself rather than across a hole], but if NOT then it's to be erased as it is spanning over a hole...
                                You must test for this scenario.
                                Make a large linear group that will span over a whole face with single lines - without that test they'll all get erased as none of them will have vertices on a face?
                                β˜€
                                πŸ’­ Instead of testing both vertices for every edge test every edge's midpoint [which is easy enough to find!], for being 'on face' [not in a hole] OR 'on edge' OR 'on vertex' - if it passes ANY one of these it's kept, BUT if it passes NONE of these then it goes on the list for erasing at the end - this reduces the number of tests by over a half! It will have noticeable speed improvements and less convoluted checking... πŸ˜•

                                TIG

                                1 Reply Last reply Reply Quote 0
                                • J Offline
                                  jolran
                                  last edited by 30 Aug 2011, 21:49

                                  @unknownuser said:

                                  test the edge's midpoint for being 'on the face' or on a face's edge if it is then it's NOT in a hole so we keep it [i.e. it's a perimeter edge or a line spanning from one edge to another across the face itself rather than across a hole], but if NOT then it's to be erased as it is spanning over a hole...

                                  Yes, this code, no? if face.classify_point(edge.start.position.offset(edge.line[1, edge.length/2))==Sketchup::Face::PointOutside]

                                  I'm working on the face thing now.. If I get that working there should be some serious testing, and then come back and fix things if needed.

                                  And yeah! There are speed increases. I will time it later when doing som more complex geometry.

                                  Thanks for this TIG.

                                  If this will get OK, Hatchfaces would use this intersection as well. Am doing some JS, html tutorials at the same time as coding πŸ˜‰

                                  1 Reply Last reply Reply Quote 0
                                  • J Offline
                                    jolran
                                    last edited by 30 Aug 2011, 23:04

                                    I don't think we can use face.bounds.center as a point in face.classify method. Eg (face.bounds.center.project_to_plane(face.plane))

                                    The center point of a face can be in a hole if the face is surrounding the hole. Hope the pic explains..
                                    (the big face gets erased!)

                                    The BIG problem was to erase edges inside holes. Wich you fixed πŸ˜„ !!

                                    So now when that seams to be working. I'm thinking, recreating the holes a' la face.clone. Then erasing the faces. This would not have been possible before if there where edges inside the hole.

                                    Edited: Hm, since there already are faces in the holes, the new one ends up on top and intersection is needed. Could be difficult to retrieve them for erasing after that.. OR rather, it might be excessive to create the faces just the get hold of them..


                                    faces-1.jpg

                                    1 Reply Last reply Reply Quote 0
                                    • T Offline
                                      TIG Moderator
                                      last edited by 31 Aug 2011, 08:36

                                      Please reread my posts, we are not talking about finding the center of any faces OR making any 'face clones'... πŸ˜•
                                      Just intersect the group's entities with the face.edges+[face] etc.
                                      Find all of the edges in the intersected group.
                                      Look at each edge...
                                      mid=edge.start.position.offset(edge.line[1],edge.length/2)
                                      Then use
                                      result=face.classify_point(mid)
                                      To see if it's on the face or an edge/vertex - if it's not it's earmarked to go!
                                      Done.

                                      TIG

                                      1 Reply Last reply Reply Quote 0
                                      • J Offline
                                        jolran
                                        last edited by 31 Aug 2011, 09:22

                                        I have reread your posts, over and over πŸ˜„

                                        @unknownuser said:

                                        Just intersect the group's entities with the face.edges+[face] etc.
                                        Find all of the edges in the intersected group.
                                        Look at each edge...
                                        mid=edge.start.position.offset(edge.line[1],edge.length/2)
                                        Then use
                                        result=face.classify_point(mid)
                                        To see if it's on the face or an edge/vertex - if it's not it's earmarked to go!

                                        This IS what I'm doing already. Edges are being erased as they should be.

                                        gp2edge.to_a.each{|edge| 
                                                      comparefaces.to_a.each{|face| 
                                        	   
                                        	                    if face.classify_point(edge.start)==Sketchup;;Face;;PointOutside and              
                                                                   face.classify_point(edge.end)==Sketchup;;Face;;PointOutside
                                        					       
                                        						   gp2ptogo << edge
                                        				       
                                        					   end
                                        	                    
                                        						if face.classify_point(edge.start.position.offset(edge.line[1], edge.length/2))==Sketchup;;Face;;PointOutside
                                        				           
                                        						   gp2ptogo << edge
                                        				      
                                        					   end
                                                               
                                        					   
                                        				} 
                                                    }
                                        

                                        The problem is that faces inside holes wont get erased unless we tell'em to. πŸ˜„

                                        If you mean to reread your posts to take care of THIS particular problem, I'm sorry did not understand how, by information provided. I'm working at the problem right now, and it should not be as difficult as erasing the edges inside holes.


                                        faces2-1.jpg

                                        1 Reply Last reply Reply Quote 0
                                        • J Offline
                                          jolran
                                          last edited by 31 Aug 2011, 15:05

                                          Hmm. This problem I havent got a clue about..

                                          The calculation is irregular. Sometimes it fails to erase the required faces..

                                          I don't know If it's worth killing thyself for.. Most of the times there will be plenty of geometry so this calculation isent needed anyway... But I would like to know why comparison fails and if there are any resque methods for these kinds of failures.


                                          hole tests.jpg

                                          1 Reply Last reply Reply Quote 0
                                          • 1
                                          • 2
                                          • 3
                                          • 4
                                          • 5
                                          • 3 / 5
                                          3 / 5
                                          • First post
                                            52/88
                                            Last post
                                          Buy SketchPlus
                                          Buy SUbD
                                          Buy WrapR
                                          Buy eBook
                                          Buy Modelur
                                          Buy Vertex Tools
                                          Buy SketchCuisine
                                          Buy FormFonts

                                          Advertisement