• 登入
sketchucation logo sketchucation
  • 登入
⚠️ Libfredo 15.4b | Minor release with bugfixes and improvements Update

[solved!!]onMouseMove show component instance

已排程 已置頂 已鎖定 已移動 Developers' Forum
32 貼文 9 Posters 3.5k 瀏覽 9 Watching
正在載入更多貼文
  • 從舊到新
  • 從新到舊
  • 最多點贊
回覆
  • 在新貼文中回覆
登入後回覆
此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
  • C 離線
    Chris Fullmer
    最後由 編輯 2011年10月30日 上午3:43

    I think I do - I need to know what edge in what group it was placed on so I can break the edge and insert new geometry. I can do all that easy enough if I do it with my own tool. But I'm scared of relying on too many observers. I've had bad luck with them already, and I know you (thom) have had many projects ruined by them.

    So I think I need my own tool. Its working ok though, I'm actually drawing lines to the viewport that represent the component I'm placing. I can attach that to the mouse easy enough, and it looks pretty cool.

    Lately you've been tan, suspicious for the winter.
    All my Plugins I've written

    1 條回覆 最後回覆 回覆 引用 0
    • D 離線
      Dan Rathbun
      最後由 編輯 2011年10月30日 上午8:20

      Hmmm... would have been nice if the method returned a ref to the newly placed instance (instead of the model object itself*****.) Then you might have been able to easily get the instances origin point and go from there.

      Just weird that a ref to the placed instance is the obvious preferred return for a method like this. Sometimes I just do not understand how the obvious can be so often overlooked.

      ***** The API doc is in error when it says it returns nil.

      I'm not here much anymore.

      1 條回覆 最後回覆 回覆 引用 0
      • D 離線
        Dan Rathbun
        最後由 編輯 2011年10月30日 上午8:50

        Ok.. you could call:
        lastdefn = defn.instances.last
        after using model.place_component( defn, false )

        Wait... weirdness, the method returns immediately, BEFORE the instance is actually placed. (It spits out a redraw time to $stdout after the instance is placed.) The move component tool does not exit with a false 2nd arg, but remains in the move tool, and the user could inadvertently move the instance again.
        It would be nice if this method took a block to be run after the instance was placed.

        I'm not here much anymore.

        1 條回覆 最後回覆 回覆 引用 0
        • T 離線
          thomthom
          最後由 編輯 2011年10月30日 上午10:07

          Agree 100% with you Dan.

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

          1 條回覆 最後回覆 回覆 引用 0
          • F 離線
            fatihbarut
            最後由 編輯 2011年11月19日 下午6:31

            I think eventhough the title has "Solved" the last solution is missing

            Here is one of them.

            
            model = Sketchup.active_model
            ent = model.entities
            sel = model.selection
            
            defn = Sketchup.active_model.definitions
            
            def onMouseMove(flags, x, y, view)
              return nil if not @instance ### only works when instance is set
              @ip.pick(view, x, y)
              if @ip != @ip1
                view.invalidate if( @ip.display? or @ip1.display? )
                @ip1.copy!(@ip)
                view.tooltip=@ip1.tooltip
                @instance.transform!(Geom;;Transformation.new(@ip1.position))
              end
            end
            
            def onLButtonDown(flags, x, y, view)
              return nil if not @instance
              @ip1.pick(view, x, y)
              if @ip1.valid?
                @instance.transform!(Geom;;Transformation.new(@ip1.position))
                @instance=nil ### un-sets instance
              end
            end
            
            lastdefn = defn[0] # ! I had just one definition in my component definition list therefor defn[0] worked well for me
            model.place_component( lastdefn , false )
            
            
            1 條回覆 最後回覆 回覆 引用 0
            • J 離線
              Jim
              最後由 編輯 2011年11月20日 上午1:33

              As has been discovered already in this thread, you probably want to use @instance.move!(..) rather than .transform!(..) so as not to disturb the Undo stack.

              Another idea might be to use the opengl draw commands to draw a proxy object instead of actually moving an Instance with the mouse.

              Hi

              1 條回覆 最後回覆 回覆 引用 0
              • C 離線
                Chris Fullmer
                最後由 編輯 2011年11月20日 上午6:44

                @jim said:

                Another idea might be to use the opengl draw commands to draw a proxy object instead of actually moving an Instance with the mouse.

                That's what I ended up doing, which was disappointing to me, but still looks pretty cool.

                Lately you've been tan, suspicious for the winter.
                All my Plugins I've written

                1 條回覆 最後回覆 回覆 引用 0
                • K 離線
                  kaas
                  最後由 編輯 2014年8月26日 下午3:04

                  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 條回覆 最後回覆 回覆 引用 0
                  • tt_suT 離線
                    tt_su
                    最後由 編輯 2014年8月28日 上午8:35

                    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 條回覆 最後回覆 回覆 引用 0
                    • K 離線
                      kaas
                      最後由 編輯 2014年8月28日 下午3:51

                      @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 條回覆 最後回覆 回覆 引用 0
                      • TIGT 離線
                        TIG Moderator
                        最後由 編輯 2014年8月28日 下午4:12

                        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 條回覆 最後回覆 回覆 引用 0
                        • K 離線
                          kaas
                          最後由 編輯 2014年8月29日 上午11:46

                          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 條回覆 最後回覆 回覆 引用 0
                          • TIGT 離線
                            TIG Moderator
                            最後由 編輯 2014年8月29日 下午2:36

                            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 條回覆 最後回覆 回覆 引用 0
                            • K 離線
                              kaas
                              最後由 編輯 2014年8月30日 下午5:19

                              @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 條回覆 最後回覆 回覆 引用 0
                              • TIGT 離線
                                TIG Moderator
                                最後由 編輯 2014年8月30日 下午5:37

                                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 條回覆 最後回覆 回覆 引用 0
                                • K 離線
                                  kaas
                                  最後由 編輯 2014年8月30日 下午6:25

                                  @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 條回覆 最後回覆 回覆 引用 0
                                  • K 離線
                                    kaas
                                    最後由 編輯 2014年8月31日 上午9:18

                                    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 條回覆 最後回覆 回覆 引用 0
                                    • 1
                                    • 2
                                    • 2 / 2
                                    • 第一個貼文
                                      最後的貼文
                                    Buy SketchPlus
                                    Buy SUbD
                                    Buy WrapR
                                    Buy eBook
                                    Buy Modelur
                                    Buy Vertex Tools
                                    Buy SketchCuisine
                                    Buy FormFonts

                                    Advertisement