SketchUcation Premium Membership

 

 

Explode group, retrive all entities and recreate group

Explode group, retrive all entities and recreate group

Postby njeremy2 » Thu May 03, 2012 2:32 pm

Hello everyone, I need you :)

I have this code :


def DefToName
@tab = []
@tabgroup = []

#retrive all entities
Sketchup.active_model.entities.each do |entities|
# put all entities into TAB called @tab
@tab << entities

@tab.each do |element|
# If the entity is a group, explode the group
if element.is_a?(Sketchup::Group)
element.explode

# I need to retrives all entities from this group HERE,
# If I put this code : "Sketchup.active_model.entities.each do |entities|" it takes all entities, and I just need only entities from the group
# after explosion, I'll do actions on this entities (ComponentInstance or Group)
# After actions, I need to recreate the group with all the entities from this group.
# For recreate the group, I have to pick the name of group before explosion into @name for example,
# Then, when I need to recreate the group, I put that name into the new name of group


end #is_a?
end #tab.each
end #|entities|
end # end DefToName


Thank you :)
njeremy2
 
Posts: 58
Joined: Mon Apr 16, 2012 2:53 pm
Name: jeremy

Re: Explode group, retrive all entities and recreate group

Postby TIG » Thu May 03, 2012 2:44 pm

Use a lowercase letter for the start of a def method.

You method will not be robust.
If you get a list of the group's entities when you explode it, they might not all exist when you want to come to recreate it - coincident edges/faces can merge.

Why do you need to explode and remake each group in the model ?
Why not simply iterate the model.entities and for each group found you then do something to the group.entities, iterating that for other groups or whatever... no explode no remake needed :?
Code: Select all
Sketchup.active_model.entities.each{|g|
  next unless g.is_a?(Sketchup::Group)
  g.entities.each{|e|
    next unless e.is_a?(Sketchup::Group)
    puts e
    # or whatever you want to do with 'e'
  }
}
TIG
User avatar
TIG
Global Moderator
 
Posts: 13919
Joined: Mon Nov 12, 2007 7:24 pm
Location: Northumbria UK
Name: TIG
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: architecture
Level of SketchUp: Advanced

Re: Explode group, retrive all entities and recreate group

Postby njeremy2 » Thu May 03, 2012 2:58 pm

Hmmm,
It seems to be good, I will try to execute it

I have a group which contains components. And with this component, I need to copy definition name into name (the copy works thanks to you. Thank to you TIG!!).
So, to access to this component for doing modification, I tought I need to explode it.

You just tell me it's possible to make modification without exploding groups.

I will try this and I tell you if it's work or not. ;)
njeremy2
 
Posts: 58
Joined: Mon Apr 16, 2012 2:53 pm
Name: jeremy

Re: Explode group, retrive all entities and recreate group

Postby njeremy2 » Thu May 03, 2012 3:00 pm

How do you use "next unless" ?

I search it into "Automatic_SketchUp.pdf", I found nothing
njeremy2
 
Posts: 58
Joined: Mon Apr 16, 2012 2:53 pm
Name: jeremy

Re: Explode group, retrive all entities and recreate group

Postby kwalkerman » Thu May 03, 2012 3:07 pm

"next unless" is ruby code - no Sketchup needed. TIG's code basically says "unless g is a Sketchup::Group, move on to the next item in each. It is functionally the same as the following, but reads a little cleaner:

Code: Select all
Sketchup.active_model.entities.each{|g|
  if g.is_a? Sketchup::Group
    g.entities.each{|e|
      if g.is_a? Sketchup::Group
        puts e
        # or whatever you want to do with 'e'
      end
    }
  end
}
kwalkerman
 
Posts: 135
Joined: Mon Feb 08, 2010 9:48 pm
Name: Karen

Re: Explode group, retrive all entities and recreate group

Postby TIG » Thu May 03, 2012 3:30 pm

When you do a 'test' you can do it like this
if e.is_a?(Sketchup::Group)
### do stuff
end#if

if you want to negate the match use
if not e.is_a?(Sketchup::Group)
### do stuff
end#if

or
if ! e.is_a?(Sketchup::Group)
### do stuff
end#if

there is the opposite of 'if' which is 'unless', so
unless e.is_a?(Sketchup::Group)
### do stuff
end#unless

where 'unless...' is the same as 'if not...'

Now when you make a if...end or unless...end block and you nest other blocks of code within those it's easy to loose track of which 'end' ends what!
I prefer to use a one line test to skip or jump out of a block.
es.each{|e|
next unless e.is_a?(Sketchup::Group)
### not a group so skip to the next item
### OR we do stuff to e because it IS a group!
###
}

the next unless e.is_a?(Sketchup::Group) is the same as next if not e.is_a?(Sketchup::Group)
You don't need an 'end' to a single line test where it follows the action.
The 'next' simply skips to the next item in the array/list.
Using 'break' stops the iteration - useful if you are testing for ONE thing and you have found it... like
g=nil
es.each{|e|
if e.is_a?(Sketchup::Group) and e.name=="FOO"
g=e
break
end#if
}
puts g if g

which sets 'g' to nil, but then makes it a reference to ONE group named 'FOO' if it's found in the tested list, if found it breaks out of the {} and 'puts' it... Note how the 'g' is defined outside of the block {} so you can use it later, references initiated inside a {} are not visible to later processes.

One tip more... you can iterate an 'entities' collection just as it it were an array, BUT if you intend to do anything to the items in the collection, like erase some, then you must convert it into a snapshot array as you start because otherwise your changes will change the entities collection as you iterate through it and give unexpected results...
So use
group.entities.to_a.each{|e|
e.erase! unless e.is_a?(Sketchup::Edge)
}

to erase everything in a group that is not an Edge - i.e. all faces and groups etc.
group.entities.each{|e|
e.erase! unless e.is_a?(Sketchup::Edge)
}

will fail to erase everything as the list will change dynamically as you change it, and so some might get missed.
TIG
User avatar
TIG
Global Moderator
 
Posts: 13919
Joined: Mon Nov 12, 2007 7:24 pm
Location: Northumbria UK
Name: TIG
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: architecture
Level of SketchUp: Advanced

Re: Explode group, retrive all entities and recreate group

Postby njeremy2 » Thu May 03, 2012 3:33 pm

Hmmm, I will meditate on this.
It's a new notion for me, let me a little time to understand it

now, I try the code



[edit]
WOOOOOW TIG !

I don't have time enough to read all answer and you wrote that !! :shock:
njeremy2
 
Posts: 58
Joined: Mon Apr 16, 2012 2:53 pm
Name: jeremy

Re: Explode group, retrive all entities and recreate group

Postby njeremy2 » Thu May 03, 2012 3:45 pm

lol !
wowowowo!
I have 2 bigs difficulties :
The first one is to understand correctly the English :) (I can manage that)
The second one is to understand Ruby and SketchUp language subtleties ---> AAAHHHH :puke:

Thanks
njeremy2
 
Posts: 58
Joined: Mon Apr 16, 2012 2:53 pm
Name: jeremy

Re: Explode group, retrive all entities and recreate group

Postby njeremy2 » Thu May 03, 2012 4:09 pm

I try this code


Maybe I don't know how to use that...


What I need to do is to retrive all entities, then I select what I need to do if it's a group or if it's a component.

If it's a component, I copy the DefinitionName into Name.
If it's a group, I need to copy DefinitionName into Name for all components into the group

The problem : I don't know how get into the group then copy the definition without exploding this

code for copying definition into name
Code: Select all
if   element.definition.name[0] != 0 && element.name == ""
element.name = "#{element.definition.name}"
end # end if
njeremy2
 
Posts: 58
Joined: Mon Apr 16, 2012 2:53 pm
Name: jeremy

Re: Explode group, retrive all entities and recreate group

Postby TIG » Thu May 03, 2012 8:40 pm

You seem to be making this too complex...
Your last piece of code seems to make no sense :?

Every definition has a unique name that is a 'string'.

Please try and explain [simply] what you want to do - in words, not code...
It IS straightforward to find definition/instance names, BUT what do you want and what will you ultimately do with them ???
TIG
User avatar
TIG
Global Moderator
 
Posts: 13919
Joined: Mon Nov 12, 2007 7:24 pm
Location: Northumbria UK
Name: TIG
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: architecture
Level of SketchUp: Advanced

Re: Explode group, retrive all entities and recreate group

Postby njeremy2 » Thu May 03, 2012 9:52 pm

I'm a student in computer science into a small business. My boss use Sketchup Pro and he asks me do make a plugin which count all entities in a design.

It tells you how many components and groups are they in the design.
We have already use that plugin but there are some bugs.
If we don't put a name into the component, the plugin display nothing (that's why I ask you how to copy definition name into name).
The other problem is : when you have a group, into that group you can have some components and the plugin didn't count these components, that's why I ask how to get into a group without exploding this.


Voila :)
njeremy2
 
Posts: 58
Joined: Mon Apr 16, 2012 2:53 pm
Name: jeremy

Re: Explode group, retrive all entities and recreate group

Postby TIG » Thu May 03, 2012 10:50 pm

OK !
Let's start at the other end... :roll:
Rather than try and mine into the model, shortcut it by examining definitions...
    A model has definitions.
    These refer to components, groups and images.
    Definitions have instances methods, so you can count how many there are etc.
This example code iterates through all of the model's definitions, list their type, name, instances [with name and parent] etc...
Code: Select all
model=Sketchup.active_model
collection=[]
model.definitions.each{|defn|
  details=[]
  if defn.image?
    details << "IMAGE"
  elsif defn.group?
    details << "GROUP"
  else #component
    details << "COMPO"
  end
  if defn.image?
    details << defn.path #images have no name
  else
    details << defn.name
  end
  insts=[]
  defn.instances.each{|ins|
    inst=[]
    if defn.image?
      inst << '' #image instances have no name
    else
      inst << ins.name
    end
    par=ins.parent
    if par==model
      inst << "MODEL"
    else
      inst << par.name
    end
    insts << inst
  }
  details << insts
  collection << details
}
collection.sort!
puts collection
OR write [puts] 'collection' into a file etc...
The format is
COMPO, Compo#1, , Group#1
COMPO, Compo#1, Cxxxxxx, MODEL
GROUP, Group#1, MyGroup, MODEL
GROUP, Group#2, , Compo#1
IMAGE, C:/Temp/My.png, , MODEL

etc
the empty fields ', ,' is where an instance or group has no name assigned.
TIG
User avatar
TIG
Global Moderator
 
Posts: 13919
Joined: Mon Nov 12, 2007 7:24 pm
Location: Northumbria UK
Name: TIG
Operating system: Windows
SketchUp version: 8
License type: Pro
SketchUp use: architecture
Level of SketchUp: Advanced

Re: Explode group, retrive all entities and recreate group

Postby Dan Rathbun » Thu May 03, 2012 11:21 pm

    Does your boss ever use the
    Model Info > Statistics panel ??



    ModelInfo_Statistics.png
    Please, register (free) to access all the attachments on the forums.
    User avatar
    Dan Rathbun
    Top SketchUcator
     
    Posts: 4069
    Joined: Tue Oct 06, 2009 3:06 am
    Location: Florida, USA
    Name: Dan Rathbun
    Operating system: Windows
    SketchUp version: 8
    License type: Pro
    SketchUp use: education
    Level of SketchUp: Advanced

    Re: Explode group, retrive all entities and recreate group

    Postby njeremy2 » Fri May 04, 2012 8:02 am

    Dan Rathbun wrote:
      Does your boss ever use the
      Model Info > Statistics panel ??



      ModelInfo_Statistics.png


      Yes he knows this tool, but it don't give you the texture (in m²) and of the components neither groups :(

      thanks to all everybody !!! I think I found the solution. :thumb:


      When I need to found each entities in a group I use that :

      Code: Select all
      if g.is_a?(Sketchup::Group)             
         g.entities.each do |element|
            if element.definition.name[0] != 0 && element.name == ""
            element.name = "#{element.definition.name}"
            end # end if
         end #|element|


      With that, I can change the name of component inside a group

      The first code of TIG gave me an idea, I combine my code with a piece of code from him and it worked ! (it was only a sample of code used to test for me)
      Now I have to copy that piece of code in the big one ! :)

      Before :


      After launching the plugin :
      njeremy2
       
      Posts: 58
      Joined: Mon Apr 16, 2012 2:53 pm
      Name: jeremy

      SketchUcation One-Liner Adverts

      by Ad Machine » 5 minutes ago

      Not a Premium Member yet? Check out the great time-limited deal we are offering.

      Ad Machine
      Robot
       
      Posts: 2012


      Return to Developers' Forum

      Who is online

      Users browsing this forum: jeffgo, mgl567 and 3 guests