sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Question about Normal vector

    Scheduled Pinned Locked Moved Developers' Forum
    9 Posts 6 Posters 818 Views 6 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.
    • G Offline
      gerard.degreve
      last edited by

      Hi everybody,

      I'm a beginner in the study sketchup API's.

      I don't understand the following behavior: If I test the normal vector of a face before and after a rotation, it does not seem to change.

      Here is my code:

      ent = Sketchup.active_model.entities
      face = ent.add_face [0,0,0], [1,0,0], [1,1,0], [0,1,0]
      face.reverse!
      face.pushpull 1
      
      group1 = ent.add_group face.all_connected
      
      puts face.normal
      
      rot=Geom;;Transformation.rotation(Geom;;Point3d.new(0, 0, 0), Geom;;Vector3d.new(0, 1, 0), 30.degrees)
      ent.transform_entities rot, group1
      
      puts face.normal,"_______________________"
      
      group1.entities.each{|e| 
      	if e.typename =="Face"
      		puts e.normal
      	end
      }
      

      and here is the ruby console return:

      load "Tests/testnormalvector.rb"
      (0.0, 0.0, -1.0)
      (0.0, 0.0, -1.0)
      _______________________
      (0.0, 0.0, -1.0)
      (0.0, 0.0, 1.0)
      (0.0, -1.0, 0.0)
      (1.0, 0.0, 0.0)
      (0.0, 1.0, 0.0)
      (-1.0, -0.0, -0.0)
      true
      

      The normal vector still point to the same direction. If I loop on each faces.normal of my object, the results are the same as if there was no rotation.

      Have I missed something?

      My goal is to rotate gradually an entity and stop the rotation when the normal vector of a reference face reaches a certain direction.

      I'm using Sketchup 7 pro.

      Thank you in advance

      Gerard

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

        First of all - when making groups using the Ruby API you change the order of who you make things.

        You make the group first, then add the content:

        <span class="syntaxdefault"><br />ent&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities<br />group1&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">ent</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_group<br /><br />face&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">group1</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">add_face</span><span class="syntaxkeyword">(&nbsp;[</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">],&nbsp;[</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">],&nbsp;[</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">],&nbsp;[</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">1</span><span class="syntaxkeyword">,</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">]&nbsp;)<br /></span><span class="syntaxdefault">face</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">reverse</span><span class="syntaxkeyword">!<br /></span><span class="syntaxdefault">face</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">pushpull&nbsp;1<br /></span>
        

        Grouping existing geometry can lead to problems very easily.

        Also, #typename is tertrible slow. Read this for more info: http://www.thomthom.net/thoughts/2011/12/never-ever-use-typename/

        If you're new to SketchUp plugin development I also recommend you read this:
        http://www.thomthom.net/thoughts/2012/01/golden-rules-of-sketchup-plugin-development/

        (Still looking at the code and question you asked.)

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

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

          Ah! You're rotating the group itself. The vector you're reading from the face remains contant because within the group itself the face hasn't moved. You get the local coordinate of the face.

          If you want the global you need to transform the face normal with the group's transformation as well as the current edit context. http://www.sketchup.com/intl/en/developer/docs/ourdoc/model#edit_transform

          More info on instances and definitions in SketchUp:
          http://www.thomthom.net/thoughts/2012/02/definitions-and-instances-in-sketchup/

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

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

            You put a face in a group.
            It has a face.normal.
            You then rotate the group:
            ent.transform_entities(rot, group1)
            the group rotates but its contents stay in the same relationship to the group's axes.
            The face is still inside the group's context and it's unchanged, so the face.normal is unchanged, since it's reported relative to the group's axes.
            If you rotate the group's contents:
            group1.entities.transform_entities(rot, group1.entities.to_a)
            Then the face.normal will change.
            You can also get the group.transformation and apply that to the face.normal, as face.normal.transform!(group.transformation) etc... You need to decide if you want to transform the group or the face inside it...

            TIG

            1 Reply Last reply Reply Quote 0
            • G Offline
              gerard.degreve
              last edited by

              Got it!

              I suspected that the problem was that the normal vector's coordinates  are expressed relative to the axes of the object.

              Thank you for your explanations and your valuable advice.

              Gerard

              1 Reply Last reply Reply Quote 0
              • jolranJ Offline
                jolran
                last edited by

                if e.is_a?(entity) should work better. Can't put space between certain arguments.

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

                  if e is_a? Sketchup::Face ==NO ==missing '.'
                  if e.is_a? Sketchup::Face ==YES
                  or better
                  if e.is_a?(Sketchup::Face)

                  TIG

                  1 Reply Last reply Reply Quote 0
                  • J Offline
                    jshaz
                    last edited by

                    Hi guys, I'm trying to find the normal of a face that i have selected in my model I thought something similar to this script shown below might do the trick but alas it hasn't. The ruby console says I have an undefined method e. With my limited ruby brain I though this might be helped by making e = [] or e = 0 which of course it did not. I have used similar script to this below for finding areas. Any help or advice is greatly appreciated. Thanks

                    <span class="syntaxdefault">model&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model<br />ents&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">entities<br />sel&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">selection<br />mat&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">sel</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">].</span><span class="syntaxdefault">material&nbsp;&nbsp;</span><span class="syntaxcomment">#&nbsp;selected&nbsp;items&nbsp;with&nbsp;material&nbsp;we&nbsp;are&nbsp;interested&nbsp;in<br /></span><span class="syntaxdefault">normal_vector&nbsp;</span><span class="syntaxkeyword">=&nbsp;</span><span class="syntaxdefault">0<br /></span><span class="syntaxcomment">#&nbsp;go&nbsp;through&nbsp;all&nbsp;the&nbsp;entities<br /></span><span class="syntaxdefault">ents</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">each&nbsp;</span><span class="syntaxkeyword">do&nbsp;|</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">|<br />if&nbsp;</span><span class="syntaxdefault">e&nbsp;is_a</span><span class="syntaxkeyword">?&nbsp;</span><span class="syntaxdefault">Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">Face&nbsp;&nbsp;</span><span class="syntaxcomment">#&nbsp;if&nbsp;e&nbsp;is&nbsp;a&nbsp;face<br /></span><span class="syntaxkeyword">if&nbsp;</span><span class="syntaxdefault">e</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">material</span><span class="syntaxkeyword">==</span><span class="syntaxdefault">mat&nbsp;&nbsp;</span><span class="syntaxcomment">#if&nbsp;e&nbsp;material&nbsp;is&nbsp;the&nbsp;material&nbsp;of&nbsp;the&nbsp;selected&nbsp;entity<br /><br />#&nbsp;normal&nbsp;equals&nbsp;initial&nbsp;normal&nbsp;vector&nbsp;plus&nbsp;the&nbsp;new&nbsp;normal&nbsp;vector<br />#this&nbsp;returns&nbsp;the&nbsp;normal&nbsp;of&nbsp;the&nbsp;selected&nbsp;face<br /></span><span class="syntaxdefault">normal_vector&nbsp;</span><span class="syntaxkeyword">=&nbsp;&nbsp;</span><span class="syntaxdefault">normal_vector&nbsp;</span><span class="syntaxkeyword">+&nbsp;</span><span class="syntaxdefault">face</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">normal<br /><br />end&nbsp;&nbsp;</span><span class="syntaxcomment">#end&nbsp;if<br /></span><span class="syntaxdefault">end&nbsp;&nbsp;</span><span class="syntaxcomment">#end&nbsp;if<br /></span><span class="syntaxdefault">end&nbsp;&nbsp;</span><span class="syntaxcomment">#end&nbsp;loop<br /><br /></span><span class="syntaxdefault">puts&nbsp;normal_vector</span>
                    
                    1 Reply Last reply Reply Quote 0
                    • Dan RathbunD Offline
                      Dan Rathbun
                      last edited by

                      this:
                      normal_vector = normal_vector + face.normal

                      will not work as expected, if you set normal_vector to reference the integer object 0, because the integer +() method will get called, and it is not likely that it would know how to handle an argument that references a Geom::Vector3d object.

                      Smarter to create either a unit vector object to start with, or a zero length vector:
                      normal_vector = Geom::Vector3d.new(0,0,0)

                      THEN, when you call the +() method using:
                      normal_vector = normal_vector + face.normal
                      the special vector addition API method will get called.

                      In other words your statement is evaluated as if it were written:
                      normal_vector.=( normal_vector.+( face.normal ) )

                      This is one of the important things about Ruby... = and + (etc,) are not really operators, they are instance method names.

                      💭

                      I'm not here much anymore.

                      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