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

    Ruby Component Insertion and Attributes - Not Updating

    Scheduled Pinned Locked Moved Developers' Forum
    7 Posts 3 Posters 8.4k Views 3 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.
    • placidfuryP Offline
      placidfury
      last edited by

      Hi all,

      I hope this is the right forum to post this in.
      I am pretty new to making my own Ruby scripts, so I'm not sure how to do this.
      I have some dynamic components I have made, and exported them out of the model as their own .skp files. I want my script to get two points from the user, then load and insert the component at the point specified by the first click, scale it along one axis, then rotate it into position so the second end is at the point specified by the second click. There is also I prompt for the user to set certain values, which are then applied to attributes on the component, as well as the geometry changed.
      I have everything working more or less perfectly, with one exception: While the attributes are set on the component, the geometry and textures are not updated on the model until I either edit the components properties manually, or scale it manually.
      How would I go about having Ruby update the appearance of the component after all the attributes are changed?
      Here's a truncated version/snippet of what I have:

      
      #load the file
      newcomp_def = Sketchup.active_model.definitions.load("Q;\Test.skp")
      #create insertion transform
      trans1 = Geom;;Transformation.new p1
      #transform scale along y to correct size
      trans2 = Geom;;Transformation.scaling p1, 1, (length/12), 1
      #move the box over since in my model it's centered and I want it on edge
      scootvec = Geom;;Vector3d.new (width/2),0,0
      #create transform from vector
      trans3 = Geom;;Transformation.translation scootvec
      entities = Sketchup.active_model.active_entities
      #insert component at point 1
      instance = entities.add_instance newcomp_def, trans1
      #scale it to length
      instance.transform! trans2
      #move it over by half
      instance.transform! trans3
      #rotate it to the correct angle
      instance.transform! transrot
      #set attributes
      instance.set_attribute("dynamic_attributes", "product", "Name")
      instance.set_attribute("dynamic_attributes", "width", width)
      instance.set_attribute("dynamic_attributes", "depth", depth)
      
      

      I have formulas on the component to set the textures, x and z dimension, etc. I have confirmed the values are changed by going into the component editor, the appearance just doesn't change/isn't updated.
      Is it simple to accomplish this?

      Thanks!

      PlacidFury

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

        After the changes you need to force it to regenerate...
        Something like this:

        def self.dc_redraw(ent, pbar_visible=true, undo=false)
            ldc = $dc_observers.get_latest_class()
            if undo
                ldc.method(;redraw_with_undo).call(ent, pbar_visible)
            else
                ldc.determine_movetool_behaviors(ent)
                DCProgressBar;;clear()
                ldc.method(;redraw).call(ent, pbar_visible)
                DCProgressBar;;clear()
                ldc.refresh_dialogs()
            end
            Sketchup.active_model.active_view.refresh
            rescue TypeError => e
            # suppress nil to float conversion error that happens
            # when redraw is called directly with true 2nd arg ?
        end#def
        

        Then at the end of your changes use: self.dc_redraw(instance, true, false)

        TIG

        1 Reply Last reply Reply Quote 0
        • placidfuryP Offline
          placidfury
          last edited by

          Perfect! Got it going. Thanks!

          1 Reply Last reply Reply Quote 0
          • PixeroP Offline
            Pixero
            last edited by

            Thanks TIG for the redraw DC code.
            However I have a question about the speed of the redraw.
            For my testing DC component that is fairly simple (a window) it takes approximately 4 to 10 seconds to redraw.
            Is that normal?
            Is there any way of speeding it up?

            Edit:
            Here are a few more times for redraw the same DC.
            5.579584 seconds to redraw
            5.536248 seconds to redraw
            4.532769 seconds to redraw
            4.360298 seconds to redraw
            4.269832 seconds to redraw
            9.777517 seconds to redraw

            1 Reply Last reply Reply Quote 0
            • PixeroP Offline
              Pixero
              last edited by

              No one knows anything about this?

              1 Reply Last reply Reply Quote 0
              • PixeroP Offline
                Pixero
                last edited by

                If anyone is interested I tried with this code and it's almost instant. 😄

                #Redraw to update the DC
                dcs = $dc_observers.get_latest_class
                dcs.redraw_with_undo(cinst)
                
                1 Reply Last reply Reply Quote 0
                • placidfuryP Offline
                  placidfury
                  last edited by

                  Just now saw this - I have been unable to get a batch redraw of DC's to not take significant time. It seems the more DC's you redraw in the same operation, the longer each successive one takes to redraw.
                  Eventually, I found a way around this by simply scrapping my usage of DC's and switching to groups. Operations on groups are essentially instantaneous.
                  I'd use DC's if it's one or few objects at a time, or something I want the user to be able to interact with via the DC interface, but most of my plugin's objects are not that - I'm manipulating them with my code. Since I'm doing Engineered Wood Products layouts on very large multifamily buildings, I end up with thousands of objects to manipulate, and DC's simply didn't work well enough, as they were too slow. And the fact that even changing one property - even one that doesn't affect geometry - forces you to have to redraw them each, that time involved was a deal-breaker.

                  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