Delete a list of components by their definitions.

Delete a list of components by their definitions.

Postby TNTDAVID » Sat Jul 01, 2017 6:20 pm

Hello, :enlight:

I want to delete a list of components with their definitions and then purge their textures.

Description of the step-by-step method:

1 - All components that are named ['BOXE', 'CUBE'] in their definitions are deleted and purged without affecting the unused components.

2 - All textures used by the components in the list must be purged without affecting the other materials.

Note

The goal is to find an alternative to purge_unused.

The method must remove the components even if they are used in SketchUp and nested within groups.

Any help in writing this method will be of great help to me.

Thank you

David
0
* Nouveau !!!
Découvrez notre nouveau Plugin Click-Window 3D, pour créer vos Fenêtres 3D !
User avatar
TNTDAVID 
PluginStore Author
PluginStore Author
 

Re: Delete a list of components by their definitions.

Postby TIG » Sat Jul 01, 2017 6:50 pm

Construct a 'match' regexp to suit - e.g. match=/BOX/
It's been explained before how to limit that to matches starting with BOX etc /^BOX/ and trap for upper/lowercase characters...

Assemble an array of definitions, using that 'match' filter [untested!].
Code: Select all
model=Sketchup.active_model
# collect matching definitions
defstogo=model.definitions.find_all{|d| d.name =~ match }
# collect materials.
matstogo=[]
defstogo.each{|d|
  # first used by instances
  d.instances.each{|i|
    matstogo << i.material unless matstogo.include?(i.material)
  }
  # now used by its entities
  d.entities.each{|e|
    matstogo << e.material unless matstogo.include?(e.material)
    ( matstogo << e.back_material unless matstogo.include?(e.material) ) if e.is_a?(Sketchup::Face)
  }
}
matstogo.compact!
matstogo.uniq!
# now check if materials used elsewhere
defsNOTtogo=model.definitions.find_all{|d| ! d.name =~ match }
# collect materials.
matsNOYtogo=[]
defsNOTtogo.each{|d|
  # first used by instances
  d.instances.each{|i|
    matsNOTtogo << i.material unless matsNOTtogo.include?(i.material)
  }
  # now used by its entities
  d.entities.each{|e|
    matsNOTtogo << e.material unless matsNOTtogo.include?(e.material)
    ( matsNOTtogo << e.back_material unless matsNOTtogo.include?(e.material) ) if e.is_a?(Sketchup::Face)
  }
}
matsNOTtogo.compact!
matsNOTtogo.uniq!
# now reduce matstogo as necessary...
matstogo.clone.each{|e|
  matstogo.delete(e) if matsNOTtogo.include?(e)
}
# start and operation ro ensure Garbage Collection works...
model.start_operation('Purger', true)
# now delete the selected entities
defstogo.each{|d| d.entities.clear! }
# now delete the unneeded materials
matstogo.each{|m| model.materials.remove(m) }
# commit
model.commit_operation

This will work in versions >= 8...
0
TIG
User avatar
TIG 
Global Moderator
 

Re: Delete a list of components by their definitions.

Postby TNTDAVID » Sat Jul 01, 2017 7:55 pm

Hello TIG,

Thank you for your very complete and precise example.

I made a simple test on a component with the definition "BOX" which has a texture called "RED".

The ruby dialog box returns "True", but does not delete the cube or the texture.



Here is the code I copied and pasted into the dialog box:

Code: Select all
  match = ['BOX']
  model=Sketchup.active_model
  defstogo=model.definitions.find_all{|d| d.name =~ match }
  matstogo=['RED']
  defstogo.each{|d| 
  d.instances.each{|i|
  matstogo << i.material unless matstogo.include?(i.material)
  }
  d.entities.each{|e|
  matstogo << e.material unless matstogo.include?(e.material)
( matstogo << e.back_material unless matstogo.include?(e.material) ) if e.is_a?(Sketchup::Face)
  }
}
  matstogo.compact!
  matstogo.uniq!

  defsnottogo=model.definitions.find_all{|d| ! d.name =~ /#{match}/ }
  matsnottogo=['RED']
  defsnottogo.each{|d|
  d.instances.each{|i|
  matsnottogo << i.material unless matsnottogo.include?(i.material)
  }
  d.entities.each{|e|
  matsnottogo << e.material unless matsnottogo.include?(e.material)
( matsnottogo << e.back_material unless matsnottogo.include?(e.material) ) if e.is_a?(Sketchup::Face)
}
}
  matsnottogo.compact!
  matsnottogo.uniq!
  matstogo.clone.each{|e|
  matstogo.delete(e) if matsnottogo.include?(e)
}
  model.start_operation('Purger', true)
  defstogo.each{|d| d.entities.clear! }
  matstogo.each{|m| model.materials.remove(m) }
  model.commit_operation


Or is my mistake?

Thank you in advance for your help.

David
0
* Nouveau !!!
Découvrez notre nouveau Plugin Click-Window 3D, pour créer vos Fenêtres 3D !
User avatar
TNTDAVID 
PluginStore Author
PluginStore Author
 

Re: Delete a list of components by their definitions.

Postby TIG » Sat Jul 01, 2017 8:34 pm

When I wrote match=/BOX/
That is a regular expression.

You wrote match=['BOX']
That's an array containing a string...

They are not the same thing !!

So you need to try with a better set of variables !

When I set a variable like matstogo=[] it's making an empty array to which we add elements...

What made you think you need to diverge from my guidance ??
0
TIG
User avatar
TIG 
Global Moderator
 

Re: Delete a list of components by their definitions.

Postby TNTDAVID » Sun Jul 02, 2017 1:04 pm

TNTDAVID wrote:What made you think you need to diverge from my guidance ?


I used a array to "match" because there will be several different definitions to delete.

As in your code you use:

defstogo.each {| d |

It seemed to me that "each" was used to browse a array.

Your code works perfectly for a single definition, what if we have "CUBE", "TOTO" and "LOLA" to delete?

-

For matstogo I did not know that it was possible to collect materials of a definition without naming them. I'm still surprised by the Ruby.

Thank you for your help.

David
0
* Nouveau !!!
Découvrez notre nouveau Plugin Click-Window 3D, pour créer vos Fenêtres 3D !
User avatar
TNTDAVID 
PluginStore Author
PluginStore Author
 

Re: Delete a list of components by their definitions.

Postby Dan Rathbun » Sun Jul 02, 2017 3:24 pm

TNTDAVID wrote:
TIG wrote:What made you think you need to diverge from my guidance ?

I used a array to "match" because there will be several different definitions to delete.

TIG is showing you how to purge ONE definition and it's materials.

TNTDAVID wrote:Your code works perfectly for a single definition, ...

No it does not. because you made 3 edits that make it NOT work properly.

CORRECTION: Actually I found 4 errors that made it not delete all the components or materials.
The second use of the Regexp was ! d.name =~ /#{name}/ (the regexp var is match.)
matsNOTtogo=[] was defined as matsNOYtogo=[], resulting in NameError
The comparison of back_material was conditional upon inclusion of front material in two statements.

TNTDAVID wrote:... what if we have "CUBE", "TOTO" and "LOLA" to delete?

First, learn how and why TIG's code works for ONE definition, then learn how to modify it for multiple definitions.

Then either you wrap what TIG showed you into a method, and call it 3 times from a loop:
Code: Select all
for cname in ['CUBE','TOTO','LOLA'] # WHOOPS this not needed --> do |cname|
  purge_comp(cname)
end


... or you build a multi-match regular expression (Regexp):
cnames = ['CUBE','TOTO','LOLA']
match = /#{cnames.join('|')}/


Test file (SU2016):
CubeLolaToto.skp

"Color B04" and "Color J08" are unused.
"Color K03", "Color M06" are used by primitive faces.
"Material 2" is the leader color.

So here is a method with extra quirks:
* Returns false if array of cnames is empty.
* Short circuits and returns 0 if no definitions are found to delete.
* Reports both to console and message box number of definitions and materials purged.
* Returns number of definitions deleted.

Code: Select all
# To test:
# purge_comps('CUBE','TOTO','LOLA')
# ... or:
# del = ['CUBE','TOTO','LOLA']
# purge_comps(del)

def purge_comps(*cnames)
  #
  return false if cnames.empty?
  cnames.flatten!
  #
  match = /#{cnames.join('|')}/
  #
  model=Sketchup.active_model
  # collect matching definitions
  defstogo=model.definitions.find_all{|d| d.name =~ match }
  return 0 if defstogo.empty?
  # collect materials.
  matstogo=[]
  defstogo.each{|d|
    # first used by instances
    d.instances.each{|i|
      matstogo << i.material unless matstogo.include?(i.material)
    }
    # now used by its entities
    d.entities.each{|e|
      matstogo << e.material unless matstogo.include?(e.material)
      ( matstogo << e.back_material unless matstogo.include?(e.back_material) ) if e.is_a?(Sketchup::Face)
    }
  }
  matstogo.compact!
  matstogo.uniq!
  # now check if materials used elsewhere
  defsNOTtogo=model.definitions.find_all{|d| ! d.name =~ match }
  # collect materials.
  matsNOTtogo=[]
  defsNOTtogo.each{|d|
    # first used by instances
    d.instances.each{|i|
      matsNOTtogo << i.material unless matsNOTtogo.include?(i.material)
    }
    # now used by its entities
    d.entities.each{|e|
      matsNOTtogo << e.material unless matsNOTtogo.include?(e.material)
      ( matsNOTtogo << e.back_material unless matsNOTtogo.include?(e.back_material) ) if e.is_a?(Sketchup::Face)
    }
  }
  matsNOTtogo.compact!
  matsNOTtogo.uniq!
  # now reduce matstogo as necessary...
  matstogo.clone.each{|e|
    matstogo.delete(e) if matsNOTtogo.include?(e)
  }
  #
  defsgone = defstogo.size
  matsgone = matstogo.size
  # start and operation to ensure Garbage Collection works...
  model.start_operation('Purger', true)
  # now delete the selected entities
  defstogo.each{|d| d.entities.clear! }
  # now delete the unneeded materials
  matstogo.each{|m| model.materials.remove(m) }
  # clear the arrays of references to deleted objects:
  matstogo.clear
  defstogo.clear
  # commit
  model.commit_operation
  msg = "#{defsgone} definitions purged\n#{matsgone} materials purged"
  puts msg
  UI.messagebox(msg,MB_OK)
  return defsgone
end


If you absolutely must, you can call GC.start to ensure Ruby garbage collection runs.
0
Last edited by Dan Rathbun on Mon Jul 03, 2017 9:12 am, edited 2 times in total.
    I'm not here much anymore. But a PM will fire email notifications.
    User avatar
    Dan Rathbun 
    PluginStore Author
    PluginStore Author
     

    Re: Delete a list of components by their definitions.

    Postby TNTDAVID » Sun Jul 02, 2017 5:30 pm

    Hello Dan Rathbun and thank you for your help.

    Dan Rathbun wrote:Then either you wrap what TIG showed you into a method, and call it 3 times from a loop:


    How to write the loop?

    I have done several tests and I still get this error message:

    Code: Select all
    Error: # <SyntaxError: <main>: syntax error, unexpected '|'
    For cname in ['CUBE', 'TOTO', 'LOLA'] do | cname |

                                             ^>


    Then I tried your method by adding:

    Cnames = ['CUBE', 'TOTO', 'LOLA']

    The ruby console returns:

    Code: Select all
    purge_comps


    But nothing changes in SketchUp. :shock:

    I have to move on from something obvious that I can not understand.

    Thank you in advance for your help.
    0
    * Nouveau !!!
    Découvrez notre nouveau Plugin Click-Window 3D, pour créer vos Fenêtres 3D !
    User avatar
    TNTDAVID 
    PluginStore Author
    PluginStore Author
     

    Re: Delete a list of components by their definitions.

    Postby sdmitch » Sun Jul 02, 2017 6:53 pm

    Dan Rathbun wrote:Then either you wrap what TIG showed you into a method, and call it 3 times from a loop:

    Code: Select all
    Error: # <SyntaxError: <main>: syntax error, unexpected '|'
    For cname in ['CUBE', 'TOTO', 'LOLA'] do | cname |

                                             ^>
    You are trying to define the variable "cname" twice in the same statement. delete the do | cname |

    As usual Dan is right. You just need to wrap TIG's code with
    Code: Select all
    ["cube","toto","lola"].each{|name|
      match = /#{name}/i
    .
    .
    .
    }
    0
    Nothing is worthless, it can always be used as a bad example.

    http://sdmitch.blogspot.com/
    User avatar
    sdmitch 
    PluginStore Author
    PluginStore Author
     

    Re: Delete a list of components by their definitions.

    Postby Dan Rathbun » Mon Jul 03, 2017 9:04 am

    sdmitch wrote:You are trying to define the variable "cname" twice in the same statement. delete the do | cname |

    MY BAD! I had a bad example (above.) [ Commented out that " do | cname |" part ]

    sdmitch wrote:As usual Dan is right. You just need to wrap TIG's code with
    Code: Select all
    ["cube","toto","lola"].each{|name|
      match = /#{name}/i
    .
    .
    .
    }

    That will actually create a separate undo operation for each entity (and it's materials) and will be much slower.

    TNTDAVID wrote:I have to move on from something obvious that I can not understand.

    I gave you a complete working method at the bottom of that previous post !!!!!!


    https://forums.sketchup.com/t/ruby-lear ... ists/22861
    Get the old "Pick Axe" book and read it.

    :ugeek:
    0
      I'm not here much anymore. But a PM will fire email notifications.
      User avatar
      Dan Rathbun 
      PluginStore Author
      PluginStore Author
       

      Re: Delete a list of components by their definitions.

      Postby TNTDAVID » Mon Jul 03, 2017 1:53 pm

      sdmitch wrote:You just need to wrap TIG's code with
      CODE: SELECT ALL
      ["cube","toto","lola"].each{|name|
        match = /#{name}/i
      .
      .
      .
      }


      Great thanks sdmitch,

      You allowed me to understand what Dan Rathbun was explaining to me.

      -

      Dan Rathbun wrote:https://forums.sketchup.com/t/ruby-lear ... ists/22861
      Get the old "Pick Axe" book and read it.


      Thanks for the Dan link, I will follow your advice.

      -

      Here is the TIG method, which works for several definitions:



      Code: Select all
        ["cube","toto","lola"].each{|name|
        match = /#{name}/i
        model=Sketchup.active_model
        defstogo=model.definitions.find_all{|d| d.name =~ match }
        matstogo=[]
        defstogo.each{|d| 
        d.instances.each{|i|
        matstogo << i.material unless matstogo.include?(i.material)
        }
        d.entities.each{|e|
        matstogo << e.material unless matstogo.include?(e.material)
      ( matstogo << e.back_material unless matstogo.include?(e.material) ) if e.is_a?(Sketchup::Face)
      }
      }
        matstogo.compact!
        matstogo.uniq!

        defsnottogo=model.definitions.find_all{|d| ! d.name =~ /#{match}/ }
        matsnottogo=[]
        defsnottogo.each{|d|
        d.instances.each{|i|
        matsnottogo << i.material unless matsnottogo.include?(i.material)
        }
        d.entities.each{|e|
        matsnottogo << e.material unless matsnottogo.include?(e.material)
      ( matsnottogo << e.back_material unless matsnottogo.include?(e.material) ) if e.is_a?(Sketchup::Face)
      }
      }
        matsnottogo.compact!
        matsnottogo.uniq!
        matstogo.clone.each{|e|
        matstogo.delete(e) if matsnottogo.include?(e)
      }
        model.start_operation('Purger', true)
        defstogo.each{|d| d.entities.clear! }
        matstogo.each{|m| model.materials.remove(m) }
        model.commit_operation
      }


      With your help I reach my goals and I discover more and more the Ruby. ;)

      Thank you all for your help.
      0
      * Nouveau !!!
      Découvrez notre nouveau Plugin Click-Window 3D, pour créer vos Fenêtres 3D !
      User avatar
      TNTDAVID 
      PluginStore Author
      PluginStore Author
       

      Re: Delete a list of components by their definitions.

      Postby Dan Rathbun » Mon Jul 03, 2017 6:57 pm

      TNTDAVID wrote:
      Here is the TIG method, which works for several definitions:

      Your implementation still has a few errors.

      David, I say again, that I gave you the code for a complete corrected method above.
      It defines a method name purge_comps(*cnames)
      0
        I'm not here much anymore. But a PM will fire email notifications.
        User avatar
        Dan Rathbun 
        PluginStore Author
        PluginStore Author
         

        Re: Delete a list of components by their definitions.

        Postby TNTDAVID » Mon Jul 03, 2017 10:53 pm

        Sorry Dan, but I can not seem to make your method work.

        In your method, how to integrate "CUBE", "TOTO" and "LOLA"?

        Thank you in advance for your help.

        David
        0
        * Nouveau !!!
        Découvrez notre nouveau Plugin Click-Window 3D, pour créer vos Fenêtres 3D !
        User avatar
        TNTDAVID 
        PluginStore Author
        PluginStore Author
         

        Re: Delete a list of components by their definitions.

        Postby TNTDAVID » Tue Jul 04, 2017 3:32 am

        Sorry Dan, I had not paid attention to your instructions in the code:

        Dan Rathbun wrote:# To test:
        # purge_comps('CUBE','TOTO','LOLA')
        # ... or:
        # del = ['CUBE','TOTO','LOLA']
        # purge_comps(del)


        Your method works very well and offers new benefits. :thumb:

        I noticed a small problem:

        How to avoid deleting the texture of 'CUBE', if it is used elsewhere in SketchUp?

        Thanks in advance for your help.
        0
        * Nouveau !!!
        Découvrez notre nouveau Plugin Click-Window 3D, pour créer vos Fenêtres 3D !
        User avatar
        TNTDAVID 
        PluginStore Author
        PluginStore Author
         

        Re: Delete a list of components by their definitions.

        Postby Dan Rathbun » Tue Jul 04, 2017 11:38 am

        TNTDAVID wrote:Your method works very well and offers new benefits.

        It is TIG's method with a few extra "bells and whistles".

        TNTDAVID wrote:I noticed a small problem:
        How to avoid deleting the texture of 'CUBE', if it is used elsewhere in SketchUp?

        I'll look at it today a bit and see if there is an issue.

        EDIT: Okay, YES I see the issue. The method does not check the model level entities collection for used materials (on primitive entity objects.)
        0
          I'm not here much anymore. But a PM will fire email notifications.
          User avatar
          Dan Rathbun 
          PluginStore Author
          PluginStore Author
           

          Re: Delete a list of components by their definitions.

          Postby Dan Rathbun » Tue Jul 04, 2017 12:00 pm

          Code: Select all
          # To test:
          # purge_comps('CUBE','TOTO','LOLA')
          # ... or:
          # del = ['CUBE','TOTO','LOLA']
          # purge_comps(del)
          #
          # ver: 2.0

          def purge_comps(*cnames)
            #
            return false if cnames.empty?
            cnames.flatten!
            #
            match = /#{cnames.join('|')}/
            #
            model=Sketchup.active_model
            # collect matching definitions
            defstogo=model.definitions.find_all{|d| d.name =~ match }
            return 0 if defstogo.empty?
            # collect materials.
            matstogo=[]
            defstogo.each{|d|
              # first used by instances
              d.instances.each{|i|
                matstogo << i.material unless matstogo.include?(i.material)
              }
              # now used by its entities
              d.entities.each{|e|
                matstogo << e.material unless matstogo.include?(e.material)
                ( matstogo << e.back_material unless matstogo.include?(e.back_material) ) if e.is_a?(Sketchup::Face)
              }
            }
            matstogo.compact!
            matstogo.uniq!
            # now check if materials used elsewhere
            defsNOTtogo=model.definitions.find_all{|d| ! d.name =~ match }
            # collect materials.
            matsNOTtogo=[]
            defsNOTtogo.each{|d|
              # first used by instances
              d.instances.each{|i|
                matsNOTtogo << i.material unless matsNOTtogo.include?(i.material)
              }
              # now used by its entities
              d.entities.each{|e|
                matsNOTtogo << e.material unless matsNOTtogo.include?(e.material)
                ( matsNOTtogo << e.back_material unless matsNOTtogo.include?(e.back_material) ) if e.is_a?(Sketchup::Face)
              }
            }
            # now used by model entities
            model.entities.each{|e|
              matsNOTtogo << e.material unless matsNOTtogo.include?(e.material)
              ( matsNOTtogo << e.back_material unless matsNOTtogo.include?(e.back_material) ) if e.is_a?(Sketchup::Face)
            }
            matsNOTtogo.compact!
            matsNOTtogo.uniq!
            # now reduce matstogo as necessary...
            matstogo.clone.each{|e|
              matstogo.delete(e) if matsNOTtogo.include?(e)
            }
            #
            defsgone = defstogo.size
            matsgone = matstogo.size
            # start and operation to ensure Garbage Collection works...
            model.start_operation('Purger', true)
            # now delete the selected entities
            defstogo.each{|d| d.entities.clear! }
            # now delete the unneeded materials
            matstogo.each{|m| model.materials.remove(m) }
            # clear the arrays of references to deleted objects:
            matstogo.clear
            defstogo.clear
            # commit
            model.commit_operation
            msg = "#{defsgone} definitions purged\n#{matsgone} materials purged"
            puts msg
            UI.messagebox(msg,MB_OK)
            return defsgone
          end
          0
            I'm not here much anymore. But a PM will fire email notifications.
            User avatar
            Dan Rathbun 
            PluginStore Author
            PluginStore Author
             

            Re: Delete a list of components by their definitions.

            Postby TNTDAVID » Tue Jul 04, 2017 2:49 pm

            Thanks for your reactivity Dan.

            Your solution works in the most by cases, but not all the time.

            The texture applied to TOTO should not be removed because it is used by the 4 Rectangle to Left:



            This mistake this product on my Click-Cuisine 2 furniture, and therefore makes the method unusable.

            Here's the SKP file:

            CubeLolaToto2.skp


            If you test your code on other examples the problem will not exist! :o

            For this reason the problem is strange and requires an investigation.

            Thank you in advance for your help.

            David
            0
            * Nouveau !!!
            Découvrez notre nouveau Plugin Click-Window 3D, pour créer vos Fenêtres 3D !
            User avatar
            TNTDAVID 
            PluginStore Author
            PluginStore Author
             

            Re: Delete a list of components by their definitions.

            Postby Dan Rathbun » Tue Jul 04, 2017 6:27 pm

            TNTDAVID wrote:For this reason the problem is strange and requires an investigation.

            I agree. Sounds like a good learning experience for you.
            I'll let you do the investigation, and fix it.

            TNTDAVID wrote:Thank you in advance for your help.

            I've given you enough help for now.

            Your turn to do some of the work. ;)
            0
              I'm not here much anymore. But a PM will fire email notifications.
              User avatar
              Dan Rathbun 
              PluginStore Author
              PluginStore Author
               

              Re: Delete a list of components by their definitions.

              Postby driven » Thu Jul 06, 2017 3:21 pm

              another way is to Hash the materials and set values for each...

              Code: Select all
                def purge_comps_n_mats(*args)
                model  = Sketchup.active_model
                defs   = model.definitions
                sel    = model.selection
                view   = model.active_view
                ents   = model.active_entities
                mats   = model.materials
                # add a hasj for materials and entities
                mats_h = Hash[mats.zip([1] * mats.size)]

                # this means you don't have to get Regexp right yourself
                names = Regexp.union(args)
                # this is similar to defs.to_a.dup.flatten
                list = defs.find_all { |d| d }
                # we will still only use one operation as v17 will error
                model.start_operation('mats')


                list.each do |defn|
                  defn.instances.each do |i|

                     ######################
                     # optional 'showtime' for testing
                 sel.add(i)
                 view.refresh
                 sleep 0.2
                 ######################

                    dents = defn.entities
                    if defn.name =~ names
                      # get rid of the comps checking their materials
                       mats_h[defn.material] = 3 unless defn.material.nil?
                       mats_h[i.material] = 3 unless i.material.nil?
                       dents.to_a.each do |item|
                        mats_h[item.material] = 3 if item.respond_to? :material
                        mats_h[item.back_material] = 3 if item.respond_to? :back_material
                      end
                 # delete the instance
                 ents.erase_entities(i)
                    else
                      mats_h[defn.material] = 2 unless defn.material.nil?
                      mats_h[i.material] = 2 unless i.material.nil?
                      dents.to_a.each do |item|
                        mats_h[item.material] = 2 if item.respond_to? :material
                        mats_h[item.back_material] = 2 if item.respond_to? :back_material
                      end
                    end
                  end
                end

                ents.to_a.each do |item|

                    ######################
                    # optional 'showtime' for testing
                    sel.add(item)
                    view.refresh
                    sleep 0.2
                    ######################

                  mats_h[item.material] = 2 if item.respond_to? :material
                  mats_h[item.back_material] = 2 if item.respond_to? :back_material
                end

                 mats_h.each { |k, v| mats.remove(k) unless k.nil? || v != 3 }

                model.commit_operation #
              end

              purge_comps_n_mats('CUBE', 'TOTO', 'LOLA')


              john
              0
              Last edited by driven on Sat Jul 08, 2017 1:59 am, edited 1 time in total.
              learn from the mistakes of others, you may not live long enough to make them all yourself...

              driven 
              PluginStore Author
              PluginStore Author
               

              Re: Delete a list of components by their definitions.

              Postby TNTDAVID » Fri Jul 07, 2017 3:12 pm

              Hello,

              You are right Dan, for the moment I still have not found a solution.

              I'm stubborn and I'd end up finding it!

              Thanks for your example Dirven :enlight:

              I have tested your code and the components are all removed from the SketchUp scene but nothing is purged.

              Is this normal?

              Edite:

              The Ruby console returns this message when I trigger your method.

              Code: Select all
              Error: #<NameError: undefined local variable or method `i' for Teste:Module>
              C:/Users/David/AppData/Roaming/SketchUp/SketchUp 2017/SketchUp/Plugins/TNT_Teste/logic.rb:60:in `block in purge_comps_n_mats'
              C:/Users/David/AppData/Roaming/SketchUp/SketchUp 2017/SketchUp/Plugins/TNT_Teste/logic.rb:56:in `each'
              C:/Users/David/AppData/Roaming/SketchUp/SketchUp 2017/SketchUp/Plugins/TNT_Teste/logic.rb:56:in `purge_comps_n_mats'
              C:/Users/David/AppData/Roaming/SketchUp/SketchUp 2017/SketchUp/Plugins/TNT_Teste/logic.rb:75:in `purge_comps'
              C:/Users/David/AppData/Roaming/SketchUp/SketchUp 2017/SketchUp/Plugins/TNT_Teste/logic.rb:85:in `block in singleton class'
              SketchUp:1:in `call'


              Thank you
              0
              * Nouveau !!!
              Découvrez notre nouveau Plugin Click-Window 3D, pour créer vos Fenêtres 3D !
              User avatar
              TNTDAVID 
              PluginStore Author
              PluginStore Author
               

              Re: Delete a list of components by their definitions.

              Postby driven » Sat Jul 08, 2017 1:58 am

              edited my example...

              line 55 i is now item...

              john
              0
              learn from the mistakes of others, you may not live long enough to make them all yourself...

              driven 
              PluginStore Author
              PluginStore Author
               

              Re: Delete a list of components by their definitions.

              Postby TNTDAVID » Sat Jul 08, 2017 3:08 pm

              Thank you driven, your solution works well but encounters the same problem as that of TIG enhanced by Dan.

              The materials applied to the "subcomponents" are not seen by the 2 methods.

              To be more precise, here is an example in image:



              The goal is that the texture "CUBE" is not deleted because it is used by "Nested component".

              Perhaps the solution would be to ask both methods to explore all the subcomponents in SketchUp and collect the materials so as not to delete them?

              How to write this in ruby?

              I could find a solution by modifying the components of Click-Cuisine 2, but the ideal would be to solve the problem with the code.

              If you want to try, here is the SKP file of the example:

              CUBE.skp


              Thank you
              0
              * Nouveau !!!
              Découvrez notre nouveau Plugin Click-Window 3D, pour créer vos Fenêtres 3D !
              User avatar
              TNTDAVID 
              PluginStore Author
              PluginStore Author
               

              Re: Delete a list of components by their definitions.

              Postby driven » Sat Jul 08, 2017 4:14 pm

              you must have changed something because it does work for me...

              did you read the code?

              it collects all nested materials from 'everything' before removing any materials...

              click image to see gif:
              it_wors.gif


              attach your test code...

              john
              0
              learn from the mistakes of others, you may not live long enough to make them all yourself...

              driven 
              PluginStore Author
              PluginStore Author
               

              Re: Delete a list of components by their definitions.

              Postby TNTDAVID » Sat Jul 08, 2017 5:00 pm

              Yes I read your code driven and am surprised that it does not work for me.

              You are right in my last SKP example, your method works.

              Make a test with this example:

              CubeLolaToto2.skp


              You will see that the texture of "TOTO" will be deleted.
              0
              * Nouveau !!!
              Découvrez notre nouveau Plugin Click-Window 3D, pour créer vos Fenêtres 3D !
              User avatar
              TNTDAVID 
              PluginStore Author
              PluginStore Author
               

              Re: Delete a list of components by their definitions.

              Postby TNTDAVID » Sun Jul 09, 2017 9:13 pm

              I can not understand why the texture applied to "TOTO" is purged.

              If I go through "purge_unused" the texture "TOTO" is not deleted.

              So I'll get around the problem with another method.

              To delete a list of materials, I can write this:

              Code: Select all
              mat_names = ['TOTO','LOLA','CUBE']
              materials = Sketchup.active_model.materials
              mat_names.each{|mnj| materials.remove(mnj)}


              Can we do the same with "purge_unused", so that the unused materials of the list are deleted?

              Thank you for your help.
              0
              * Nouveau !!!
              Découvrez notre nouveau Plugin Click-Window 3D, pour créer vos Fenêtres 3D !
              User avatar
              TNTDAVID 
              PluginStore Author
              PluginStore Author
               

              SketchUcation One-Liner Adverts

              by Ad Machine » 5 minutes ago



              Ad Machine 
              Robot
               



               

              Return to Developers' Forum

              Who is online

              Users browsing this forum: Yahoo Bot and 7 guests

              Visit our sponsors: