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

    Projected Texture (and Google Earth)

    Scheduled Pinned Locked Moved Developers' Forum
    13 Posts 3 Posters 991 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.
    • S Offline
      skavan
      last edited by

      Hi all,

      I'm trying to Ruby-ize the excellent tutorial found here:
      http://www.go-2-school.com/media/view/1

      This tutorial shows how to manually replace the B&W terrain images that are pulled from google earth with color ones.

      I was hoping to eliminate the manual material "line-up" process with an automatic one.

      I have it working with the 2D plane...but can't for the life of me figureout how to do it with the 3D terrain...and am hoping someone more talented than I can kick me in the right direction.

      So, my steps for the 2D piece of the puzzle are in the attached code..to see it in action, fire up Google Earth, zoom into the required terrain. Switch to sketchup and "Get Current View" to import the google terrain. Go back into Google Earth and SAVE IMAGE (for the higher res color image). Edit the script to the image file you just saved and let it rip. You will see the 2D terrain is perfect. The 3d terrain needs resizing - but I can't figure out how to do it (and alter the aspect ratio!). HELP!

      ` # Grab a handle to the currently active model (aka the one the user is looking at in SketchUp.)
      model = Sketchup.active_model

      def flattenUVQ(uvq)
      uvq.x = uvq.x / uvq.z
      uvq.y = uvq.y / uvq.z
      uvq.z = 1.0
      return uvq
      end

      Grab other handles to commonly used collections inside the model.

      entities = model.entities
      layers = model.layers
      materials = model.materials
      component_definitions = model.definitions
      selection = model.selection

      Now that we have our handles, we can start pulling objects and making

      method calls that are useful.

      ge_entity = entities[0]
      ge_snapshot = entities[0]
      ge_terrain = entities[0]

      UI.messagebox("First thing in your model is a " + first_entity.typename)

      number_objects = entities.length
      puts "\nnumber entities:" + number_objects.to_s
      puts "=================\n"

      for k in 1..number_objects
      if entities[k-1].typename.to_s == "Group"
      ge_entity = entities[k-1]
      if ge_entity.name == "Google Earth Snapshot"
      ge_snapshot = ge_entity
      elsif ge_entity.name == "Google Earth Terrain"
      ge_terrain = ge_entity
      end
      end
      end

      bounds = ge_snapshot.local_bounds #get the bounds of the image
      puts "processing google earth snapshot..."
      puts "---bounds [height:" + bounds.height.to_s + "] width:" + bounds.width.to_s
      puts "---sub-entities:" + ge_snapshot.entities.length.to_s + " found. looking for face."

      ge_snapshot.locked=false #unlock the entity
      ge_terrain.locked = false

      for h in 1..ge_snapshot.entities.length
      face_entity = ge_snapshot.entities[h-1]
      if face_entity.typename.to_s == "Face" # we've found our face
      break
      end
      end

      mat = face_entity.material # grab the material
      texture = mat.texture #Assign the texture

      puts "---face found. processing face."
      puts "------[material:" + mat.display_name + "]\n------[texture:" + texture.filename + "]"
      puts " height: " + texture.height.to_s
      puts " width: " + texture.width.to_s
      puts " image_height: " + texture.image_height.to_s
      puts " image_width: " + texture.image_width.to_s

      tw = Sketchup.create_texture_writer
      uv_helper = face_entity.get_UVHelper true, false, tw

      samples = [] #Create a set of samples
      samples << face_entity.vertices[0].position # 0,0 | Origin
      samples << samples[0].offset(face_entity.normal.axes.x) # 1,0 | Offset Origin in X
      samples << samples[0].offset(face_entity.normal.axes.y) # 0,1 | Offset Origin in Y
      samples << samples[1].offset(face_entity.normal.axes.y) # 1,1 | Offset X in Y

      Arrays containing 3D and UV points.

      xyz = []
      uv = []

      samples.each { |position|
      # XYZ 3D coordinates
      xyz << position
      # UV 2D coordinates
      uvq = uv_helper.get_front_UVQ(position)
      uv << self.flattenUVQ(uvq)
      }
      print "\nxyz: " + xyz.to_s
      print "\nuv : " + uv.to_s
      print "\n"

      Position texture.

      pts = []
      (0..3).each { |i|
      pts << xyz[i]
      pts << uv[i]
      }

      puts "------Setting size to " + bounds.width.to_s

      mat.texture = "G:\Test Image 01.JPG" # Grab our hi-res image
      mat.texture.size = bounds.width # Resize the thing
      face_entity.position_material mat, pts, true # Apply the coordinates

      puts "------Reapplying co-ordinates"

      puts "=================\nend of run"`

      1 Reply Last reply Reply Quote 0
      • GaieusG Offline
        Gaieus
        last edited by

        Hi Suresh,

        The whole process shown in the video is overcomplicated and useless.

        What you can simply do is skip the whole resizing and positioning phase and follow these steps:

        1. go to the edit mode of the B&W image
        2. without any kind of fiddling around with the tape measure and image resizing steps, simply reload it with the colur version.
          The size and positioning will be perfectly as that of the colour version (as by reloading the imayge, it will NOT affect its previous UV mapping at all)
        3. now enter the flat terrain group, right click on the face, go to Texture > Projected (don't even touch the positioning tool - no need at all).
        4. Now sample this projected material, open the terrain and paint it with the projected material
          You can also use this projected texture to paint the roofs of your models per Google's "preference" - at least where the GE imagery is good enough (and positioned correctly)
          You may use these steps to write a plugin but IMO it is so simple and speedy procedure that you wouldn't really need it. Can be done within like half a minute.

        Gai...

        1 Reply Last reply Reply Quote 0
        • S Offline
          skavan
          last edited by

          Gaieus,

          Thanks for the comments. As you'll see from the code, I'm not re-creating the useless steps in the video - however simply loading an image DOES NOT work as the aspect ratio gets reset. Therefore, positioning and sizingthe map IS required. Hence the code. As for the terrain bit (where I'm stuck), yes - it can be done manually-but since I want to repeat this exercise 50+ times (I'm cutting a range of terrain from GE).

          So - how can one do your steps 3 and 4 programattically? I can't figure it out for the life of me!

          s.

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

            Reload a texture via Ruby?

            Before you replace the old texture - read and store the width and height of it.
            Then when you have loaded the new one - apply the width and height.

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

            1 Reply Last reply Reply Quote 0
            • S Offline
              skavan
              last edited by

              thomthom,

              ok - I'm sure I'm being very dense...but a couple of points/questions:

              1. How does one set the width and height of the texture in code? One can read texture.height and texture.width but not set them..and one only gets to SET texture.size....but that assumes the aspect ratio is the same as before. In this example, it's not...so the question is how does one set the width and height independently --- isn't it in the apply material position function?

              2. by way of explanation, google earth in injects the terrain with a 1" square texture size that is then stretched as needed EVEN though the image is say, 1600x1200. As soon as one reloads/loads an image, this aspect is changed to match the incming image and the "ASPECT LOCK" is lost. So when one reapplies the texture.size =1", what happens is width becomes 1" and height becomes 5/8" to maintain aspect ratio. Manually, it's easy - click OFF the aspect lock button in the texture window and enter the 1" value in the width...but how to do that in code?

              Thanks,

              s.

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

                Ah, yes: welcome to the SU API Manual - Don't trust it!

                Texture.size=
                http://code.google.com/apis/sketchup/docs/ourdoc/texture.html#size=

                Arguments:

                • Number size
                • Array(width, height) <- πŸ˜‰

                Example: Texture.size=[20,40]

                We got a looooong thread going with reports of missing and incorrect info in the manual: http://forums.sketchucation.com/viewtopic.php?f=180&t=17047

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

                1 Reply Last reply Reply Quote 0
                • S Offline
                  skavan
                  last edited by

                  awesome! thanks so much -- you have no idea how many hours I spent - bloody manual!

                  Anyway - one more, last part of the puzzle.

                  Loading the image and then setting a new mat.texture.size = [1,1] works fine.
                  The only thing is that the image isn't really a square aspect ratio and its applied size isn't really 1" x 1". It's actually a 4800x3600 image and an applied size of 4913' 5 1/4" and 3137' 8 1/2"!!! While the above 1x1 at aspect of 1 works...do you have any tips for how I then adjust the image so that its physically "right" even though its already visually "right"!

                  Thanks.

                  s.

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

                    Not sure if I understand. You say it's visually right - it looks correct in SU? Then what is physically right?

                    There's two things that affects how a material is applied to a face.

                    The default size if the info in material.texture
                    But if the user has positioned the material on the face, or you have used face.position_texture, then that also affects it.

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

                    1 Reply Last reply Reply Quote 0
                    • S Offline
                      skavan
                      last edited by

                      "visually right" = it looks good in sketchup..the texture is applied as it should be.

                      "physically wrong" = the size of the terrain is 4090' x 3250'. the texture size is 1"x1". The texture size has the wrong size and aspect ratio...but somehow sketchup knows how to transform this. Maybe I shouldn't worry about it since it's "visually right" - but it would be great for the physics to match the visual.

                      Best way of seeing this, if you have google earth, is to fire it up. click the Getr Current View in Sketchup and see the texture properties of the material that represents the ground terrain. it will say 1"x1", even though it's really not!

                      I'm guessing the trick is to use face.position_material -- and someshow pass in xyz and uv pairs -- but containing what is beyond me.

                      s.
                      Thanks again.

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

                        Since GE places the original texture there in 1" x 1" and you want to replace it with a different colour version, then it's best to just leave it like that. It works.
                        It's visually correct because it has been Positioned like that, which override the default Texture size. But if you afterwards meddle with the Texture size you will affect the positioned material.

                        But if you where creating a material from scratch, then you'd just calculate the aspect ratio of the texture's pixel size and use that for texture.size=

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

                        1 Reply Last reply Reply Quote 0
                        • GaieusG Offline
                          Gaieus
                          last edited by

                          Guys, I really don1t know coding - but totally without any texture positioning, I could simply reload the image in this file in less than a minute.
                          Now how you translate it into ruby code - is totally out of my knowledge


                          MyPlace.skp

                          Gai...

                          1 Reply Last reply Reply Quote 0
                          • S Offline
                            skavan
                            last edited by

                            Gaieus --

                            are you sure it reloaded with EXACTLY the same positioning. If so, it's a fluke.
                            IF you pull the terrain from Google Earth, take a color snapshot from google earth and load the color image into the texture...the texture size (tiling is wrong) as it shifts from a 1:1 to the aspect ration of the incoming image.

                            It only takes a few seconds, but one MUST reset the texture size.

                            If you are doing this for 50 pieces of a large terrain loaded from GE, tile by tile, then ruby saves a LOT of effort.

                            s,

                            1 Reply Last reply Reply Quote 0
                            • GaieusG Offline
                              Gaieus
                              last edited by

                              Well, I did indeed play around quite a lot to see what's happening when I am doing this. My approach was to reload the image and then go to top view and toggle undo/redo to see the difference between the B&W and the colour version.
                              To be honest, I didn1t see any difference so I basically trust the method - true that when I go quite close in my area, the imagery is not the best as well as in those rare cases when I use this technique (to paint some small scale, artificial terrain for GE), any subtle difference would be rather unnoticeable.

                              Gai...

                              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