SketchUp Ruby API and 2 Point Perspective Expertise Needed

But why do all that zipping work ? Does the following do the same ?

def center_model_on_ORIGIN(op_name="Center Model")
  model = Sketchup.active_model
  center = model.bounds.center
  vector = Geom::Point3d.new(center.x,center.y,0).vector_to(ORIGIN)
  #
  model.start_operation( op_name, true, false, true )
  ###
    model.entities.transform_entities(vector,model.entities.to_a)
    model.pages.each do |page|
      cam = page.camera
      cam.set(
        cam.eye.transform!(vector),
        cam.target.transform!(vector),
        cam.up # use the same up
      )
    end
  ###
  model.commit_operation
  # 
end ### center_model_on_ORIGIN

EDIT: Removed the call to page.update within the block.
(As this would set all page cameras to whatever the current camera is.)

2 Likes

Got it. Thanks Dan!

@DanRathbun @john_drivenupthewall Thank you for all the effort. I will apply the code to our model today and let you guys know how it works.

Really, really appreciate!

1 Like

Be safe. Try it on a backup copy first.

2 Likes

@DanRathbun @john_drivenupthewall Problem solved!!! I gave solution to John’s original code, but what actually worked is a combination of Dan’s and John’s code below. Kudos to both you guys!!!

model = Sketchup.active_model
center = model.bounds.center
vec =  Geom::Point3d.new(center.x,center.y,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
2 Likes

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