Dear Friends,
I need to find all connected groups to my_group (if any) in ruby sketchup. Can you help me for it?
What does it mean?
There are many topic about itâŚ
âŚand a result is : There is no âsimpleâ method for this.
My goal is make two (or more) connected groups as one group.
There are dozens of possibilities for groups to be connected.
Can you tell us your interpretation of âconnected groupsâ? Please explain in sufficient detail!
I guess there will be no solution for your request as âtwo-lineâ codeâŚ
In picture you can see some connected groups that I wish to find.
. I wish to solve this problem in different steps. In first step I need to know name of other group that is connected to my group.An idea.
You have to get an array of all vertices position of all the faces of âmy groupâ. Transformation of group must be taken into consideration when you retrieving the position. You will get Point3d array. You may need to make it uniq!.
You have to get an array of all group in a model excluding âmy groupâ.
You have to iterate through each of this group entities and check the faces for all above mentioned points with .classify_point method if it is on it or not. (This time you heve to use both PointInside , PointOnEdge, PointOnVertex for.classify_point condition). Transformation of group must be taken into consideration when you make the compassion.
If you get âhitâ you can store the group to an array for later processingâŚcheck the names, etc.
Lets have a simple 2D example. Following we have face1 (one point in common), face2 (One line in common), face3 (an area in common), face4 (Nothing in common) and face_main. If we have only face_main, how can we find face1, face2 and face3?
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
pt1 = [20, 20, 0]
pt2 = [15, 30, 0]
pt3 = [25, 30, 0]
face1 = ent.add_face pt1, pt2, pt3
pt1 = [13, 10, 0]
pt2 = [17, 10, 0]
pt3 = [15, 5, 0]
face2 = ent.add_face pt1, pt2, pt3
pt1 = [15, 15, 0]
pt2 = [30, 10, 0]
pt3 = [30, 20, 0]
face3 = ent.add_face pt1, pt2, pt3
pt1 = [0, 0, 0]
pt2 = [10, 0, 0]
pt3 = [0, 10, 0]
face4 = ent.add_face pt1, pt2, pt3
pt1 = [10, 10, 0]
pt2 = [10, 20, 0]
pt3 = [20, 20, 0]
pt4 = [20, 10, 0]
face_main = ent.add_face pt1, pt2, pt3, pt4
!! dirty & cheap !!
#the snippet of your previous post continued like:
all_faces = ent.grep(Sketchup::Face).to_a
other_faces = all_faces - [face_main]
p_v = Sketchup::Face::PointOnVertex
p_e = Sketchup::Face::PointOnEdge
p_i = Sketchup::Face::PointInside
faces_con = []
all_faces.each{|face_a|
face_a.vertices.each{|vert|
if face_a == face_main
other_faces.each{|face_o|
result = face_o.classify_point(vert.position)
if result == p_v || result == p_e || result == p_i
faces_con<<face_o
end
}
else
result = face_main.classify_point(vert.position)
if result == p_v || result == p_e || result == p_i
faces_con<<face_a
end
end
}
}
puts "------"
puts "found total #{faces_con.size} connected face(s)..."
faces_con.uniq!
puts "...and : #{faces_con.size} of them are unique"
puts "The face(s) connected to face_main (#{face_main}) are:#{faces_con} "
sel.clear
puts "The number of face(s) in selection:"
puts "------"
sel.add(faces_con)
I wish to merge face2 and face3 to face_main if faces are in same height. Can you also help me for it?
There are dozens of possibilities for âmergeâ and âsame heightâ.
Please explain in sufficient detail!
Same as picture
!! MORE dirty & cheap !!
#the snippet of my previous snippet continued like:
faces_con.each{|f|
gr_temp = ent.add_group
gr_temp.entities.add_face f.vertices
gr_temp.explode
}
2.times{
ent.grep(Sketchup::Edge).to_a.each{|e|
next unless e.valid?
if e.start.edges.size == 1 || e.end.edges.size == 1
e.erase!
next
end
next if e.faces.size != 2
e.erase!
}
}
If you take at look at the top right example, youâll see that it has no vertices lying on or in the other group.
Also, none of the bounding box corners would be within the other groupâs bounds.
For this scenario we have suggested in the past that a boolean intersect be done on two copies of the groups. And then the result examined to see if it has an length or volume. (Lastly the temporary result is deleted.)
The drawback to this approach is that it makes modifications to the model, so some have used this approach within an undo operation and then call Sketchup.undo
or abort the operation after doing the determination of intersect.
Thank you so much. I will back to this codes many timesâŚ
Thank you for advice. I will check it carefully.
Dear Dezmo,
Lets make it more interesting⌠In following example we have faces in different groups. Can you help me to solve problem for this scenario?
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
pt1 = [20, 20, 0]
pt2 = [15, 30, 0]
pt3 = [25, 30, 0]
grp1 = Sketchup.active_model.active_entities.add_group
face1 = grp1.entities.add_face pt1, pt2, pt3
pt1 = [13, 10, 0]
pt2 = [17, 10, 0]
pt3 = [15, 5, 0]
grp2 = Sketchup.active_model.active_entities.add_group
face2 = grp2.entities.add_face pt1, pt2, pt3
pt1 = [15, 15, 0]
pt2 = [30, 10, 0]
pt3 = [30, 20, 0]
grp3 = Sketchup.active_model.active_entities.add_group
face3 = grp3.entities.add_face pt1, pt2, pt3
pt1 = [0, 0, 0]
pt2 = [10, 0, 0]
pt3 = [0, 10, 0]
grp4 = Sketchup.active_model.active_entities.add_group
face4 = grp4.entities.add_face pt1, pt2, pt3
pt1 = [0, 0, 0]
pt2 = [0, 10, 0]
pt3 = [10, 10, 0]
pt4 = [10, 0, 0]
grp_main = Sketchup.active_model.active_entities.add_group
face_main = grp_main.entities.add_face pt1, pt2, pt3, pt4
tr = Geom::Transformation.new [10, 10, 0]
grp_main.transform! tr
ents = Sketchup.active_model.active_entities
all_faces = []
ents.each{ |entity|
case entity
when Sketchup::ComponentInstance, Sketchup::Group
entg = entity.definition.entities
entg.each{ |entityg|
case entityg
when Sketchup::Face
if entityg.normal == [0, 0, -1]
all_faces << entityg
end
end
}
end
}
other_faces = all_faces - [face_main]
p_v = Sketchup::Face::PointOnVertex
p_e = Sketchup::Face::PointOnEdge
p_i = Sketchup::Face::PointInside
Thank you in advance.
I asked twice in this topic: âPlease explain in sufficient detail!â
I will not ask a third time.
From the randomly copy-pasted code snippest above, I came to the conclusion that the help so far has had no effect.
Instead of sitting down and looking at the basics, youâre waiting for someone else to write it. It wonât be me.
Sorry.
Apologize my mistake. In fact after I put faces in groups you codes work but I could not see. After I deleted groups I find one merged face.
I added following codes and deleted connected faces and their parent group. My problem solved.
num = faces_con.size.to_i
loop do
face_b = faces_con.pop
grp_f = face_b.parent.instances[0]
grp_f.erase!
num -=1
break if num == 0
end
main_grp.erase!
For friends whom are interest on this topic⌠You need to use following code.
" entities.intersect_with recurse, transformation1, entities1, transformation2, hidden, entities2 ".
It looks confusing but you can find clear explanation and simple example in this link. About 'intersect_with' method ⢠sketchUcation ⢠1. This method will return you an array. If array.size is one means 2 groups has one line in common. if two means one face in common. 3 or more means volume in common.