How to draw a bubble in SketchUp

advice

#1

I need to draw this skylight using the Ruby API. I have no idea how to draw the bubble. Does anyone have a suggestion?

image


#2

It looks like a shape that you could just import and scale.


#3

That shape looks like it could be well represented with a bezier patch. If you use a 4x4 set of control points where you raise the top two ones and the generate a mesh using bezier interpolation you should get that shape.

You can poke at my Bezier Surface extension if you need some reference implementation: https://bitbucket.org/thomthom/bezier-surface


#4

Here is a GIF demo:

BezierSurface


#5

The way my extension works I redraw everything from scratch when the user changes options, rather than importing a component. It’s a magnitude faster that way.


#6

Nice! I’ll have a look. Thanks.


#7

Ooh that looks complicated. It’ll take a bit for me to check it out.


#8

The profile Looks like half a cos curve - maybe you can cheat and use the Face.followme method.


#9

Don’t think that’ll work - since the curvature is longer from the corners than from the sides.


#10

I’m working on creating my own mesh based off the bezier tool.

Also do to the fact that my skylight could be rectangular rather than square, for say a 2’ X 4’ skylight,


#12

I did end up using the follow me tool for my concave cupola roof.


#13

Mr. Burkholder, I enjoy a good challenge. Here is my dashed up solution to drawing this complex shape.

Start by (programmatically) creating a grid one inch by one inch on a side. I have already made one for you in the attached grid.skp file. Then manipulate the grid with the grid_by_faces.rb code below. Lastly texture, scale and rotate! Enjoy

gris%20start

gris%20after

on_roof

module DemoSpace
  model = Sketchup.active_model
  entities = model.active_entities
  model.start_operation('bubble', true)

  # grab the entities collection for your grid
  my_grid = entities.select {|e| e.is_a?(Sketchup::ComponentInstance) && e.name = 'grid'}
  p 'name =' + my_grid[0].name
  
  ents = my_grid[0].definition.entities

  # cache the face outer_loops
  faces  = []
  ents.each { |f|
    next unless f.is_a?(Sketchup::Face)
    faces << f.outer_loop.vertices.map {|v| v.position.to_a}
    }  
  puts 'number of faces = ' + faces.size.to_s

  #erase the original grid 
  ents.clear!
  
  #calculate new value for z for each vertex.
  # by iterating through the outer_loops, and loop vertices
  faces.each {|l|
    l.each {|v|
    v[2] = 0.3 * Math.sqrt(Math.sin(v[0] * Math::PI)) * Math.sqrt(Math.sin(v[1] * Math::PI)) if v[2] == 0.0
    }
  }
  
  # Add the calculated faces loops
  faces.each {|l| ents.add_face(l) } 

  # orient all of the faces in the up direction
  ents.each {|f| 
    next unless f.is_a?(Sketchup::Face)
    f.reverse! if f.normal.z < 0
  }
  model.commit_operation
end

grid.skp (147.6 KB)

grid_by_faces.rb (1.0 KB)


#14

Nice! … and straight forward!


#15

Yeah pretty good. I suggest using a PolygonMesh to create the geometry before adding anything to the model. That way you can create the finished mesh with smoothed lines in one go. Plus it’s faster.


#17

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