Creating edges where faces intersect a plane?
-
I'm trying to write a tool that adds edges wherever a face in a component instance (@ci) intersects a specified X/Z or Y-Z axis "slicing plane".
Anyway, the basic procedure I'm using is:
Traverse a list of slicing planes: [1,0,0,-x1], [0,1,0,-y1], ...
Traverse @ci.definition.entities:
Bail out unless the entity is a face.
Bail out unless plane passes through the face.
Get the plane for the face.
Call Geom.intersect_plane_plane().
Bail out unless it returns a line.
Call add_line().
I'm currently stalled at the point where I call ents.add_line(). I've tried several variations:
# edge = ents.add_line(line) # H0 # edge = ents.add_line(*line) # H1 # edge = ents.add_line(line[0], line[0]) # H2 # edge = ents.add_line(line[0], line[1]) # H3
Versions H0-H2 all give me the following output:
p1 = 1, 0, 0, 2.4880390561432 line = (-2.488039", 8.362949", 0")(0.0, -0.607450107570801, -0.794357832977193) Geom;;Point3d Geom;;Vector3d Error; #<ArgumentError; Cannot convert argument to Sketchup;;Point3d>
I suspect that the error message is faulty and should refer to Geom::Point3d, rather than Sketchup::Point3d. If so, the problem is that SU isn't willing to accept a line in the (Point, Vector) format that Geom.intersect_plane_plane() returns.
This is confirmed by Version H3, which doesn't complain because I'm actually handing in a pair of points (of course, the second point is bogus).
Questions
Is there an easier way to create these edges?
Am I analyzing the nastygram correctly?
How do I convert the line to an acceptable form?
See http://pastie.org/729725 for a larger code snippet...
-
You intersect a face with a plane.
You use
face.plane
to intersect with the slice plane..intersect_plane_plane
returns a line. A line is infinite..add_line
is misleading, it's would be more accurate as ".add_edge
"
As the manual says:@unknownuser said:
The add_line method is used to add an edge to the collection of entities. This is not to be confused with the concept of a "line" from a geometric sense, which is an invisible object represented by an Array of a point and a vector. (See the Array class for more information on geometric lines in SketchUp.)
What you need is to find the finite part of the face that intersect the slice plane. Two Point3Ds.
I think you want to iterate each Edge of the face and find the ones that intersect, use those points to create your intersecting edges. -
Thanks; that was quite helpful!
My only current question is how to handle situations where the plane intersects a vertex (rather than just an edge). This could happen, for example, if a square face had a triangular hole in the center and the plane just touched the top point of the triangle.
-
hmm.. I guess you can test if the intersecting points matches the face's vertices?
The Face class has a nice function
Face.classify_point
http://code.google.com/intl/nb/apis/sketchup/docs/ourdoc/face.html#classify_point
But if you only have a plane - that won't help you much.Another alternative, iterate over the face vertices and check if they lie on the plane:
Point3d.on_plane?
http://code.google.com/intl/nb/apis/sketchup/docs/ourdoc/point3d.html#on_plane? -
This could be interesting:
Entities.intersect_with
http://code.google.com/intl/nb/apis/sketchup/docs/ourdoc/entities.html#intersect_withAlso means you need a real Face to intersect your lines with. But it will correctly intersect faces that has holes in it.
- You'd need to create a temporarily face (inside a group I'd recommend) large enough to cover the entities you want to intersect. You could make it as large as the scene boundary.
- Then iterate over the faces you want to intersect, filter out those edges where the vertices lie on your intersecting face.
- Intersect the faces with your intersect_face.
Advertisement