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

    [solved!!]onMouseMove show component instance

    Scheduled Pinned Locked Moved Developers' Forum
    32 Posts 9 Posters 3.5k Views 9 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.
    • K Offline
      kaas
      last edited by

      I'm trying out several methods for a plugin-user to define a plane. Picking 3 points works but maybe more easy would be to use a component plane thats glues to the underlying objects.

      Using the code from this thread I can attach a component-plane to the mouse pointer.

      behavior = @plane_def.behavior behavior.snapto = SnapTo_Arbitrary behavior.is2d = true

      Adding this code makes the component-plane glue to objects but only outside the ruby code as it seems. The glue works if the component is picked from the component browser OR if the component is added with model.place_component componentdefinition, repeat. Then I would have to add an observer to have the code pick it up again.

      Is there any way around this?

      edit: changed 'listener' to 'observer'

      1 Reply Last reply Reply Quote 0
      • tt_suT Offline
        tt_su
        last edited by

        In addition to changing the behaviour you need to use glued_to= to specify what it should be glued to.

        ...or maybe I didn't quite understand what you where asking for..?

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

          @tt_su said:

          In addition to changing the behaviour you need to use glued_to= to specify what it should be glued to.

          Hello Thomas, Thanks for your reply.

          I want the component to glue to any face in the model, just like a normal glue-ing component would do, if inserted from the component browser.

          Funny part is: when using the code below the instance doesn't glue. If I manually pick the component afterwards from the component browser and place it, it does glue...??

          def activate
          	@model = Sketchup.active_model
          	@definitions = @model.definitions
          	@entities = @model.entities	
                  @ip = Sketchup;;InputPoint.new
          	@ipP = Sketchup;;InputPoint.new	
          		
          	size = 20
          	pm = Geom;;PolygonMesh.new
          	pm.add_point([-size, -size, 0]) # 1
          	pm.add_point([-size, size, 0]) # 2
          	pm.add_point([size, size, 0]) # 3
          	pm.add_point([size, -size, 0]) # 4
          	pm.add_polygon(1,3,2,4)
          	
          	smooth_flags = Geom;;PolygonMesh;;NO_SMOOTH_OR_HIDE
          	mb_rundim_plane_def = @definitions.add("mb_runDimPlane");
          	dim_plane = mb_rundim_plane_def.entities.add_faces_from_mesh(pm, smooth_flags)
          	behavior = mb_rundim_plane_def.behavior
          	behavior.snapto = SnapTo_Arbitrary
          	behavior.is2d = true
          	
          	@instance = @entities.add_instance(mb_rundim_plane_def, ORIGIN)
          end # def activate
          
          def onMouseMove(flags, x, y, view)
            @ip.pick(view, x, y)
            if @ip != @ipP && @instance
              view.invalidate if( @ip.display? or @ipP.display? )
              @ipP.copy!(@ip)
              view.tooltip=@ipP.tooltip
              @instance.move!(Geom;;Transformation.new(@ipP.position))
            end
          end
          
          def onLButtonDown(flags, x, y, view)
            return nil if not @instance
            @ipP.pick(view, x, y)
            if @ipP.valid?
              @instance.move!(Geom;;Transformation.new(@ipP.position))
              @instance=nil
            end
          end
          
          1 Reply Last reply Reply Quote 0
          • TIGT Online
            TIG Moderator
            last edited by

            You must tell SketchUp which face to glue it onto.
            You could do that by using a ' pickhelper' which is activated 'on button up'... which finds the best face-match http://www.sketchup.com/intl/en/developer/docs/ourdoc/pickhelper#picked_face
            And then use:
            @instance.glued_to=some_face_that_you_specify_from_pickhelper
            See http://www.sketchup.com/intl/en/developer/docs/ourdoc/componentinstance#glued_to=

            TIG

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

              Hi TIG,

              Thanks for your suggestion. I changed the code, drew a simple rectangle and pushed-pulled it. After picking it throws an error on the 'glue-line':
              Error: #<ArgumentError: Can only glue to something in the same component>
              Doesn't make sense to me. They should be both in the same context: Sketchup.active_model.entities. Google-ing this error results in another thread you were active in http://sketchucation.com/forums/viewtopic.php?f=180%26amp;t=54813 but no help there. Any suggestions anyone?

              def onLButtonUp(flags, x, y, view)
              	ph = view.pick_helper
              	ph.do_pick(x, y)
              	face = ph.picked_face
              	@instance.move!(Geom;;Transformation.new(@ipP.position))
              	view.invalidate
              	if face
              		@instance.glued_to=face
              	end	
              end
              
              1 Reply Last reply Reply Quote 0
              • TIGT Online
                TIG Moderator
                last edited by

                You need to set ents=model.active_entities and add the instance to that entities context.
                BUT if the face you pick is inside another context you cannot glue to it.
                You can check that by using instance.parent.entities==face.parent.entities

                Why not use the way that mimics the native component placer - http://www.sketchup.com/intl/en/developer/docs/ourdoc/model#place_component

                You already have the gluing definition, so you can erase the placed instance/code... and there is no need to then find the face at all ?

                TIG

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

                  @tig said:

                  ..Why not use the way that mimics the native component placer - http://www.sketchup.com/intl/en/developer/docs/ourdoc/model#place_component...

                  I gave your suggestion a go. Instead of adding the component to the mouse I used @model.place_component ... and have the code pick it up again with an observer.

                  Problem I now face: the newest added instance doesn't show up if I look for it. My guess is: its returning the definition info instead.

                  I tried:

                  @entities.each {|e|
                     puts e.to_s
                     next unless e.is_a?(Sketchup;;ComponentInstance)
                     puts "instance; #{e.to_s}"
                     puts "origin; #{e.transformation.origin}"
                  }
                  
                  

                  OR

                  	
                     instance = @definitions[instance_def_name]
                     puts "instance; #{instance.instances[0].to_s}"
                     puts "origin; #{instance.instances[0].transformation.origin}"
                  
                  

                  Only if I add another (and another) instance, all but the last one are found (see animated gif).

                  I must be missing something elementary... Any suggestions?


                  problem.gif

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

                    You already have a reference to the instance called @instance - so, without re-coding [so you make a definition rather than an instance], you can get a reference to the instance's definition thus: @defn=@instance.definition, then immediately erase the instance with @instance.erase!...
                    And then you NOW use @model.place_component(@defn) πŸ˜•

                    TIG

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

                      @tig said:

                      You already have a reference to the instance called @instance - so, without re-coding [so you make a definition rather than an instance], you can get a reference to the instance's definition thus: @defn=@instance.definition, then immediately erase the instance with @instance.erase!...
                      And then you NOW use @model.place_component(@defn) πŸ˜•

                      ...? I changed the code a bit compared what I posted a few posts above. Now, at the start of model.place_component for the first time there is no instance in the model, only a definition. So I'm not sure what I should delete here.

                      I ask myself: is the result of Sketchup.active_model.place_componentthe same context as Sketchup.active_model.entities?

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

                        Still trying to figure it out. Tested it by putting the code directly into the Ruby Console and putting it into a rb-file.

                        Try with a freshly started Sketchup 2014 and delete 'Sophie' (but leave her in the component definitions). First I executed in the Ruby Console:

                        
                        @model = Sketchup.active_model
                        @ents = @model.entities
                        @defs = @model.definitions
                        inst = @defs["Sophie"]
                        @model.place_component inst,false
                        
                        

                        Place her anywhere but not on the origin 0,0,0

                        Second run this:

                        
                        @ents.each {|e|
                        next unless e.is_a?(Sketchup;;ComponentInstance)
                        puts e.transformation.origin
                        }
                        
                        

                        You get the proper coordinates of Sophie.

                        Now I delete all Sophies but leave her in the component definitions.
                        I wrap the above code into a plugin. I need to add an observer so the code can pick it up again (place_component breaks the code). I load it and start it with: MB_place_instance.activate

                        The first placed instance always returns 0,0,0 as the origin. Add another one (activate again) and it returns the origin of the first added instance etc... Looks like its returning the definition and not the placed instance.

                        There must be some logic in it but I fail to see it...

                        
                        require 'sketchup.rb'
                        module MB_place_instance
                        
                        	class MyDefObserver < Sketchup;;DefinitionObserver ### create an observer (place_component breaks the code and returns to SU) ###
                        	   def onComponentInstanceAdded(definition, instance)
                        		 puts "observer has fired; " + instance.to_s
                        		 MB_place_instance.refire(instance) # go back to the tool
                        	   end
                        	end
                        
                        	def self.activate
                        		@model = Sketchup.active_model
                        		@ents = @model.entities
                        		@defs = @model.definitions
                        		inst = @defs["Sophie"]
                        		@observer = MyDefObserver.new
                        		@model.definitions[0].add_observer(@observer)
                        		@model.place_component inst,false
                        	end #def
                        	
                        	def self.refire(instance)
                        		@defs[0].remove_observer(@observer) # delete the observer
                        		@observer = nil # delete the observer in case previous method fails
                        		GC.start # collect garbage
                        		@ents.each {|e|
                        			next unless e.is_a?(Sketchup;;ComponentInstance)
                        			puts "looking with each; #{e.transformation.origin}"
                        		}	
                        		puts "directly adressing passed instance; #{instance.transformation.origin}"
                        	end #def
                        	
                        end #module
                        
                        ### start in RubyConsole with; MB_place_instance.activate
                        
                        
                        1 Reply Last reply Reply Quote 0
                        • 1
                        • 2
                        • 1 / 2
                        • First post
                          Last post
                        Buy SketchPlus
                        Buy SUbD
                        Buy WrapR
                        Buy eBook
                        Buy Modelur
                        Buy Vertex Tools
                        Buy SketchCuisine
                        Buy FormFonts

                        Advertisement