Axes question
-
I'm trying to understand how axes works and have a script where axes are set to a custom value. I create a face and a group and still the origin and axes of the group is the default origin and axes.
Why doesn't it respect the new working axes?
If I do it in the UI it works as expected and I get it to line up with the custom axes set in the script.I'm looking for a way of not having to transform everything back to origo to get group/component origin and axes correctly as this workflow has caused issues with certain values and rotation directions for me.
I found the
Sketchup.active_model.axes.set(origin, xaxis, yaxis, zaxis)
and thought it might be possible to:First, store the current axes.
Set origin and axes to some custom value.
Then do stuff within the new origin and axes. (Like creating a face and group it and have groups and components to have their axis set correct.)
And finally reset axes as they were before the script was executed.I got really exited about this and was hoping it could be a work around until we get proper set axes for components and groups.
If done in the UI it works so why doesn't it within my script?
-
Here is a small test script that describes what I'm after.
Only that it doesn't align the created groups axis with the set axes.
Any ideas?
Note that for this test I have hard coded some points and vectors.module JS class Axestest model=Sketchup.active_model entities=model.active_entities # First we save the current origin and axes so we can reset back to them when we are done. current_origin = Geom;;Point3d.new(model.axes.origin) current_xaxis = Geom;;Vector3d.new(model.axes.xaxis) current_yaxis = Geom;;Vector3d.new(model.axes.yaxis) current_zaxis = Geom;;Vector3d.new(model.axes.zaxis) # Debug puts current_origin.to_a puts current_xaxis.to_a puts current_yaxis.to_a puts current_xaxis.to_a # Now get the point for the temp_origin and temp_axes temp_origin = Geom;;Point3d.new(20, 10, 0) temp_xaxis = Geom;;Vector3d.new(1, 1, 0) temp_yaxis = Geom;;Vector3d.new(-1, 1, 0) temp_zaxis = Geom;;Vector3d.new(Z_AXIS) # Set the origin and axes to the temp_axes model.axes.set(temp_origin, temp_xaxis, temp_yaxis, temp_zaxis) # Do stuff here to (hopefully) "set" group/component axes correctly align with the object pt0=Geom;;Point3d.new(10, 20, 0) pt1=Geom;;Point3d.new(20, 30, 0) pt2=Geom;;Point3d.new(20, 10, 0) pt3=Geom;;Point3d.new(30, 20, 0) group=entities.add_group entities=group.entities base=entities.add_face(pt0, pt2, pt3, pt1) # At the end reset the axes model.axes.set(current_origin, current_xaxis, current_yaxis, current_zaxis) end#class end#module
-
No one?
-
I solved this problem by doing it a bit differently. I set the axes to the temp axes and then create all geometry and groups/components at original "world" origo and then at the end used
tr = Sketchup.active_model.axes.transformation
to transform the component to the temp axes and finally revert axes back to what it was before.Maybe it's an unorthodox way of doing it but I found that by creating everything at world origo it was much easier to add stuff. And it works well with all components axis set perfectly.
Here is a small test script that shows the process if anyone is interested.
module JS class Axestest model=Sketchup.active_model entities=model.active_entities # First we save the current origin and axes so we can reset back to them when we are done. current_origin = Geom;;Point3d.new(model.axes.origin) current_xaxis = Geom;;Vector3d.new(model.axes.xaxis) current_yaxis = Geom;;Vector3d.new(model.axes.yaxis) current_zaxis = Geom;;Vector3d.new(model.axes.zaxis) # Now get the point for the temp_origin and temp_axes (Hardcoded for this example) temp_origin = Geom;;Point3d.new(20, 10, 0) temp_xaxis = Geom;;Vector3d.new(1, 1, 0) temp_yaxis = Geom;;Vector3d.new(-1, 1, 0) temp_zaxis = Geom;;Vector3d.new(Z_AXIS) # Set the origin and axes to the temp_axes model.axes.set(temp_origin, temp_xaxis, temp_yaxis, temp_zaxis) # Point for a rectangle. points = [ Geom;;Point3d.new( 0, 0, 0), Geom;;Point3d.new(10, 0, 0), Geom;;Point3d.new(10, 20, 0), Geom;;Point3d.new( 0, 20, 0) ] group=entities.add_group entities=group.entities base=entities.add_face(points) tr = Sketchup.active_model.axes.transformation # Transform the group/component so that it is local to the temp axes. group.transform!(tr) # At the end reset the axes model.axes.set(current_origin, current_xaxis, current_yaxis, current_zaxis) end#class end#module
-
You might have missed the fact that the virtual helper classes Point3d, Vector3d and Array, can be transformed.
So if you were not creating a group, you could do before actually creating the geometry:
points.map! {|pt| pt.transform!(tr) }
For a group, you can actually apply the transform to the group, before adding the geometry. (You might need to assign a temporary cpoint to prevent SketchUp from garbage collecting it, as is normal.)
This will prevent the users from seeing geometry appear in a strange place. -
@pixero said:
I'm trying to understand how axes works and have a script where axes are set to a custom value. I create a face and a group and still the origin and axes of the group is the default origin and axes.
Why doesn't it respect the new working axes?
Only the native tools respect the custom Axes setting by default.
If they had suddenly changed the API so that ALL code creating geometry in model space used the custom axes, they'd have broken a multitude of extensions, causing havoc.
Another facet, is that the original model origin and axes actually remain unchanged.
So, anyway, they decided that coders themselves had to decide to honor the user's custom axes settings.
-
Add coming from all this would be the need to detect when the user changes the axes:
# encoding; UTF-8 # # A simple Axes Observer to detect when a user changes axes. module Author class AxesSpy < Sketchup;;EntityObserver @@instance ||= self;;new def self;;attach( mod = Sketchup.active_model ) mod.axes.add_observer(@@instance) end def onNewModel(mod) self;;attach(mod) end alias_method ;onOpenModel, ;onNewModel def expectsStartupModelNotifications() true end def onChangeEntity(ent) puts "AxesSpy; #{ent.inspect} changed." end Sketchup.add_observer(@@instance) end end
- Note that the Axes object was first exposed with SketchUp 2016.
Edit: Fixed
alias_method
call. args were swapped, in error.
(I always seem to get them backwards. I always think "alias this as that", but it is more like "newalias that of this".) -
Thanks for the info.
Advertisement