sketchucation logo sketchucation
    • Login
    🤑 SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

    Faces area in a group ?

    Scheduled Pinned Locked Moved Developers' Forum
    15 Posts 7 Posters 1.8k Views 7 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Didier BurD Offline
      Didier Bur
      last edited by

      Hi,
      Has anyone ever figured out how to calculate the total area of all the faces that are in a group and this group has been scaled/rotated/moved, etc ?

      If you do that:

      def faces_area(faces)
      a = 0.0
      faces.each do |f|
        a+=f.area
      end
      a
      end
      

      You'll get the area of the faces BEFORE the group was scaled.

      So I tried that (assuming that faces is an array of faces of group.entities):

      def faces_area(faces,group_transfo)
      a = 0.0
      faces.each do |f|
        fv=[]
        f.vertices.each do |v|
          fv.push(v.position.transform(group_transfo))
        end
        new_face=Sketchup.active_model.entities.add_face fv
        a+=new_face.area
        new_face.erase!
      end
      a
      end
      

      But I got the "Points are not coplanar syndrom".
      Any hint anyone ?

      DB

      1 Reply Last reply Reply Quote 0
      • M Offline
        Matt666
        last edited by

        Salut Didier !
        Si tu exploses le groupe, calcules l'aire totale, et recompose le group ?
        And if you explode group, calculate total area of the faces, and re-create group ?

        Petit truc pour afficher l'aire totale des face du groupe :
        Smt to show the total area of all the faces in a group :

        
        def face_area
        	model = Sketchup.active_model
        	n = model.active_entities.count
        	cn = 0
        	sel = []
        	
        	group = model.selection[0]
        	group.explode.each do |e|
        		if e.typename == "Face"
        			cn += e.area
        		end
        	end
        	UI.messagebox("\nAire totale des faces du groupe ; " + cn.to_s + "unités")
        	while(n < model.active_entities.count)
        		sel.push(model.active_entities[n])
        		n += 1
        	end
        	model.selection.add(model.active_entities.add_group(sel))
        end
        

        ^^

        Frenglish at its best !
        My scripts

        1 Reply Last reply Reply Quote 0
        • TIGT Offline
          TIG Moderator
          last edited by

          I'd perhaps be best to copy the group inside another group, then explode it and get the areas and then delete the parent group. That way no coincident geometry will be erased and the original is not changed ?

          TIG

          1 Reply Last reply Reply Quote 0
          • M Offline
            Matt666
            last edited by

            Hi TIG!
            This is the second time you corrected me on this error! 😆 🤣

            Frenglish at its best !
            My scripts

            1 Reply Last reply Reply Quote 0
            • Didier BurD Offline
              Didier Bur
              last edited by

              TIG, you are my ☀
              Merci mate/Matt

              DB

              1 Reply Last reply Reply Quote 0
              • M Offline
                Matt666
                last edited by

                De rien mon initiateur de Ruby 😉

                Frenglish at its best !
                My scripts

                1 Reply Last reply Reply Quote 0
                • T Offline
                  todd burch
                  last edited by

                  Personally, I'd call that a bug in the #area method if it is not taking the scaling factor into consideration.

                  1 Reply Last reply Reply Quote 0
                  • Didier BurD Offline
                    Didier Bur
                    last edited by

                    Hi Todd,
                    You know, groups are almost like component instances, they are stored in the model like "internal definitions" and a group is like an unique occurence of its definition, with or without a transformation applied. This is where the 'group' object in SU is wrong defined IMHO.
                    It's a shame we can't apply a transformation to a face, this will solve quickly the problem. I've written Face::transform myself, but for some unknown reason it sometimes raises an error "points are not coplanar" when applying the method to the edges of the face. Go figure...

                    PS: great presentation at 3DBC, but perhaps you need a little bit more training with the compo spray ?

                    DB

                    1 Reply Last reply Reply Quote 0
                    • Didier BurD Offline
                      Didier Bur
                      last edited by

                      @AdamB: just let me call you the ruby wizard Voilà, c'est touT !

                      DB

                      1 Reply Last reply Reply Quote 0
                      • AdamBA Offline
                        AdamB
                        last edited by

                        (FWIW I'd say face.area giving objects space area is the correct behaviour.)

                        But people, this is all the wrong approach. You don't want to be building geometry, you just want to run through each face in the object and scale the area by the transformation. The trick is to project the scaling into the face's basis frame.

                        So the code in my book is:

                        def objectsurfacearea(container, xform)
                        
                        	total = 0
                        	for ent in container.entities
                        		next unless ent.kind_of? Sketchup;;Face	
                        
                        		# get face basis frame	
                        		normal = ent.normal
                        		binormal = Geom;;Vector3d.new(normal.y,normal.z,normal.x)
                        		tangent = (normal * binormal).normalize
                        		
                        		areascale = (xform * binormal).length * (xform * tangent).length
                        
                        		total += ent.area * areascale
                        	end
                        
                        	return total
                        end
                        
                        

                        So you'd do:
                        objectsurfacearea(mygroup, mygroup.transformation)

                        or

                        objectsurfacearea(myinstance.definition, myinstance.transformation)

                        Voila! C'est tous.

                        Adam

                        Developer of LightUp Click for website

                        1 Reply Last reply Reply Quote 0
                        • AdamBA Offline
                          AdamB
                          last edited by

                          @didier bur said:

                          Voilà, c'est touT !

                          Enfin! Apres vingt ans avec une epouse Francais, plus ca change avec mon Franglais..

                          Developer of LightUp Click for website

                          1 Reply Last reply Reply Quote 0
                          • Didier BurD Offline
                            Didier Bur
                            last edited by

                            @unknownuser said:

                            une epouse FrancaisE

                            En effet, en effet... 🤣

                            DB

                            1 Reply Last reply Reply Quote 0
                            • thomthomT Offline
                              thomthom
                              last edited by

                              Sweet! Just what I needed. 😄
                              How does it handle nested scaled groups/components? Do y ou have to add up the total transformation?

                              Thomas Thomassen — SketchUp Monkey & Coding addict
                              List of my plugins and link to the CookieWare fund

                              1 Reply Last reply Reply Quote 0
                              • K Offline
                                kat
                                last edited by

                                Hey thanks a lot AdamB for your super professional approach!
                                Finally found what I was looking for, now my code works fantasticly.

                                I did some additional reading about the Frennet-Serret/TNB frame but I don't really understand everything.
                                If I get it wel, the normal(N) is perpendicular to the face, the tangent(T)'touches' the face and de binormal(B) is perpendicular to both normal and tangent. But then how do you know on which side of the face formed by N and T, is B? I don't get the
                                @unknownuser said:

                                tangent = (normal * binormal)
                                multiplication. Isn't B supposed to be the cross product of N and T?
                                And why is gives
                                @unknownuser said:

                                (xform * binormal).length * (xform * tangent).length
                                

                                you the scale factor?

                                Could you give me some extra matematical information about this?
                                I would like to understand why this code works,

                                thanks, kat

                                1 Reply Last reply Reply Quote 0
                                • AdamBA Offline
                                  AdamB
                                  last edited by

                                  @kat said:

                                  I don't get the
                                  tangent = (normal * binormal)
                                  multiplication. Isn't B supposed to be the cross product of N and T?

                                  Makes no odds. Binormal and tangent both lie in the plane.

                                  @kat said:

                                  And why is gives

                                  @adamb said:

                                  (xform * binormal).length * (xform * tangent).length

                                  you the scale factor?

                                  I'm taking the unit vectors in the plane of the face and transforming them by the Group transform which may scale them. Getting the length in the binormal and tangent direction allows me to figure out how much to scale the area of the face accounting for the transform.

                                  Adam

                                  Developer of LightUp Click for website

                                  1 Reply Last reply Reply Quote 0
                                  • 1 / 1
                                  • First post
                                    Last post
                                  Buy SketchPlus
                                  Buy SUbD
                                  Buy WrapR
                                  Buy eBook
                                  Buy Modelur
                                  Buy Vertex Tools
                                  Buy SketchCuisine
                                  Buy FormFonts

                                  Advertisement