I notice this was last updated for SU 2015, last commit Nov 7 2014 - does it still work with SU 2016?
Latest posts made by archidave
-
RE: Call C++ from ruby in Sketchup
-
RE: SU2015 gives NoMethodError for Length class #abs method
Thanks for quick reply TIG.
we were testing on 15.2.685 Windows 64-bit and 15.2.686 Mac 64-bit
didn't know there was an update out - will try that... -
SU2015 gives NoMethodError for Length class #abs method
Since SU 2015, there seems to be a difference in the way the Length class handles the #abs method.
Up to and including SU 2014, it would return the absolute value as would be expected.However, in SU 2015 it is now generating Error: #<NoMethodError: undefined method `abs' for nil:NilClass>
eg. in SU 2014;
> 2.m.abs
78.740157480315but in SU 2015;
> 2.m.abs
gives the NoMethodErrorThis is pretty bad (it has broken my plugin for SU 2015) and means I now need to go hunting through the code for all occurrences of <Length>.abs replacing them with <Length>.to_f.abs and building-in extra validation where the class is not intrinsically known, just in case there could be a Length instead of a Float.
Anybody know why this has been changed? it seems pretty unhelpful
Dave
-
RE: Start and commit operation: how they work?
Hi all,
I've been trying to get to grips with Sketchup operations for some time now and reading the comments above from Dan and Thomas and also these older posts has really helped shed some light on it for me.
<code> wrapping operations
Model Operation blockform methods
Ruby, Undo Stack and dynamic components
start/commit_operationI realised part of the problems I was experiencing was due to nested operations, however I was still left with a conundrum; I need nested operations - because I have some code in low-level methods that works with Dynamic Components for example, and not encapsulating it with an operation either leads to very slow operation or littering the undo stack with "Properties". Putting an operation inside these methods fixed all the problems I was having there. However, these low-level methods can sometimes be called inside other methods with their own operation wrappers, for example when an action is invoked from the user-interface
I believe I have come up with a solution that allows low-level methods to have their own operation when they are called in isolation, but when they are called as part of a larger chain of operations, they become appended to the larger operation. When a
start_operation
is called, the operation name is also pushed on to the module's own stack. If there is already a higher level operation on the stack, the new operation is made transparent. When the operation finishes,commit_operation
is only called if the stack is empty, so that the whole composite operation is committed as the highest first (highest level) operation called.
This seems to work well in the trivial example below. Would appreciate your comments! Can you see any potential problems?cheers
Davemodule DME_Test @@op_stack = [] @@model = Sketchup.active_model def self.model # could handle changes of active_model here @@model end def self.error(op_name, err, call_stack=nil) model.commit_operation if !@@op_stack.empty? # should it abort_operation or commit_operation that was executed so far? @@op_stack.clear ;;UI.beep Sketchup.status_text="ERROR; #{op_name}" ;;UI.messagebox("ERROR; #{op_name} - Operation did not complete due to an error.") raise if $DEBUG # or module specific debug flag end # command level operations - directly called by user through menu items or toolbar def self.cmd1 op_name = "Cmd1" begin @@op_stack.push(op_name) if model.start_operation(op_name, disable_ui=false) macro_op(0,0,1,1) puts @@op_stack.pop model.commit_operation if @@op_stack.empty? rescue => err self.error(op_name, err, caller) else # ensure # end end def self.cmd2 op_name = "Cmd2" begin @@op_stack.push(op_name) if model.start_operation(op_name, disable_ui=false) # -- statements macro_op(1,1,1.5,1.5) # -- end statements puts @@op_stack.pop model.commit_operation if @@op_stack.empty? rescue => err self.error(op_name, err, caller) else # return result ensure # end end # A macro operation method, which may be combined with others in macro operations def self.macro_op(x,y,x_dim,y_dim) begin op_name = "draw square (#{x_dim} x #{y_dim})" prev_trans = !@@op_stack.empty? @@op_stack.push(op_name) if model.start_operation(op_name, disable_ui=false, trans=false, prev_trans) # -- statements grp = model.active_entities.add_group pt1 = minor_op(x,y) pt2 = minor_op(x,y+y_dim) pt3 = minor_op(x+x_dim,y+y_dim) pt4 = minor_op(x+x_dim,y) grp.entities.add_line(pt1,pt2) grp.entities.add_line(pt2,pt3) grp.entities.add_line(pt3,pt4) grp.entities.add_line(pt4,pt1) # -- end statements puts @@op_stack.pop model.commit_operation if @@op_stack.empty? rescue => err self.error(op_name, err, caller) else # return result return grp ensure # end end # A minor operation method, which may be combined with others in macro operations def self.minor_op(x,y) begin op_name = "add point (#{x},#{y})" prev_trans = !@@op_stack.empty? @@op_stack.push(op_name) if model.start_operation(op_name, disable_ui=true, trans=false, prev_trans) # -- statements pt = Geom;;Point3d.new(x,y,0) model.active_entities.add_cpoint(pt) # -- end statements puts @@op_stack.pop model.commit_operation if @@op_stack.empty? rescue => err self.error(op_name, err, caller) else # return result return pt ensure # end end end
-
RE: Start and commit operation: how they work?
Thanks Dan, useful to know, have edited.
Do you have any comments on the validity of the scheme above?
I've made some further changes in trying to implement this into my plugin - for handling multiple models on Mac, a separate stack is required for each model.
Also as an alternative: rather than making subsequent operations transparent, when there is already an op on the stack, both the start_operation and commit_operation could be conditional on the stack being empty. -
RE: Webdlg debugging on Mac using WebKit inspector
Does anyone know how to enable something like this on a Windows machine? The WebKit inspector on Mac is brilliant for debugging webdialogs, but I need to debug a problem that seems to be occurring on Windows only.
Is there a way to enable Firebug within the SketchUp webdialogs or some kind of native DOM inspector for IE?thanks
Dave -
RE: Puts inconsistency & machine epsilon management
Thanks all,
Thom, that link looks very useful thanks, makes me think I should dig out my A-level computer science notes too ...
Dan, I still get
> r1 = (20.0/1000)/0.8 0.025 > puts r1 0.025
How do you output the full precision in order to understand what is going on?
I don't have the Rational class in SU8 (I'm on OS X 10.6.8 so can't go any higher for the time being)
FYI;RUBY_VERSION
1.8.5
Do I need Ruby 2.0 for that?Dave
-
RE: Puts inconsistency & machine epsilon management
Hi,
I have come across a problem which seems to be related to this issue.> r1 = (20.0/1000)/0.8 0.025 > r1.class Float > "%.2f" % r1 0.02
=> INCORRECT
However;
> "%.2f" % (20.0/(0.8*1000)) 0.03
=> CORRECT
> r2 = 0.025 0.025 > r2.class Float > "%.2f" % r2 0.03
=> CORRECT
> "%.2f" % 0.025 0.03
=> CORRECT
Also:
> r1 <=> 0.025 -1
=> INCORRECT
> r2 <=> 0.025 0
=> CORRECT
> r1 <=> r2 -1
=> INCORRECT
So it is clearly something to do with how the number is stored in binary and the order of operators can affect the result as alluded to above in this thread.
Any ideas on how to manage this? - it seems quite a fundamental flaw if this comes up when making calculations at a pretty basic level of precision. It doesn't seem practical to re-order potential calculations to push the precision one way or another because the values of variables may not be known in advance. -
RE: A few newbie questions...
Do you know if this is still the case?
I'm trying to reload an rbs file to perform a live patch of some methods;Sketchup.load('file_path.rbs') returns 0 the first time, then false on subsequent calls, same as Sketchup::require
Is there a global equivalent to $" that SU stores the list of files in, that I can delete the file name from to force a reload?
thanks
SU 8.0 M2, Mac
-
RE: Organising namespaces and loading scripts on demand
Hi Thomthom, Dan
Many thanks for your replies, that seems to have cleared up the problem. (NB I've changed the subject slightly to be more useful to anyone searching the forum)@thomthom said:
You are loading scrambled files, correct?
Yes that is correct, I want to be able to load scrambled library files, hence the use of Sketchup::require().
@thomthom said:
There is a known issue where scrambled files are not evaluated into the top level namespace.
Place your require statements outside your modules - on the top level code and it will be ok.@dan rathbun said:
This is a bug with the
Sketchup
module's override of therequire
method, and as Thomas says, happens most often with rbs files.This does seem to be the key to the problem, and thanks for clarifying Dan (I have realised now that this issue only started to occur after I tested some scrambled scripts).
@thomthom said:
Note that if you are using the SketchupExtension class you probably need to use an unscrambled proxy .rb file to load the .rbs files.
Yes, I currently do so there was no problem there.After some more testing it seems that there is no problem with the libraries themselves being scrambled, but the script that loads those libraries must be unscrambled, then it works fine. So to load scrambled libraries from within a module, they must be loaded by a proxy script that itself is unscrambled.
I don't really want to useeval('Sketchup::require("my_library")',TOPLEVEL_BINDING)
unless I have to, but good to know that option exists too.So using my abstract example again, it works ok if it is structured like this:
"my_toolbars.rbs" (can be scrambled)
module My_library module Mod_A # various classes, method defs, statements etc cmd = ;;UI;;Command.new("Launch…") { … require("Load_libraries.rb") # load unscrambled proxy script } … end end
"Load_libraries.rb" (must be plain text Ruby)
Sketchup;;require("Library_1") Sketchup;;require("Library_2") Sketchup;;require("Library_3") Sketchup;;require("Library_4") Sketchup;;require("Library_5") Sketchup;;require("Library_n")
"Library_n.rbs" (can be scrambled)
module My_library module Mod_A # various classes, method defs, statements etc end module Mod_B # various classes, method defs, statements etc end … end