sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    [APIBug] Applying current material might cause bugsplat

    Scheduled Pinned Locked Moved Developers' Forum
    11 Posts 3 Posters 528 Views 3 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • thomthomT Offline
      thomthom
      last edited by

      I documented a cause of bugsplat on video.

      [flash=640,505:39uk3dmx]http://www.youtube.com/v/Rv4KmpEMP5M?fs=1&hl=en_US[/flash:39uk3dmx]

      Snippets used in video:
      Sketchup.active_model.materials.length

      Sketchup.active_model.selection[0].material = Sketchup.active_model.materials.current

      Issue:
      It appears that when the user has selected a material from the libraries in the material browser, and you try to apply that material via the Ruby API before it exists in the model, then SketchUp becomes unstable and will eventually crash shortly after. I noticed other odd behaviour, but didn't manage to catch that on camera.

      I haven't found a way to safely apply current material if it's not already in the model.

      Avoidance:
      So far I've only managed to find a way to avoid using materials that are not in the model:
      current_materia = Sketchup.active_model.materials.current Sketchup.active_model.materials.any? { |m| m == current_material }

      Thomas Thomassen — SketchUp Monkey & Coding addict
      List of my plugins and link to the CookieWare fund

      1 Reply Last reply Reply Quote 0
      • mitcorbM Offline
        mitcorb
        last edited by

        A question here:
        This condition occurs only when you have the Ruby Console open, and in the video it appears you are applying it as input to the console and not in the model space?
        Could the material, or the program be looking for a defined face in its "code" on activation? Is this condition unique to any particular version of Sketchup?

        I take the slow, deliberate approach in my aimless wandering.

        1 Reply Last reply Reply Quote 0
        • thomthomT Offline
          thomthom
          last edited by

          @mitcorb said:

          This condition occurs only when you have the Ruby Console open,

          No - I ran into it when testing a plugin I was working on. I used the Ruby Console in this example because it shows the simplest case to reproduce it.

          @mitcorb said:

          and in the video it appears you are applying it as input to the console and not in the model space?

          Sorry, but what? 😕

          @mitcorb said:

          Could the material, or the program be looking for a defined face in its "code" on activation?

          Still not quite sure what you mean here, but my snippet which I used in the Ruby Console applied the current material to the selected entity. The bugsplat occurs when the current material does not yet exist in the model, but is picked from the model library - as shown in the video.

          @mitcorb said:

          Is this condition unique to any particular version of Sketchup?

          I have only tested SketchUp8 under Windows. Don't know the other versions.

          Thomas Thomassen — SketchUp Monkey & Coding addict
          List of my plugins and link to the CookieWare fund

          1 Reply Last reply Reply Quote 0
          • mitcorbM Offline
            mitcorb
            last edited by

            ThomThom:
            mitcorb wrote:and in the video it appears you are applying it as input to the console and not in the model space?
            Sorry, but what? 😕

            Here, what I mean is you selected the material from its browser, then clicked on the input line of the console, not on anything in the model space, as far as I can tell. (didn't know you could do that)

            mitcorb wrote:Could the material, or the program be looking for a defined face in its "code" on activation?
            

            Here, what I mean is: As part of Selection of Material and placement, you have to tell Sketchup, or whatever what surface you will apply it to.

            I really do not have any Ruby experience. I was just looking at this from a conceptual point of view, with the intent to help discover an idea, if it was lurking there.

            I take the slow, deliberate approach in my aimless wandering.

            1 Reply Last reply Reply Quote 0
            • TIGT Offline
              TIG Moderator
              last edited by

              I can reproduce the problem.
              If you have a library-material picked that should become the model.materials.current after it's used once BUT SUp changes the model.materials.current too soon to be the library-material when it isn't part of model.materials [except that it returns as 'current'], you can then use that 'current' material in the SKP... BUT it is not yet added to materials [the length of model.materials remains the same, materials.to_a doesn't include this library-material [yet], and the material-browser model-window doesn't show it either]... later doing something to the materials list will cause a Bugsplat as something is cross-threaded in the data-base.
              The clunky trap is to get the current_material before this library step ( current_material0=model.materials.current) then reset it current_material=model.materials.current if model.materials.to_a.include?(model.materials.current) then reset the current_material with current_material=current_material0 if not current_material; model.materials.current=current_material - then you can't cross-thread things???
              Surely a selected library-material should not pass the model.materials.current until it has been used.
              It is taking the material in the top pane of the material-browser rather than the true 'current-material' - which is the "[last] selected material that is in the model" ???
              Of course using my 'SKMtools' would let you import the SKM into the model's materials and then set it current without this mess...

              TIG

              1 Reply Last reply Reply Quote 0
              • thomthomT Offline
                thomthom
                last edited by

                @mitcorb said:

                Here, what I mean is you selected the material from its browser, then clicked on the input line of the console, not on anything in the model space, as far as I can tell. (didn't know you could do that)

                Yes, I applied the material to the selected face via the Ruby API. It makes the whole difference. Using the Paint Bucket tool does not have this problem. The problem comes when you write a plugin that makes use of the user-selected material.

                @mitcorb said:

                you have to tell Sketchup, or whatever what surface you will apply it to.

                Yes, which is what this line does:
                Sketchup.active_model.selection[0].material = Sketchup.active_model.materials.current
                It applied the current material to the selected entity.

                Thomas Thomassen — SketchUp Monkey & Coding addict
                List of my plugins and link to the CookieWare fund

                1 Reply Last reply Reply Quote 0
                • thomthomT Offline
                  thomthom
                  last edited by

                  @tig said:

                  Surely a selected library-material should not pass the model.materials.current until it has been used.
                  It is taking the material in the top pane of the material-browser rather than the true 'current-material' - which is the "[last] selected material that is in the model" ???

                  It would be ok if SU ensured to add the material to the model when used. Which is what I'd prefer so you could get seamless experienced with the material browser and plugins.

                  Thomas Thomassen — SketchUp Monkey & Coding addict
                  List of my plugins and link to the CookieWare fund

                  1 Reply Last reply Reply Quote 0
                  • thomthomT Offline
                    thomthom
                    last edited by

                    @tig said:

                    The clunky trap is to get the current_material before this library step ( current_material0=model.materials.current) then reset it current_material=model.materials.current if model.materials.to_a.include?(model.materials.current) then reset the current_material with current_material=current_material0 if not current_material; model.materials.current=current_material - then you can't cross-thread things???
                    Surely a selected library-material should not pass the model.materials.current until it has been used.

                    That would be:
                    current_material0=model.materials.current current_material=model.materials.current if model.materials.to_a.include?(model.materials.current) current_material=current_material0 if not current_material model.materials.current=current_material

                    ❓

                    Doesn't that just move the material reference around to different variables? I can't get that to make the material be added to the in-model list.

                    Thomas Thomassen — SketchUp Monkey & Coding addict
                    List of my plugins and link to the CookieWare fund

                    1 Reply Last reply Reply Quote 0
                    • TIGT Offline
                      TIG Moderator
                      last edited by

                      @thomthom said:

                      @tig said:

                      The clunky trap is to get the current_material before this library step ( current_material0=model.materials.current) then reset it current_material=model.materials.current if model.materials.to_a.include?(model.materials.current) then reset the current_material with current_material=current_material0 if not current_material; model.materials.current=current_material - then you can't cross-thread things???
                      Surely a selected library-material should not pass the model.materials.current until it has been used.

                      That would be:
                      current_material0=model.materials.current current_material=model.materials.current if model.materials.to_a.include?(model.materials.current) current_material=current_material0 if not current_material model.materials.current=current_material
                      ❓
                      Doesn't that just move the material reference around to different variables?
                      I can't get that to make the material be added to the in-model list.

                      You can't force a library-material into the model.materials proper unless you physically add it manually.
                      The way to do it in code is to use my SKMtools - SKM.import(path_skm).
                      You can perhaps get the temporary limboed material.current.name to find the SKM name ?
                      Then find it in Materials ?
                      If you make an array of model.materials before andafterward the SKM import you get the reference to the new material - although you could get it by name preexisting names might screw that up... Then set the model.material.current=that_new_material to complete...

                      Alternatively you could try to get all of the properties of the 'current-material-in-limbo' half-baked on it's way in from the library and make a completely new material in the model based on all of it's properties and then set that as current. However you need to get it's texture which requires it to be applied to something temporarily at least for a texturewriter... which would probably splat too ???

                      TIG

                      1 Reply Last reply Reply Quote 0
                      • TIGT Offline
                        TIG Moderator
                        last edited by

                        Thom

                        I have a clunky work round to force a selected material from the library into the model.materials without a Bugsplat.
                        You need my SKMtools, material_class.rb loaded as it uses the material.name="newname" method
                        Here are the basic steps...

                        mats=Sketchup.active_model.materials
                        #<Sketchup;;Materials;0xa93a9cc>
                        cmat=mats.current
                        ### let's assume if is a library material not really in the model yet...
                        #<Sketchup;;Material;0xa77e084>
                        cname=cmat.display_name
                        Brick_Antique
                        cmat=(cmat.name=cname+"x")
                        #<Sketchup;;Material;0xa77e098>
                        cmat.name=cname
                        Brick_Antique
                        

                        The material hovering in limbo when is selected from the library materials-browser but not yet used in the model itself is briefly renamed and then named back again... forcing it to become part of the model's materials, so it keeps its name and is kept as the current-material too. I haven't got a Bugsplat [yet 😒 ]...

                        TIG

                        1 Reply Last reply Reply Quote 0
                        • TIGT Offline
                          TIG Moderator
                          last edited by

                          Here's a short code snippet

                          <span class="syntaxdefault"></span><span class="syntaxkeyword">=</span><span class="syntaxdefault">begin<br /></span><span class="syntaxkeyword">(</span><span class="syntaxdefault">c</span><span class="syntaxkeyword">)</span><span class="syntaxdefault"> TIG 2011<br /></span><span class="syntaxkeyword">=</span><span class="syntaxdefault">end<br />require </span><span class="syntaxstring">'sketchup.rb'<br /></span><span class="syntaxdefault">require </span><span class="syntaxstring">'SKMtools/material_class.rb'<br /></span><span class="syntaxcomment">###<br /></span><span class="syntaxdefault">def material_from_limbo</span><span class="syntaxkeyword">()<br /></span><span class="syntaxdefault">    mats </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">materials<br />    cmat </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> mats</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">current </span><span class="syntaxcomment">### the limbo one<br /></span><span class="syntaxdefault">    cname </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> cmat</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">display_name<br />    cmat</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">name </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> cname</span><span class="syntaxkeyword">+</span><span class="syntaxstring">"x"<br /></span><span class="syntaxdefault">    cmat </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> mats</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">current<br />    cmat</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">name </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> cname<br />    cmat </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> mats</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">current<br />    return cmat </span><span class="syntaxcomment">### now safely added to model<br /></span><span class="syntaxdefault">end<br /></span><span class="syntaxcomment">### usage; cmat = material_from_limbo<br /></span><span class="syntaxdefault"> </span>
                          

                          If you select a material from the library and then immediately run the 'usage' example you will have a reference to the new current material that is added to the model [but currently unused]. The active tool will stay as the paintbucket unless you code an alternative 'tool' change...

                          TIG

                          1 Reply Last reply Reply Quote 0
                          • 1 / 1
                          • First post
                            Last post
                          Buy SketchPlus
                          Buy SUbD
                          Buy WrapR
                          Buy eBook
                          Buy Modelur
                          Buy Vertex Tools
                          Buy SketchCuisine
                          Buy FormFonts

                          Advertisement