Is it possible to save shadows as image?

not with the API, but with a trick you can make an image that doesn’t need cropping…

if your ‘viewport’ has the same ‘ratio’ as your required image, then you can set view.zoom 1.045 to have it fill your ‘viewport’ which is exactly what ‘save_image’ will use…

view.zoom 1.045 may need adjusting for your monitor and needs to be done after the ZoomToSelection…

john

Is it possible to set the viewport width and viewport height?

have a look at Viewport Resizer extension and see if the code can be run on v8…

I think it uses win32 or a system call…

I only have mac code that does it automagicly…

john

I installed the plugin but I was not able to find if it really works. IDK how to use it. The code seems complicated. I includes some .so but only for SU versions 2.0.0 and above? How can I find out which ruby version am I running?

Edit:
Už jsem to našel je to v Plugins jako “Resize Window” a “Resize Viewport”

@john_drivenupthewall:
My new code for view port resizer. This works at least for Ruby console. I do not know how could I access the SU window hwnd to test on SU directly.

For ruby <2.0 you need the Enorth Viewport Resizer because of the Win32API.so driver.

#Require win32api
if RUBY_VERSION < "2.0.0"
  require File.join(PLUGIN_ROOT, "ene_viewport_resizer", "Win32API.so")#Bundled with plugin for SU 2013.
else
  require "Win32API"#Standard libraries included in SU 2014+.
end  

GetActiveWindow = Win32API.new("user32.dll", "GetActiveWindow", "", "L") unless defined?GetActiveWindow  
GetWindowRect = Win32API.new("user32.dll", "GetWindowRect", "LP", "I") unless defined?GetWindowRect
ShowWindow = Win32API.new("user32.dll", "ShowWindow", "LI", "I") unless defined?ShowWindow
MoveWindow = Win32API.new("user32.dll", "MoveWindow", "LIIIII", "I") unless defined?MoveWindow

#Returns array of left, top, right and bottom
def get_rect(hwnd)
  rect = [0, 0, 0, 0].pack("L*")
  GetWindowRect.call hwnd, rect
  rect.unpack("L*").map { |e| [e].pack("L").unpack("l").first }
end
#Get window size as array of width and height.
def get_size(hwnd)  
  left, top, right, bottom = get_rect hwnd
  w = right - left
  h = bottom - top
  return [w, h]
end;

def getRectangleDimensions();
  ss = Sketchup.active_model.selection
  ent = ss[0];
  origin = ent.transformation.origin;
  if ent.class == Sketchup::Group
	   box = ent.local_bounds
  end
  if ent.class == Sketchup::ComponentInstance
	   box = ent.definition.bounds
  end
  mx = box.max.x;
  my = box.max.y;
  x = origin[0];
  y = origin[1];
  z = origin[2];
  v = Sketchup.active_model.active_view;
  a = v.screen_coords(Geom::Point3d.new(x, y, z))
  b = v.screen_coords(Geom::Point3d.new(x, y+my, z))
  c = v.screen_coords(Geom::Point3d.new(x+mx, y+my, z))
  d = v.screen_coords(Geom::Point3d.new(x+mx, y, z))
  w1 = d[0]-a[0];
  h1 = d[1]-c[1];
  # w2 = c[0]-b[0];
  # h2 = a[1]-b[1];
  # puts "#{w} x #{h}"
  # return [ x, y, w, h ]
  return [a[0], c[1], w1, h1];   
end;

def setViewPort(w=400,h=200);
  x, y, w, h = getRectangleDimensions();
  size = [w, h]
  view = Sketchup.active_model.active_view;
  view.vpwidth;
  view.vpheight;
  wp_size = [view.vpwidth, view.vpheight]

  #Assume the main Sketchup window is the active one
  hwnd = GetActiveWindow.call
  window_size = get_size hwnd
  delta_size = window_size.zip(wp_size).map { |x, y| x - y }
  window_new_size = size.zip(delta_size).map { |x, y| x + y }
  ShowWindow.call hwnd, 9; #9 = SW_RESTORE
  left, top, right, bottom = get_rect hwnd
  MoveWindow.call hwnd, left, top, size[0], size[1], 1
end

def centerCamera(perspective = false, zoomOut = 150)
  cam = Sketchup.active_model.active_view.camera;
  cam.perspective = perspective;
  Sketchup.send_action('viewTop:');  
  Sketchup.send_action('viewZoomToSelection:');
end;

PLUGIN_ROOT = File.dirname(__FILE__) unless defined?(PLUGIN_ROOT)
# file = PLUGIN_ROOT + "/shadows.rb"
file = File.join(PLUGIN_ROOT, "shadows.rb")
if not (file_loaded? file )
	UI.menu("Plugins").add_item("Barracuda Shadows") { centerCamera(); }
  file_loaded file
end  

call setViewPort

Viewport is ready. But if I change the ratio of the view then the label “Top” will be visible above the plane to be exported. Is is possible to hide the “Top” text in upper left corner of the viewport?

did you test that?

it dosn’t export in later versions and I don’t recall it happening in v8…

john

Sorry, u’r right

@john_drivenupthewall

I found that the modification of the viewport is not correct. There are some odd numbers

def self.get_rect(hwnd)
  rect = [0, 0, 0, 0].pack("L*")
  GetWindowRect.call hwnd, rect
  rect.unpack("L*").map { |e| [e].pack("L").unpack("l").first }
end;

def self.get_size(hwnd)  
  left, top, right, bottom = self.get_rect hwnd
  w = right - left
  h = bottom - top
  return [w, h]
end;


  window_size = self.get_size @hwnd
  puts "Window " + @hwnd.to_s + " size:"
  puts size
  delta_size = window_size.zip(wp_size).map { |x, y| x - y }
  puts delta_size

Do you know what the zio … map methods do? It is Not clear to me what is this doing { |x, y| x - y }

The odd values:
426.0309657635
341.98404054485
delta_size:
-40
-54

Real values:
cca 535, 600
cca -66, -92

Real viewport size cca 466, 396

Edit:
I found problem with the self.get_rect method.
It returns silly numbers. The only number in bold
left: 126, top: 147, right: 552, bottom: 488
is correct

Let’s take a look on the method which should set the view port:

def self.setViewPort(w=400,h=200);
  x, y, w, h = self.getRectangleDimensions();
  size = [w, h]
  view = Sketchup.active_model.active_view;
  view.vpwidth;
  view.vpheight;
  wp_size = [view.vpwidth, view.vpheight]
  puts wp_size
  #Assume the main Sketchup window is the active one
  #hwnd = GetActiveWindow.call
  # hwnd = get_sketchup_window(hwnd) if hwnd == 0

  #Loop this code a few times since toolbars can get 'thicker' when made narrower and change delta_size value.
  3.times do
    window_size = self.get_size @hwnd
    #puts "Window " + @hwnd.to_s + " size:"
    #puts size  
    
    #delta_size = window_size.zip(wp_size)
    #UI.messagebox wp_size[0].to_s + " " + wp_size[1].to_s
    #UI.messagebox delta_size[0].to_s + " " + delta_size[1].to_s
    delta_size = window_size.zip(wp_size).map { |ws, wps| ws - wps }
    #puts "delta_size:"
    #puts delta_size
    # UI.messagebox delta_size[0].to_s + " " + delta_size[1].to_s
    
    window_new_size = size.zip(delta_size).map { |x, y| x + y }
    
    break if window_size == window_new_size
    
    #'restore window' (stop it from being maximized)
    #Without this the window would still get the wanted size be 'marked' as maximized and moving it would result in reseting the size (Win7).
    ShowWindow.call @hwnd, SW_RESTORE;
    
    left, top, right, bottom = get_rect @hwnd
    MoveWindow.call @hwnd, left, top, size[0], size[1], 1
  end#3.times do
end;

wp_size array includes width and height of viewport - correct
window_size array includes width and height of window - correct
delta_size - contains window size - viewport size
delta_size = window_size.zip(wp_size).map { |ws, wps| ws - wps }
Not exactly clear to me why this is made this way. Maybe you could explain how it works? Especially the zip. But I think this is the same like delta_size[0] = window_size[0] - wp_size[0] and delta_size[1] = window_size[1] - wp_size[1] The map here I understand it works similar like each. I guess the zip creates array with 4 elements from 2 separate arrays with 2 elements, rights? I mean it joints them togheter rights? But I think the zip creates two long numbers instead 4 elements so I am not sure.

The look 3 times tries to set the viewport to new size.

ary1 = [ 1, 2, 3 ]
ary2 = [ 4, 5, 6 ]
puts
p ary3 = ary1.zip( ary2 )
puts
p ary3.map { |a, b| a + b }
puts
ary3.each { |a, b| a + b }

=begin returns
[[1, 4], [2, 5], [3, 6]]

[5, 7, 9]

[[1, 4], [2, 5], [3, 6]]

=end

.each returns the original array, .map returns the result…

john

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.