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

    EntitiesObserver and attributes

    Scheduled Pinned Locked Moved Developers' Forum
    7 Posts 2 Posters 164 Views 2 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.
    • R Offline
      rvs1977
      last edited by

      Hi,

      Im working with EntitiesObserver, and having trouble understanding the method
      def onElementModified(entities, entity).

      For instance, if you add an EntitiesObserver to a group consisting of a face, the EntitiesObserver will fire when you doubleclick the group and alter the face.

      (Eg. moving one of the edges so that the area of the face will increase.) In that case it will fire 3 times because 2 edges will get longer, and the face itself will increase in size.

      If you have set an attribute to the face it is then possible to retrieve the value by saying
      myFaceAttr = entity.get_attribute "rsdict", "face_attr", and you can set a new value with set_attribute "rsdict", "face_attr", "new value".

      But now my question is: what if I have an attribute set to the group, and I want to alter that when the EntitiesObserver fires. Is it possible to see name of the parent of the entity? (The face is a child of the group)

      Hope the question is understandable... πŸ˜’

      -Rasmus


      Get a Ruby

      1 Reply Last reply Reply Quote 0
      • Dan RathbunD Offline
        Dan Rathbun
        last edited by

        @rvs1977 said:

        But now my question is: what if I have an attribute set to the group, and I want to alter that when the EntitiesObserver fires. Is it possible to see name of the parent of the entity? (The face is a child of the group)

        model#active_path

        Get the group instance's name from inside the observer callback:

        editpath = entities.model.active_path
        grp =( editpath.size > 0 ? editpath.last ; nil )
        name =( grp ? grp.name ; "" )
        
        

        Get the group definition's name from inside the observer callback:

        entities.parent.name
        

        A Group is a special flavour ComponentInstance, so it therefor has a ComponentDefinition, which is the real owner of the Entities collection.

        πŸ’­

        I'm not here much anymore.

        1 Reply Last reply Reply Quote 0
        • R Offline
          rvs1977
          last edited by

          Thank you Dan, but I try to explain it again:

          My goal is to set an attribute to the group when a face has been modified. As you can see in the code below Im able to set an attribute to the face inside the group, but not the group containing the face. Do you have any ideas how to work around this problem?

          If the group is called rsgroup:

          yv_face_height = rsgroup.entities.add_face pts[0..3]
          rsgroup.set_attribute "rsdict","area", yv_area
          yv_face_height.set_attribute "rsdict", "yv_face_area", yv_area

          class MyEntitiesObserver < Sketchup;;EntitiesObserver        
              def onElementModified(entities, entity)    
                  
                  attr_area = entity.get_attribute "rsdict", "yv_face_area"       
          				
                          if attr_area
                              yv_area_new = i.area.to_m.to_m                          
                              entity.set_attribute "rsdict", "yv_face_area", yv_area_new
          
                              #(HERE I WOULD LIKE TO SET THE ATTRIBUTE OF THE GROUP-something like;)
                              entity.parent.set_attribute "rsdict","area", yv_area_new
          			
                          end #attr_area       
                  
              end #onElementModified_end   
          end #class
          

          Get a Ruby

          1 Reply Last reply Reply Quote 0
          • Dan RathbunD Offline
            Dan Rathbun
            last edited by

            I showed you how to get a reference to the group (named grp in my example, above.)
            Just ignore the calls to get the name ... BUT ...

            ... you have a vicious circle situation.

            Changing attributes fires observers on Entities collections.

            In SketchUp:
            I made a box and grouped it. And left it selected.
            I made a ref to the group:
            grp = Sketchup.active_model.selection[0]

            At the Ruby Console, I defined a quick checker class:

            class Spy; attr_accessor(;name); def initialize(spy); @name = spy.to_s; end; alias_method(;has_method?,;respond_to?); # override respond_to? method; def respond_to?(meth); puts("\nSpy '#{self.name}' method '#{meth.to_s}' was called by Sketchup."); has_method?(meth); end; end
            

            Then made two spy instances:
            mspy = Spy.new("Model Entities Spy") gspy = Spy.new("Group Entities Spy")

            And attached them:
            Sketchup.active_model.entities.add_observer(mspy) grp.entities.add_observer(gspy)

            Then added a dummy attribute:
            grp.set_attribute "rsdict","area", (1.23).to_l.to_m.to_m

            This was the output to the console:
            [pre:gsyu95n9]Spy 'Model Entities Spy' method 'onElementAdded' was called by Sketchup.

            Spy 'Model Entities Spy' method 'onElementRemoved' was called by Sketchup.

            Spy 'Model Entities Spy' method 'onElementModified' was called by Sketchup.

            Spy 'Group Entities Spy' method 'onElementAdded' was called by Sketchup.

            Spy 'Group Entities Spy' method 'onElementRemoved' was called by Sketchup.

            Spy 'Group Entities Spy' method 'onElementModified' was called by Sketchup.[/pre:gsyu95n9]

            Problem is you are already within the EntitiesObserver instance attached to the Group's Entities collection !
            You must be careful not to set up an infinite loop !

            Changing the model from within observer callbacks can crash SketchUp !

            ❗

            I'm not here much anymore.

            1 Reply Last reply Reply Quote 0
            • R Offline
              rvs1977
              last edited by

              @dan rathbun said:

              Problem is you are already within the EntitiesObserver instance attached to the Group's Entities collection !
              You must be careful not to set up an infinite loop !

              Changing the model from within observer callbacks can crash SketchUp !

              Ok, for now I will abandon this approach.

              Please consider this example:

              
              mod = Sketchup.active_model
              ent = mod.entities 
                    i = 0		
              		h= {}
              		ent.each do |o|
              		attr = o.get_attribute "rsdict","area"		
                  
              			if attr 					
              			   h[i] = {'structid' => 201, 'area' => attr}		
              			   i += 1;			
              			end
              		end
              

              Here it scans the entire model for groups with the attribute_dictionary "rsdict", "area".

              Lets say it finds a group with the "rsdict" attribute. Inside the group there are a face
              with an attribute attached to it.

              Is it possible to scan that group for all its entities? Something like this:

              
              mod = Sketchup.active_model 
              ent = mod.entities 
                    i = 0		
              		h= {}
              		ent.each do |o|
              		attr = o.get_attribute "rsdict","area"		
                  
              			if attr
                                         o.entites.each do |u|
                                         yv_face_area = u.get_attribute "rsdict", "yv_face_area"
              
                                         if yv_face_area
                                             h[i] = {'structid' => 201, 'area' => yv_face_area}			                       i += 1;
                                         end		  			
              			end
              		end
              

              Get a Ruby

              1 Reply Last reply Reply Quote 0
              • Dan RathbunD Offline
                Dan Rathbun
                last edited by

                Something more like:

                mod = Sketchup.active_model
                ent = mod.entities
                h = {}
                ent.each_with_index do |o,i|
                  next unless o.is_a?(Sketchup;;Group)
                  attr = o.get_attribute("rsdict","area")
                  if attr
                    o.entities.each do |u|
                      next unless o.is_a?(Sketchup;;Face)
                      yv_face_area = u.get_attribute("rsdict", "yv_face_area")
                      if yv_face_area
                        h[i] = {'structid' => 201, 'area' => yv_face_area}
                      end             
                    end                 
                  end
                end
                

                I wonder why you are using ordinal integers as hash keys ??
                You might as well just use an array:

                mod = Sketchup.active_model
                ent = mod.entities
                h = []
                ent.each do |o|
                  next unless o.is_a?(Sketchup;;Group)
                  attr = o.get_attribute("rsdict","area")
                  if attr
                    o.entities.each do |u|
                      next unless o.is_a?(Sketchup;;Face)
                      yv_face_area = u.get_attribute("rsdict", "yv_face_area")
                      if yv_face_area
                        h << {'structid' => 201, 'area' => yv_face_area}
                      end
                    end
                  end
                end
                

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • R Offline
                  rvs1977
                  last edited by

                  Great, this solved my problem! Thank you very much Dan! πŸ˜„


                  Get a Ruby

                  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