Hi @Fredo6, Welp, I tried to implement your instructions, but I think the part where it has to delete faces is just too much for my poor little mac. Even with a cloud of only two spheres, it hung and hung on that part before finally producing this funny result. And swallowed all the print statements to boot.
Maybe I implemented it wrong, or maybe it’s just too n^2 for my machine, I’m not sure.
Here’s my modified script in which I tried to implement what you suggested.
Everything goes great until the delete faces part at the end.
module Cloud
def self.create_color(color, alpha, i)
model = Sketchup.active_model
entities = model.active_entities
material = model.materials.add("Cloud Face #{i}")
material.color = color
material.alpha = alpha
return material
end # end create_color
def self.create_ovoid_sphere(sphere, min_rand, max_rand)
cpt = sphere.bounds.center
x = rand(min_rand..max_rand)
y = rand(min_rand..max_rand)
z = rand(min_rand..max_rand)
scale = Geom::Transformation.scaling(cpt, x, y, z)
sphere.transform!(scale)
return sphere
end # end create_ovoid_sphere
def self.create_sphere(entities, center, radius, material)
#print "create_sphere"
model = Sketchup.active_model
group = entities.add_group
g_entities = group.entities
model.start_operation("create_sphere",true,false,true)
circle = g_entities.add_circle(center, Z_AXIS, radius)
circle_face = g_entities.add_face(circle)
circle_face.material = material
circle_face.back_material = material
path = g_entities.add_circle(center, X_AXIS, radius + 1)
circle_face.followme(path)
g_entities.erase_entities path
model.commit_operation
model.active_view.refresh
return group
end # end create_sphere
def self.displace_sphere(sphere, x_range, y_range, z_range, angle_range)
cpt = sphere.bounds.center
x = rand(-x_range..x_range)
y = rand(-y_range..y_range)
z = rand(-z_range..z_range)
center = [x,y,z]
angle = rand((90-angle_range)..90+angle_range)
x_rotate_x = Geom::Transformation.rotation(ORIGIN, X_AXIS, angle.degrees)
x_rotate_y = Geom::Transformation.rotation(ORIGIN, Y_AXIS, angle.degrees)
x_rotate_z = Geom::Transformation.rotation(ORIGIN, Z_AXIS, angle.degrees)
x_point = Geom::Transformation.new(center)
sphere.transform!(x_rotate_z * x_rotate_x * x_rotate_y)
sphere.transform!(x_point)
return sphere
end # end displace_sphere
def self.create_cloud(num_spheres, min_radius, max_radius, min_rand, max_rand,
x_range, y_range, z_range, angle_range)
print "create_cloud"
model = Sketchup.active_model
entities = model.active_entities
master_group = entities.add_group
m_entities = master_group.entities
model.start_operation("create_cloud",true,false,true)
color = Sketchup::Color.new(255, 255, 255)
material = self.create_color(color, 0.25, 1)
num_spheres.times do |i|
x = rand(min_rand..max_rand)
y = rand(min_rand..max_rand)
z = rand(min_rand..max_rand)
radius = rand(min_radius..max_radius)
sphere = self.create_sphere(m_entities, [x,y,z], radius, material)
sphere = self.create_ovoid_sphere(sphere, 20, 40)
sphere = self.displace_sphere(sphere, x_range, y_range, z_range, angle_range)
pid = sphere.persistent_id
eid = sphere.entityID
thing1 = model.find_entity_by_id(pid)
thing2 = model.find_entity_by_id(eid)
print "thing1:", thing1
print "thing2:", thing2
sphere.explode
thing1 = model.find_entity_by_id(pid)
thing2 = model.find_entity_by_id(eid)
print "thing1:", thing1
print "thing2:", thing2
end
model.commit_operation
Sketchup.active_model.active_view.zoom_extents
return master_group
end # end create_cloud
def self.find_faces_to_delete(entity, other_entities, distance)
print "find_faces_to_delete"
model = Sketchup.active_model
entities = model.active_entities
extent = entity.bounds
ctr = extent.center
norm = entity.normal
line = [ ctr, ctr.offset(norm, distance) ]
other_entities.each { |e|
if e.deleted?
print "skipping deleted face", e
next
end
if e.is_a?(Sketchup::Face)
other_face = e
ptinter = Geom.intersect_line_plane(line, other_face.plane)
if ptinter
v = ctr.vector_to(ptinter)
if v % other_face.normal > 0
print "found a face to delete!", other_face
entities.erase_entities([e])
end
end
end
}
end
def self.find_deletable_faces(cloud_group)
model = Sketchup.active_model
model.start_operation("find deletable faces",true,false,true)
print "find things to delete"
entities = cloud_group.entities
print "number of entities to process:", entities.length
entities.each { | entity |
print "entity:", entity
if entity.is_a?(Sketchup::Face)
self.find_faces_to_delete(entity, entities, 100)
end
}
model.active_view.refresh
model.commit_operation
return entities_to_delete
end
def self.intersections(cloud_group)
print "intersections"
model = Sketchup.active_model
model.start_operation("intersect",true,false,true)
eeg = cloud_group.entities
t = Geom::Transformation.new
t2 = Geom::Transformation.new
eeg.intersect_with(false, t, eeg, t2, false, eeg.to_a)
print "done intersecting entities"
model.active_view.refresh
model.commit_operation
end
end
num_spheres = 2
min_radius = 15.0
max_radius = 40.0
min_rand = 1
max_rand = 40
x_range = 750
y_range = 750
z_range = 750
angle_range = 20
cloud_group = Cloud.create_cloud(num_spheres, min_radius, max_radius, min_rand, max_rand, x_range, y_range, z_range, angle_range)
Cloud.intersections(cloud_group)
Cloud.find_deletable_faces(cloud_group)
I wonder if there’s a way to do it with some kind of ray tracing where you only preserve surfaces that the sun hits or something. I don’t know. It’s probably too much for my machine as well!
Thank you
-j_jones