# Intersect between a plane and a group

Hi,
Any idea how can I find faces that are the result of an intersection between a plane and a group?

The intersect_plane_plane method is used to compute the intersection of two planes.

possible method snippet (did not tested):

``````def find_intersect_faces(faces_in_group, myplane)
intersection = []
faces_in_group.each{|face|
if Geom.intersect_plane_plane(myplane, face.plane)
intersection<<face
end
}
intersection
end
``````

call it with the arguments : faces and plane in question
You may need to take care about some transformation for `face.plane`â€¦ depends how deep the group is nested.

Edit:
Then you need some more comparation if the intersection line is â€śinsideâ€ť a group faceâ€¦

1 Like

Hello Dezmo,
I want to find created faces that are the result of plane and group intersect. I should explain it more clear.

The result of an intersection is a set of edges:

`intersection_edges = entities.intersect_with (...)`

The newly created faces are attached to those edges.

2 Likes

intersect_with will find the intersection between 2 groups or entities but I wish to find the intersection between a plane and a group. The plane is not an entity or group or component. I wish to use edges in drawing so creating a face find intersect and deleting it is not a good way for it.

Thank you Dezmo, in the first step I should find the intersection between all faces in the group and my plane that will be some lines. In the second step, I should find the intersections between these lines that will be some edges. I will try for it.
P.S.
It is not working because the plane of faces that didnâ€™t cut by plane will have interset.

an other :

``````EDIT: removed, my concept was wrong... :-(
``````

In your special case above this face is what you wantâ€¦ I guess

When a plane cuts a group, some edges will intersect. I am looking for those edges.
For example, if the group is a ball, its intersect with a plane will be a circle and I wish to have points of that circle.

Draw a temp grouped face onto the plane, so that its extents are bigger that your main groupâ€™s bounds.
Intersect the faceâ€™s group with your main group and put the results into another new 3rd group.
That 3rd group now contains the resultant edges of any intersectionâ€¦
Erase the temp faceâ€™s group.
Do what you need to do with the intersectionâ€™s edges - e.g. add faces etc.

Tig, in fact, I wish to move the plane by mouse pointer and highlight the intersection between plane and group. I cannot create and delete a group when the mouse moves.

That is totally different than you asked originallyâ€¦

my main problem is finding " Intersect between a plane and a group". am I right?

The main problem is that we could not understand what you really want to achieveâ€¦

Do you really want to do something with the resulted â€śfaceâ€ť or you just to want to show how will it look like the intersection temporally?

Perhaps ???:

``````class Testtool
def initialize
@ip = Sketchup::InputPoint.new
@plane_normal = Geom::Vector3d.new(1,1,1)
end

def onMouseMove(_flags, x, y, view)
@ip.pick(view, x, y)
@pts = poly_points( @ip.position, 100, @plane_normal)
view.invalidate
end

def poly_points( center = ORIGIN, radius = 1, norm = Z_AXIS, xaxis = norm.axes[0], seg = 24 )
ang = 2*Math::PI/seg
tr = Geom::Transformation.rotation( center, norm, ang )
pts = []
pts[0] = center.offset( xaxis, radius )
(1...seg).each{ |i| pts[i] = pts[i-1].transform(tr) }
pts
end

def draw(view)
if @pts
view.drawing_color = [0,128,128, 128]
view.draw( GL_POLYGON, @pts )
end
end

def getExtents
bb = Sketchup.active_model.bounds
return bb unless @pts && @pts.size > 0
end
end
Sketchup.active_model.select_tool(Testtool.new)
``````
2 Likes

I donâ€™t want a face I want something temporary.

In this video yellow square move with the mouse pointer is fixed but I wish always it will be around of group.

Do you mean you wish the yellow plane to be constrained to the groupâ€™s bounds ?

Yes sir, exactly. Any solution for it?

I donâ€™t think so. I guess you want to follow the contour of the group, which is not equal to bounding box (cuboid). You may want same as the section plane do. Donâ€™t you?

If yes (even if not ), here are some â€śfinger exercisesâ€ť, just an idea, not fully engineered :

.
.

Code snippet
``````class TesttoolB

def initialize
@ip = Sketchup::InputPoint.new
@ro_backup = nil
ro_backup_and_set()
reset()
end

def reset(view = Sketchup.active_model.active_view)
@picked = false
@start_pts = nil
@gr_edges = nil
@sp.erase! if @sp && @sp.valid?
# not that elegant, but remove the
# "track" of section plane operations
# from undo stack:
Sketchup.active_model.abort_operation
view.invalidate
end

def onCancel(reason, view)
reset(view)
end

def deactivate(view)
reset(view)
ro_restore() if @ro_backup
end

def get_trans_at(obj, ph)
ph.count.times{|i|
if ph.leaf_at(i) == obj
return ph.transformation_at(i)
end
}
return IDENTITY
end

def get_trans_pts(face)
face.outer_loop.vertices.map{ |v| v.position.transform(@tr) }
end

def onMouseMove(_flags, x, y, view)
@ip.pick(view, x, y)
if @picked
pos = @ip.position.transform(@tr.inverse)
@sp = @sp.set_plane(pos, @normal.reverse)
else
ph = view.pick_helper
ph.do_pick(x, y, 5)
@ph_face = ph.picked_face
if @ph_face
@tr = get_trans_at(@ph_face, ph)
@start_pts = get_trans_pts(@ph_face)
else
@start_pts = nil
end
end
view.invalidate
end

def onLButtonDown(flags, x, y, view)
if !@picked && @ip.face
@normal = @ph_face.normal
gr_ents = @ph_face.parent.entities
@gr_edges = gr_ents.grep(Sketchup::Edge)
Sketchup.active_model.start_operation("Operation will be aborted")
@sp.activate
@picked = true
else
reset(view)
end
end

def draw(view)
@ip.draw(view) if @ip.display?
view.tooltip = @ip.tooltip
# draw the start face contour:
if @start_pts && @start_pts.size > 2
view.drawing_color = "dodgerblue"
view.line_width = 4
view.draw( GL_LINE_LOOP, @start_pts )
end
# highlight all edges in group:
if @gr_edges
view.drawing_color = "peru"
view.line_width = 2
@gr_edges.each{|e|
epts = e.vertices.map{|v| v.position.transform(@tr)}
view.draw( GL_LINES, epts )
}
end
end

def getExtents
bb = Sketchup.active_model.bounds
return bb unless @pts && @pts.size > 0
end

# to display the section "properly"
# set it up as you need, but before that
# make a backup
# you may need to consider more properties to change
# this is just a "most important"
def ro_backup_and_set
rend_ops = Sketchup.active_model.rendering_options
@ro_backup = {
"DisplaySectionPlanes" => rend_ops["DisplaySectionPlanes"],
"DisplaySectionCuts" => rend_ops["DisplaySectionCuts"],
"SectionCutFilled" => rend_ops["SectionCutFilled"]
}
rend_ops["DisplaySectionPlanes"] = false
rend_ops["DisplaySectionCuts"] = true
rend_ops["SectionCutFilled"] = true
end

# restore the above rendering_options
# to state before the tool was started
def ro_restore
@ro_backup.each{|k,v|
Sketchup.active_model.rendering_options[k] = v
}
end

end
Sketchup.active_model.select_tool(TesttoolB.new)

``````

.

1 Like

Now exactly. I wish the yellow plane to be constrained to the group.

You are right. Your code is so strong and I can learn so much from it. Your code shocked me and I am so excited that we can do something so interesting by code. You are great. Thank you so much.
At the end of the day, it seems there is not a simple and direct way to find the intersection between a group and a plane. (we can create a face on a plane and find the intersection between face and group and delete face but not good for the â€śdrawâ€ť method.)

2 Likes

Refutation (kind of)
Motto: Man can do everything, just a matter of time (and or ) .

My third conceptual idea is:

.
.

Code snippet C
``````class TesttoolC

def initialize
@ip = Sketchup::InputPoint.new
reset()
end

def reset(view = Sketchup.active_model.active_view)
@picked = false
@start_pts = nil
@pts_pairs = nil
@gr_edges = nil
view.invalidate
end

def onCancel(reason, view)
reset(view)
end

def deactivate(view)
reset(view)
end

def get_trans_at(obj, ph)
ph.count.times{|i|
if ph.leaf_at(i) == obj
return ph.transformation_at(i)
end
}
return IDENTITY
end

def get_trans_pts(face)
face.outer_loop.vertices.map{ |v| v.position.transform(@tr) }
end

def onMouseMove(_flags, x, y, view)
@ip.pick(view, x, y)
if @picked
pos = @ip.position.transform(@tr.inverse)
@pts_pairs = find_intersect_pts( [pos, @normal] )
else
ph = view.pick_helper
ph.do_pick(x, y, 5)
@ph_face = ph.picked_face
if @ph_face
@tr = get_trans_at(@ph_face, ph)
@start_pts = get_trans_pts(@ph_face)
else
@start_pts = nil
end
end
view.invalidate
end

def onLButtonDown(flags, x, y, view)
if !@picked && @ip.face
@normal = @ph_face.normal
gr_ents = @ph_face.parent.entities
@gr_edges = gr_ents.grep(Sketchup::Edge)
@picked = true
else
reset(view)
end
end

def draw(view)
@ip.draw(view) if @ip.display?
view.tooltip = @ip.tooltip
# draw the start face contour:
if @start_pts && @start_pts.size > 2
view.drawing_color = "dodgerblue"
view.line_width = 4
view.draw( GL_LINE_LOOP, @start_pts )
end
# highlight intersect
if @pts_pairs
view.drawing_color = "peru"
view.line_width = 4
@pts_pairs.each{|pair|
trpts = pair.map{|p| p.transform(@tr)}
view.line_width = 4
view.line_stipple = ""
view.draw( GL_LINE_STRIP, trpts )
view.line_width = 3
view.line_stipple = "-"
view.draw2d( GL_LINE_STRIP, trpts.map{|pt| view.screen_coords(pt)} )
}
end
end

def getExtents
bb = Sketchup.active_model.bounds
end

def point_between?(point, point1, point2)
return true if point == point1 || point == point2
!( point.vector_to(point1).samedirection?( point.vector_to(point2) ) )
end

def dig_pts_faces(plane)
dig_pts = []
faces = []
@gr_edges.each{|edge|
pt = Geom.intersect_line_plane(edge.line, plane)
if pt
pt1,pt2 = edge.vertices.map{|v| v.position}
if point_between?(pt, pt1, pt2)
dig_pts<<pt
faces += edge.faces
end
end
}
[dig_pts, faces]
end

def find_intersect_pts(plane)
dig_pts, faces = dig_pts_faces(plane)
lines = []
faces.each{|face|
line = Geom.intersect_plane_plane(plane, face.plane)
lines<<line if line && !lines.include?(line)
}
pts_pairs = []
lines.each{|line|
pts_pairs<<dig_pts.select{|pt| pt.on_line?(line)}
}
pts_pairs
end

end
Sketchup.active_model.select_tool(TesttoolC.new)

``````
4 Likes

In Sketchup, you can do everything. Your code is so advanced and you find very interesting solutions for the problems. Thanks again.

1 Like