Accessing Groups

37 views
Skip to first unread message

Harald Torch

unread,
Mar 7, 2010, 4:13:27 PM3/7/10
to Google SketchUp Developers - SketchUp Ruby API
I used this: -

for n in 0..f do
if entities[n].name.to_s == "Block_0"
entities[n].visible = true
end
end

and it worked for a while. But now sketch-up doesn't like it
(the .name part specifically) and I don't know where I copied and
pasted it from. The entities I am accessing are all groups, how do I
iterate through them?

Dan Rathbun

unread,
Mar 7, 2010, 5:30:53 PM3/7/10
to Google SketchUp Developers - SketchUp Ruby API
On Mar 7, 4:13 pm, Harald Torch wrote:
> I used this: -
>
> for n in 0..f do
>       if entities[n].name.to_s == "Block_0"
>         entities[n].visible = true
>       end
>     end

(1) .name.to_s should not be necessary as .name returns string
(2) You must make a temporary array to iterate, when changing
entities, because Sketchup (C++) will optimize, collate, reshuffle
(etc.) the collection when changes are made; otherwise you will end up
iterating objects more than once, and missing others.
(3) If speed is not an issue, use built-in iterator methods (.each) to
avoid fencepost errors.

Try this:

def show_groups( gname=nil )
# empty string param shows unnamed Groups
# nil param (or no param) shows ALL Groups
ents = model.entities.to_a # make array
ents.each do |i|
if i.is_a?(Sketchup::Group)
if ( gname.nil? or i.name==gname )
i.visible=true
end
end # if
end # do
end # def

Dan Rathbun

unread,
Mar 7, 2010, 9:06:17 PM3/7/10
to Google SketchUp Developers - SketchUp Ruby API
UPDATE: Added parameter type ckecking


def show_groups( gname=nil )
case gname.class
when NilClass, String


# empty string param shows unnamed Groups
# nil param (or no param) shows ALL Groups
ents = model.entities.to_a # make array
ents.each do |i|
if i.is_a?(Sketchup::Group)
if ( gname.nil? or i.name==gname )
i.visible=true
end
end # if
end # do

else # param is wrong class
raise( TypeError, 'String name or nil value Expected!', caller )
end # case
end # def

# Note that "ents.each do |i|" coulde be replaced with:
i=0
for i in ents do
# possibly with faster performance on large models
.

Harald Torch

unread,
Mar 8, 2010, 3:51:05 PM3/8/10
to Google SketchUp Developers - SketchUp Ruby API
Dan,

Thanks for that, I haven't quite got it working yet but I think part
of my problem is, I've got different versions of the same script in my
plug-ins directory (named differently), each of which contains the
same (named) procedure and the interpreter seems to be running every
version of that procedure it finds. (I noticed that one of the groups
was becoming visible but with text above it - one of my previous tries
- which wasn't in the script I was running. And, this was in a
version of the script I had in plugins/other/ directory... so, are all
my .rb scripts really just one huge script?

Dan Rathbun

unread,
Mar 9, 2010, 1:21:38 AM3/9/10
to Google SketchUp Developers - SketchUp Ruby API
On Mar 8, 3:51 pm, Harald Torch wrote:

> Thanks for that, I haven't quite got it working yet but I think part
> of my problem is, I've got different versions of the same script in my
> plug-ins directory (named differently), each of which contains the
> same (named) procedure and the interpreter seems to be running every
> version of that procedure it finds.

LOADING: Of course it (the interpreter,) will. It will load ANY and
ALL scripts it's told to load. Sketchup tells ruby to load ALL scripts
in the Plugins folder and then ALL scripts in the Tools folder. (This
appears to be hard-coded in C or C++, and at present, is not
configurable, directly, by users. But IS controllable indirectly, if
you move scripts into subfolders, and put an Extension loader script
using SketchupExtension class into one of those two folders. THEN, you
can toggle, certain scripts/plugins through the "Preferences >
Extensions" dialog. See the script 'Tools/extension.rb' for the
SketchupExtension class. And also examine examples of extension
registration scripts: 'Plugins/examples.rb' and 'Plugins/
utilities.rb', too name a few. You can ignore the use of
LanguageHandler class if your only making English plugins.)

ORDER of LOAD: Scripts are 'told to load' via a require statement, in
each of the 'autoload' folders, in alphabetical filename order
(according to the ASCII character set.) '!' char before letters, '_'
char after letters.
[Win32 and OSX, are case-insensitive, but case-preserving Operating
Systems, so the underscore character should get collated after all
letters, even though the lowercase letters follow the '_' in the ASCII
set.]
The order of loading can be (and often is) modified by scripts
(internally) if they use a require statement. (Example: one of the
first few scripts to load will often have a "require 'sketchup'"
statement that will load the 'Tools/sketchup.rb' script out of order,
because it needs functionality from that script.) When it finally
comes time, and scripts are auto loading from the Tools folder, and
it's 'sketchup.rb's turn to be 'required' by the autoload feature,
the require method checks the global array $" and will find that the
script has already been loaded. It (require) then does NOT reload it,
and returns false, instead of true (as it does when it does load a
script.)

DEFINITION of OBJECTS: Everything in Ruby is an object (a subclass of
class Object.) This applies also to classes Class, Module and Method
(as well as base types you'd expect, such as Integer, Float, String,
etc.) However, the rules for defining Class, Module and Method in
script form differ.
(1) Class and Module Definitions can span multiple blocks and multiple
files. So when ever Ruby encounters a Class or Module definition block
(for an existing object,) it appends the new code to what it already
has defined. (Assume here for example that each new block encountered
has completely new code, new variables references, new constants, and
new methods. They are all just added into the Class or Module object.)
(2) Method Definitions CANNOT span multiple blocks (or files.) When
Ruby reads a method definition for a existing method, the method is
totally redefined. The old version is discarded. When we do this in a
subclass, we call it 'overriding' the inherited method. If you set the
global $VERBOSE=true you will see warnings (in the console,) whenever
a method gets redefined.
(3) Constants and Variables (References) that are defined in later
blocks, redefine those defined in earlier Class or Module blocks.
Whenever a Constant is redefined you will see a warning in the
console, even if $VERBOSE is set to the default medium mode (false.)
[BTW, $VERBOSE=nil is silent mode.]

> so, are all my .rb scripts really just one huge script?

They ARE... IF they are running in the same NAMESPACE. If you don't
wrap your scripts in modules with different names, then they are
running in the Objectspace, which is actually class Object.
You dont want to do this! Any methods defined outside a module block,
become methods of class Object, and get inherited by ALL objects as
private methods. This wastes memory. And besides many objects will
never use those methods, such as objects of Sketchup::DrawingElement
class and all it's subclasses (Face, Edge, etc.)

For now.. you can use namespace Torch just to play around. Make sub
namespaces (sub-modules) inside module Torch to separate your
different plugins/scripts. Any custom Class (or subclass) definitions
you create must be at least inside module Torch. (They can be inside a
submodule as well.)

Ex:

module Torch

module GroupTools
class GroupGrabber
<code>
end # class
def show_Groups( gname=nil )
<code>
end # method
def hide_Groups( gname=nil )
<code>
end # method
begin
<module setup code>
end # module GroupTools

module LineTools
class LineTwister
<code>
end # class
def find_Line( ver1, ver2 )
<code>
end # method
end # module LineTools

<...etc...>

end # module Torch

The above can be split up into any number of files you wish (as long
as methods don't cross files.)

Make a template in your editor that has your top-level namespace as an
empty module block for you to always add code into.

It's up to YOU to keep track of the child and grandchild namespaces,
since it's YOUR namespace, and not likely anyone else would intrude
into it.

This all keeps your code from corrupting other people's code, and
their code from corrupting yours; but more importantly, the Standard
Ruby namespaces (classes and modules, both Base and Extension.)

Dan Rathbun

unread,
Mar 9, 2010, 1:36:05 AM3/9/10
to Google SketchUp Developers - SketchUp Ruby API
Forgot to mention, when refering to objects in another scope use the
scope operator ::

module Some_Plugin_Namespace_Name

# create a new GroupGrabber class object:
gg = Torch::GroupTools::GroupGrabber.new('Group_0')

# use it
Torch::GroupTools::show_Groups( gg.members )

end # module

Harald Torch

unread,
Mar 9, 2010, 2:05:31 PM3/9/10
to Google SketchUp Developers - SketchUp Ruby API
Dan,

Thanks again. I'm not going to ask any more, I'm going to have a good
experiment. I have to say though that I find ruby script very
frustrating partly because there doesnt seem to be any decent
reference documentation but also because I like Sketchup so much, and
I'm allergic to Cad programmes in general. I think Google missed a
trick in not going for a more mainstream scripting language. But!
It's not going to stop me...

> end # moduleddrrrrrr

Dan Rathbun

unread,
Mar 9, 2010, 5:51:48 PM3/9/10
to Google SketchUp Developers - SketchUp Ruby API
Example of file spanning:

# --- begin file1.rb ---


module Torch
module GroupTools
class GroupGrabber
<code>
end # class

end # module GroupTools
end # module Torch
# --- endof file1.rb ---

# --- begin file2.rb ---
module Torch
module GroupTools


def show_Groups( gname=nil )
<code>
end # method
def hide_Groups( gname=nil )
<code>
end # method
begin
<module setup code>
end # module GroupTools

end # module Torch
# --- endof file2.rb ---

# --- begin file3.rb ---
module Torch


module LineTools
class LineTwister
<code>
end # class
def find_Line( ver1, ver2 )
<code>
end # method
end # module LineTools

end # module Torch
# --- endof file3.rb ---

Reply all
Reply to author
Forward
0 new messages