Knowing that a face contains another face using Ruby API ?
-
Hello everyone i have this 3D model on Sketchup, and i need to get the areas of diffrent faces using Ruby Sketchup API:
For example :@unknownuser said:
-for the first face on the left, i need to say that the face has a total area of 1.55 m² which is the area of the B face + the area of the A face, and say that this face has another face (A) in it and it's area is 0.06 m².
And same for other faces (E and G).How can i find that the face B contains the face A and not C or D ? because all face have the same material and have random x,y,z coordinates.
thank you in advance
-
Let's take face A [ref as 'face'] and see what other faces are in it's plane and share edges etc.
I assume that face A and face B have common edges - all other faces do not.loops = face.loops-[face.outer_loop] ### holes nested_faces=[] loops.each{|loop| nested_faces << loop.face ### filled in hole } nested_faces.flatten! nested_faces.uniq! ### Now check which face[s] are in nested_faces... ### Should be B and no others...
-
thank you so much for your answer i'll try that
-
TIG i tried your method i used this code:
model = Sketchup.active_model ents = model.active_entities ents.each do |f| if f.is_a? Sketchup;;Face loops = f.loops-[f.outer_loop] nested_faces=[] loops.each{|loop| nested_faces << loop.face } nested_faces.flatten! nested_faces.uniq! for i in (0..nested_faces.length) do if nested_faces[i]!=nil UI.messagebox("face #{f.material.name} in face #{nested_faces[i].material.name}") end end end end
but the messagebox shows :
face B_material is in B_material face E_material is in E_material face G_material is in G_material
but i want it to show :
face A_material is in B_material
so as to know both face B and A so that i can calculate the sum of their areas
how can i do that ? -
Try this corrected code:
model = Sketchup.active_model model.active_entities.grep(Sketchup;;Face).each{|f| f.loops next unless f.loops[1] # skip faces without 'holes' inner_loops = (f.loops - [f.outer_loop]) nested_faces = [] inner_loops.each{|loop| loop.edges[0].faces.each{|e| nested_faces << e unless e == f } } nested_faces.each{|ff| UI.messagebox("Face '#{ff.material.display_name}' [area=#{ff.area}]\ninside face '#{f.material.display_name}' [area=#{f.area}]\n[total-area=#{ff.area+f.area}]") } } puts
The issue is with finding the loops correct face - see how I have now done it by getting the loop's first edge, then getting that edge's face[s], but excluding the 'host' face [f]...
I have tested it and it works...
PS:
You might also want to check for the two faces having the same plane, and face.normal etc unless you can be sure that the faces are 2d and coplanar, and every edge has just one or two faces... -
Hello TIG thnx for your answer.
i didn't really understand this part:@unknownuser said:
PS:
You might also want to check for the two faces having the same plane, and face.normal etc unless you can be sure that the faces are 2d and coplanar, and every edge has just one or two faces..did you meant that it will only work if the faces who contain other faces are in the same plane ? and not for faces who are in an other side ? like this image, in case of the blue face (face H) on the right it also has a face in it (face X) so would it create a problem as it's not in the same plane as the other faces ?
-
Like this...
-
Face B will not be found on Face A because it is not defined by a "inner" loop.
-
Correct !
Let me modify the example so it truly fails...
A doughnut face A contains face B but face C is connected to B and A too by the Dual edge !
-
oh oky i understand now, thank you soo much this realy helped (y)
Advertisement