[solved!!]onMouseMove show component instance
-
no totally error free BUT..i just made it work by.....(drumroll)... changing .transform!() to .move!()
I don't know why it worked...i just did it on a whim, but presto!
thanks for all the help, this was driving me crazy...so much thesis to do, but I tend to obsess on things I cant solve.
cheers
Korbin -
@kdasilva said:
no totally error free BUT..i just made it work by.....(drumroll)... changing .transform!() to .move!()
I don't know why it worked...i just did it on a whim, but presto!
thanks for all the help, this was driving me crazy...so much thesis to do, but I tend to obsess on things I cant solve.
cheers
KorbinI was just going to suggest .move! instead of .transform! as it's 'outside of the undo stack'... [honest!]
Glad it's working at last... -
(I'm not sure that there is a question in this - its more of me just talking out loud).
I'm trying to do the same, and I'm getting the problem that once I attache the component to the cursor, then the ip point easily grabs onto the component when the mouse moves. And sine the component is closer to the camera, than the center of the component that is attached tot he cursor, then the ip jumps to the closer position, moving the whole component closer. And repeats. So every time I start move the mouse,t he component gets closer and closer to the camera until it clips out of view, and the mouse can reach geometry in the model to reset the ip back to the model.
I have not thought much about this yet, but I was wondering how you guys got it to work? It just doesn't seem to do the trick for me. I was really hoping it would be easy to place a component in the model, and have the component attach to the cursor.
Its not the end of the world if it turns out to not work, I don't truly need to show the component.
-
Do you need a custom tool? Can you not use model.place_component ?
-
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.
-
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
. -
Ok.. you could call:
lastdefn = defn.instances.last
after usingmodel.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 afalse
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. -
Agree 100% with you Dan.
-
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 )
-
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.
-
@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.
-
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'
-
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..?
-
@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
-
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= -
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
-
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 usinginstance.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 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?
-
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 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_component
the same context asSketchup.active_model.entities
?
Advertisement