Ruby autosplit edge?
-
Starting scenario:
edge1 = model.entities.add_line [0,-100,0], [100,-100,0]
Edge crossing:
edge2 = model.entities.add_line [50,-100,0], [50,-200,0]
Result:edge2
doesn't splitedge1
Edgepoint meet edge:
edge2 = model.entities.add_line [50,-100,0], [50,-100,0]
Result:edge3
splitsedge1
Why doesn't edge2 split edge1? I thought this was automatic behaviour controlled by:
Sketchup.break_edges=
http://code.google.com/apis/sketchup/docs/ourdoc/sketchup.html#break_edges?But does that property only effect the native tools? Not the API methods?
And how would one simulate the effect whereedge2
splitsedge1
? (wouldn't intersect be very slow if one had large models?)And what if one does not want the break as in
edge3
? -
The auto-splitting is only for built in tools [and that can be toggled on/off too]
if Sketchup.breaks_edges Sketchup.break_edges=false else Sketchup.break_edges=true end#if
For your own tool you can get the intersection of both edges'
line
and from that split each edge at the point - simply work out the % the point is away from each edges'start.position
andsplit
each of the two edges at that point as desired.
For several crossing edges 'intersect' would probably work fastest if you temporarily grouped all of the edges then intersected the groups entities with themselves ? explode the group to return the now 'split' edges back to where you want them ?? -
No need to group to intersect a set of entities - you specify that which entities to intersect with which.
But I wonder if that's what SU do - intersect new edges with the whole lot of existing edges? -
@tig said:
simply work out the % the point is away from each edges' start.position and split each of the two edges at that point as desired.
you don't need the % calculation, you can use the Point3d as well in the .split
-
But all this would just be a re-invent of intersect. One would have to iterate the whole entities collection to check if anything intersected.
-
yeah. I am doing the same thing now - reinventing the wheel of intersect. got some crashes after doing some .intersect_with and also a lot of the frozen UI.
I think I will do an outside process monitor of the SketchUp Ruby system - I hate unresponsive UIs
-
@unknownuser said:
I think I will do an outside process monitor of the SketchUp Ruby system - I hate unresponsive UIs
??? Progressbar??
@unknownuser said:
got some crashes after doing some .intersect_with and also a lot of the frozen UI.
Got a reproducible test case? I'm using it in a plugin where I need to ensure edges crossing each other split. It's already slow, but assumed any attempt to manually intersect would be slower.
-
You would need to iterate active_entities.
If 'intersect' is used then you only test it the edge intersects ?
If 'split' is used you reduce the active_entities to edges only that have a line that intersects with new_edge.line, and then you split new_edge at each point - you need to add the extra_edge made by the split into the mix as that might intersect with an edge later [it will have the same 'line' so no need to retest for that]
Something likedef new_edge_that_splits(p0 ,p1) ### add test for p0/p1 being valid points ### or 3-elem arrays with acceptable values model=Sketchup.active_model ents=model.active_entities edges=[] ents.each{|e|edges << e if e.class==Sketchup;;Edge} edge=ents.add_line(p0, p1) line=edge.line cuts=[] edges.each{|e| pt=Geom.intersect_line_line(line, e.line) cuts << pt if pt } cuts.each{|p| ed=edge.split(p) edge=ed if ed } return end
???
-
The boolean intersection operation as I'm sure you've already discovered can be really flaky when working with complex geometry, and that's more or less been the case in every CAD package I've worked with. It's a tough algorithm to implement and for anything non-linear it will be imperfect.
Also, when you add an edge to the entities collection a lot is going on behind the scenes. Information about which face the edge belongs to, what the adjacent edges are, and their vertices all has to be stored in a table and updated on each operation. That overhead should be avoided when possible, and it can be here.
Calculating the intersection of two lines is however, really fast computationally, and it's also fast to check if it's in the segment defined by your two points as well. Thankfully you can avoid comparing each edge by using the Bentley-Ottmann Algorithm or one of it's variants if the segments are coplanar. It runs in about n log n time which sure beats the n^2 time of the naive approach. If your edges are not coplanar than you will have to test for that as well, however that's not to bad either since if your segments are skew then the four points form a tetrahedron with non-zero volume, so you simply calculate the volume and if it's 0, they're coplanar so you can sort them out and calculate the intersections from there. I would expect this to be orders of magnitude faster than using the intersect_with method.
-
I found a very easy way to auto split crossing edges. Create all edges inside a group when all edges are added to the group, explode the group. Sketchup will automatic split all crossing edges.
Advertisement