Ruby - confusing find_faces behaviour
-
Hi All,
Just playing for the first time with creating geometry using Ruby, and I'm a little confused by what seems to be an anomaly in the way that the find_faces method works.First I created some 'test points' to connect with edges and use to make a face...
points = [[-1,-1,0],[1,-1,0],[1,1,0],[-1,1,0]] points << points.first # Close the loop points.map!{|pt| Geom;;Point3d.new(pt)}
(explicit conversion to Point3d doesn't seem necessary most of the time, but I was being strict!)
I can then use these to create all the edges in one hit using...
temp_group.entities.add_edges(points)
Where 'temp_group' is an empty group used to stop the new entities from sticking to other geometry.
When I view the group contents, I can clearly see that the new group now contains my four edges (and nothing else); so I then try to close the face...
temp_group.entities[0].find_faces
But no face will form - even if I iterate over every edge entity. Manually overdrawing any of the four lines creates a face as expected.
However, if I create the edges 'longhand' using a loop to add one edge at a time...
(1...points.size).each do |index| temp_group.entities.add_line(points[index-1],points[index]) end
...find_faces has no trouble making the face, even though the group contents are essentially the same.
I realise that, for this trivial example, I could just use add_face to make the face and lines in one hit - but I am keen to understand what's going on here, as 'add-face' might not be appropriate in every circumstance, and I would imagine 'add_lines' to be more efficient than creating edges with an explicit loop. I get the feeling that maybe I'm missing something to do with group/component editing context - but I can't see how that would affect one method of adding the edges, but not the other.
Thanks in advance for any explanations/tips - this has me thoroughly baffled!
(PS - is there some good reason that the forum search engine removes underscores from search terms (even when "quoted")? - it makes searching for 'underscored' Ruby methods a bit tricky!)
-
I'm in a hurry so I could have missed something. But are you sure you get a hold of the edges like that? temp_group.entities[0].
Maybe try to make sure you get your targeted entity, like if entity.is_a(Sketchup_ whatever type of entity) then do some stuff...NOTE pseudo code!
Maybe..
-
face=temp_group.entities.add_face(points)
does it in one go - if it can... -
TIGs right, if you want a face, just add the face.
But for the sake of working out what makes up the difference:
I had a hunch - and I checked how many vertices there was in the group.
Notice it says five. That's the first and last vertex not begin merged. It appear that
.add_line
will trigger SketchUp's merging, while.add_edges
does not make the edges merge with themselves.Also note that neither
add_line
oradd_edges
intersect the edges they create like the Line tool in SketchUp does - you have to do that yourself. But as we see, merging of vertices can occur. -
Thanks everyone for your replies - and especially to ThomThom for going the extra mile to highlight the different vertex behaviour of the methods.
Having thought a little about your suggestions, things are much clearer - adding a face directly will be more efficient because SU doesn't have to parse through all the edges looking for co-planar ones to make a face. Seems obvious now that I've been pointed in the right direction - I was thinking too much in terms of how I would draw using the mouse. -
@unknownuser said:
adding a face directly will be more efficient because SU doesn't have to parse through all the edges looking for co-planar ones to make a face
Ahh, I thought you where interested in particulary the find_faces method.
Well. TIG's and Thomthoms answers make more sence then, of course.
@unknownuser said:
But as we see, merging of vertices can occur.
Really? There may not be any undocumented methods we can use forcing this behavior?
You'd probably figured them out already by now, I guess... -
@tig said:
face=temp_group.entities.add_face(points)
does it in one go - if it can..... AND you do not need to append the start point to the array, just the 4 corner points when using
add_face()
-
@jolran said:
Really? There may not be any undocumented methods we can use forcing this behavior?
You'd probably figured them out already by now, I guess...No built in method unfortunately, but it would have been nice.
My hack to do so is create a temp group where I add an edge for each vertex, I then transform the edges to become zero length edges and explode the temp group. That's just to trigger vertex healing - it does not intersect crossing edges etc.
-
@unknownuser said:
No built in method unfortunately, but it would have been nice.
I suspected that. And yes, that would have been useful.
Clever hack, anyway. Might come in handy, thanks
Advertisement