SketchUp Ruby API and 2 Point Perspective Expertise Needed

how was the speed?

can you run a timing on both versions for our curiosity…

# at the top
t1 = Time.now
# at the end
Time.now - t1

just swap the core…

   # swap this
    e0  = eye.to_a
    t0  = target.to_a
    # use standard ruby on target position
    t = t0.zip([stp_r, stp_g, stp_b]).map(&:sum)
    # eye positions
    e = e0.zip([stp_r, stp_g, stp_b]).map(&:sum)
    # use the same up
   cam.set(e, t, up)
###  for this
      cam.set(
        cam.eye.transform!(vector),
        cam.target.transform!(vector),
        cam.up # use the same up
      )

do a restart in between runs of fresh copies of the same skp file…

and maybe add some model statistics…

john

The update speed was instant.

I would like to try, however Dan’s code core couldn’t run on my SketchUp 2019 when I tested. I ended up only using part of his on centering the model.

1 Like

Did you get an error? What was it?

Dan,

I didn’t get any error. It just ran the code and returned no visual change before/after.

Thanks.

Was this before or after I fix the code by removing the page.update call ?

Ie …

Was after you removed the call.

Can you post a test model with all the camera scenes before the move operation ?

Let me do it shortly!

Link to the model.

I had to convert it to v2018. But I do not see any scene pages in this model.
You said you had scenes, …
Some were 3 pt perspective and some where 2 pt perspective and some may have been orthogonal ?

It is the adjustment of your scenes that is the main issue.

Below is the 2018 version of the test model I converted. Yes, this is my test model which should have 2 scenes in it. Our project model has tons of scene, I didn’t send you for confidential concern. However I guarantee the code behave the same in both models.

Test model 2018 Version

Best,

Shuojin

@john_drivenupthewall @DanRathbun

Hi Dan and John,

There is one more little question.

We got the code working perfectly for the purpose. I have been thinking about how to execute centering of the model process. Since not only we have multiple people team, we have multiple models (around 20): elevation exports, individual building model, animation model, aerial view model, etc,. And we have a lot of archived versions of each. Is there an effective way, by adding something to the code, to leave marks after the centering is done (for example to generate a layer of certain name) to inform the team members visually, as well as to inform the code itself not to run twice? What would you guys usually do?

Thanks a lot,

Shuojin

you can tag the model file…

tested code…

def test_tag
  # at the top
  done = Sketchup.active_model.get_attribute('JcB', 'cams_moved')
  return 'already processed' if done
  # <code>
p 'new_file'
  # at the end of the code you add...
  Sketchup.active_model.set_attribute('JcB', 'cams_moved', true)
end

the script will only run once per file…

john

Let me test out!!!

@john_drivenupthewall The core works as used alone, but it doesn’t return anything once I combined the code. Appreciated, could you please help take a quick look at the code?

def test_tag
  # at the top
  done = Sketchup.active_model.get_attribute('JcB', 'cams_moved')
  return 'already processed' if done
# <code>

model = Sketchup.active_model
center = model.bounds.center
vec =  Geom::Point3d.new(189600,169200,0).vector_to(ORIGIN)
model.entities.transform_entities(
vec,model.entities.to_a)
 stp_r, stp_g, stp_b = vec.to_a.entries
    # then
    pages = Sketchup.active_model.pages
    pages.each do |page|
    # camera
    cam = page.camera
    # camera target
    target = cam.target
    # camera eye
    eye = cam.eye
    # camera up
    up = cam.up
   # get arrays
    e0  = eye.to_a
    t0  = target.to_a
    # use standard ruby on target position
    t = t0.zip([stp_r, stp_g, stp_b]).map(&:sum)
    # eye positions
    e = e0.zip([stp_r, stp_g, stp_b]).map(&:sum)
   # use the same up
   cam.set(e, t, up)
   
   end #pages.each

p 'new_file'
  # at the end of the code you add...
  Sketchup.active_model.set_attribute('JcB', ' cams_moved', true)
end

The name of the dictionary "JcB" should have been read as an example. (It is John’s initials.)
You really should use your own unique dictionary name. Usually developers use a combination of their company namespace and the plugin name …
Ex:

return if Sketchup.active_model.get_attribute('YangSuoJin_ModelMover', 'move_done')

The return statement in Ruby “returns” from a method to the place that called the method.

The first time run, your should see "new_file" output to the Console.
You can change that to something more descriptive, if you wish. Or you could use a message box.
See: UI.messagebox

1 Like

Very good to know! Thanks Dan.

1 Like

@john_drivenupthewall

Final Code with Full Function:

require 'sketchup.rb'

module Examples
	module CenteringModel

		#centering model.
		def self.centering_model
			# at the top
	        done = Sketchup.active_model.get_attribute('Shuojin', 'model_moved')
	        if done
	        	UI.messagebox('This model is centered already!')


            else
				#centering the model by preset distance.
				model = Sketchup.active_model
				vec =  Geom::Point3d.new(186764.218159,167965.596006,188.011513).vector_to(ORIGIN)
				model.entities.transform_entities(vec,model.entities.to_a)

				 stp_r, stp_g, stp_b = vec.to_a.entries
				    # then
				    pages = Sketchup.active_model.pages
				    pages.each do |page|
				    # camera
				    cam = page.camera
				    # camera target
				    target = cam.target
				    # camera eye
				    eye = cam.eye
				    # camera up
				    up = cam.up
				   # get arrays
				    e0  = eye.to_a
				    t0  = target.to_a
				    # use standard ruby on target position
				    t = t0.zip([stp_r, stp_g, stp_b]).map(&:sum)
				    # eye positions
				    e = e0.zip([stp_r, stp_g, stp_b]).map(&:sum)
				   # use the same up
				   cam.set(e, t, up)
				   
				   end #pages.each

				# adding a tag
	            Sketchup.active_model.set_attribute('Shuojin', 'model_moved', true)

	            UI.messagebox('This model is centered!')

            end


        end # centering_model

        #Add menu item.
        unless file_loaded?(__FILE__)

        	# Add to extension menu.
        	menu = UI.menu('Plugins')

        	#Menu name.
        	menu.add_item('Centering Model'){
              self.centering_model
        	}

        	file_loaded(__FILE__)
        end

    end # module CenteringModel
end # module Examples
  1. Your top level namespace module should be unique, probably Shuojin, and not Examples as this is too generic and likely to clash with someone’s else’s example utility plugin.

  2. Offsetting the model by a specific “hard-coded” distance does not set a good example. Not all models will have the same boundingbox so they’ll need to each be offset by the vector from their bottom center to the ORIGIN (as we showed above several times.)

  3. Your indentation is not correct and it’s 4 spaces. Ruby language uses 2 space indents. (The 4 space indents cause the need for excessive horizontal scrolling of code block in forum posts.)

1 Like

Thanks Dan! I will definitely do clean up and repost. I do see your comments would benefit hugely, hugely in the long run.

2 Likes