How do I 'hold on' to a vertex when scripting with Ruby?


#1

Hello!

I have a model, which I want to modify by applying transformations to its vertices. I iterate through its faces[] array.

After some first modifications, new faces appear, and so on. This means that some of the old faces get deleted, and I have a hard time ‘finding’ them in the array afterwards. (I use the following hack: I apply unique colors to them before transforming anything at all, then I look for the unique colors to find them again. It’s working well.)

Unfortunately, the faces seem to be rotated (or flipped?) after some other transformations to the model have been applied - face.vertices[1] is then in the bottom left corner, even though it was top right before.

Is there anything I can do to ‘hold on’ to the top right vertex of a face, even though the face might be indirectly affected by other transformations I apply to the model?

My faces are arranged in a circular way, so it’s a bit hard to simply compare their positions.

Greetings, and thanks!
Fabian


#2

In order to account for AutoFold splitting faces I’d use attributes instead of materials to keep track of your faces.

When you modify a face’s vertices so that they are not co-planar any more SketchUp’s AutoFold kicks in an tessellates the face - creating new faces. The order of the data cannot be expected to be preserved.

Can you elaborate what you mean by holding on to? Transient? Persistent? You can get a reference to the vertices before you transform, and even if AutoFold kicks in I think (note think) they persist.

Maybe we can approach this a different way. You ask for holding on to vertices for some reason, though it’s not clear to me exactly why or how you expect this to be. Maybe if we step back and look at the broader picture of what you are trying to do? Maybe you can include some screenshot of what geometry you have and have you are trying to achieve? Maybe even a sample model?


#3

Hi Thomas,

thanks for your help! I did some further experimentation, yet I did not manage to solve my initial problem. Here is what I want to do:

I have an array of values (in my case, they’re ratings). Iterating through this array, I want to deform a donut-shaped model - a data-deformed sculpture, showing the ‘ups and downs’ in the ratings.

This is what I created in the first place:

#Code Example 1

Sketchup.file_new

model = Sketchup.active_model
entities = model.active_entities

model.active_entities.clear!

diameter  = 24.cm
thickness = 2.cm
height    = 4.cm

steps       = 12
radius      = diameter/2.0
base_points = Array.new
hole_points = Array.new

ratings1 = [7,2,7,4,5,6,7,8,9,7,2,3]
ratings2 = [6,4,7,7,3,7,9,7,3,8,6,7]


def month_face1 (entities, month)
	if defined? entities[month].faces
		entities[month].faces[1]
	end
end

def month_face2 (entities, month)
	if month==0 
		month = 12
	end

	if defined? entities[month-1].faces
		entities[month-1].faces[1]
	end
end

def rating1_vertex (face)
	face.vertices[2]
end

def rating2_vertex (face)
	face.vertices[2]
end



for step in 1..steps

	x = (radius+thickness) * Math.sin(2 * Math::PI * (step / steps.to_f))
	y = (radius+thickness) * Math.cos(2 * Math::PI * (step / steps.to_f))

	base_points << [x, y,  0]

end

for step in 1..steps

	x = radius * Math.sin(2 * Math::PI * (step / steps.to_f))
	y = radius * Math.cos(2 * Math::PI * (step / steps.to_f))

	hole_points << [x, y,  0]

end



top = entities.add_group

top_base = top.entities.add_face base_points
top_hole = top.entities.add_face hole_points
top_base.pushpull(-height/2.0, true)
top_hole.erase!

bottom = entities.add_group

bottom_base = bottom.entities.add_face base_points
bottom_hole = bottom.entities.add_face hole_points
bottom_base.pushpull(height/2.0, true)
bottom_hole.erase!


top.entities.each do |entity|
	if defined? entity.faces
		entity.faces.each do |face|
		#	face.material = [255, 0, 0]
		end
	end
end

for month in 0...steps

	puts "#{month} #{ratings2[month]}"

	edge1 = month_face1(top.entities, month)
	if edge1 != nil
		#edge1.material = [155, 20*month, 0]
		t1 = Geom::Transformation.new([0,0,-((10-ratings1[month]).to_f/10.0+month/50.0)*height.to_f/3.0])
		entities.transform_entities(t1, rating1_vertex(edge1) )
	end

	edge2 = month_face2(bottom.entities, month)
	if edge2 != nil
		#edge2.material = [0, 100, 20*month]
		t2 = Geom::Transformation.new([0,0,+((10-ratings2[month]).to_f/10.0+month/50.0)*height.to_f/3.0])
		entities.transform_entities(t2, rating2_vertex(edge2) )
	end

end

This one works - so far, so good. If you change the values in the ratings array, the sculpture gets adjusted accordingly.

However, the hole in the middle needs to be really round, which made things a whole lot more complicated. I also wanted to chamfer the edges a bit, so I came up with this:

# Code Example 2

model = Sketchup.active_model
entities = model.active_entities

model.active_entities.clear!

diameter  = 24.cm
thickness = 2.cm
height    = 4.cm

steps        = 12
circle_steps = 365
radius       = diameter/2.0
base_points  = Array.new
hole_points  = Array.new

ratings1 = [1,2,3,4,5,6,7,8,9,8,7,6]


def month_face (entities, month)
# Find the face that corresponds to a month by its color.

	targetColor = Sketchup::Color.new(0, 255, month*20)
	
	faces = []
	entities.each do |entity|  
		if entity.is_a? Sketchup::Face
			if entity.material != nil 
				if entity.material.color.to_i == targetColor.to_i
					# If the face's color matches the target color: that's what we're looking for.
					return entity
				end
			end
		end
	end

	return nil

end


# Construct the basic shape.

for step in 1..steps

	x = (radius+thickness) * Math.sin(2 * Math::PI * (step / steps.to_f))
	y = (radius+thickness) * Math.cos(2 * Math::PI * (step / steps.to_f))

	base_points << [x, y,  0]

end

# Construct the hole in the middle (for later).

for step in 1..circle_steps

	x = (radius) * Math.sin(2 * Math::PI * (step / circle_steps.to_f))
	y = (radius) * Math.cos(2 * Math::PI * (step / circle_steps.to_f))

	hole_points << [x, y,  0]

end


edge_tapering = 0.96

edge_height = height*0.2
body_height = height*0.8


ring = entities.add_group
shape = ring.entities.add_face base_points # Start with the basic shape

normal_transformation = Geom::Transformation.scaling 1

edge_tapering_transformation = Geom::Transformation.scaling edge_tapering
entities.transform_entities(edge_tapering_transformation, shape)

shape.pushpull(edge_height, true)

faces = []
ring.entities.each do |e|
	if e.is_a? Sketchup::Face
		faces << e
	end
end
extrusionFace = faces[1]

undo_edge_tapering_transformation = edge_tapering_transformation.inverse
entities.transform_entities(undo_edge_tapering_transformation, extrusionFace)

extrusionFace.pushpull(body_height, false)

faces = []
ring.entities.each do |e|
	if e.is_a? Sketchup::Face
		faces << e
	end
end

extrusionFace = faces[13]
entities.transform_entities(normal_transformation, extrusionFace)

extrusionFace.pushpull(edge_height, true)


faces = []
ring.entities.each do |e|
	if e.is_a? Sketchup::Face
		faces << e
	end
end

extrusionFace = faces[26]

entities.transform_entities(edge_tapering_transformation, extrusionFace)

shape = ring.entities.add_face hole_points
shape.pushpull(ring.local_bounds.depth)


faces = []
ring.entities.each do |e|
	if e.is_a? Sketchup::Face
		faces << e
	end
end

faces[13].erase! # Remove the hole

ring.explode

faces = []
entities.each do |e|  
	if e.is_a? Sketchup::Face
		faces << e
	end
end


# Label the vertices:

for month in 0..11

	face = faces[12+month]
	face.material = [0, 255, month*20] # This works correctly: the colors' blue value increases around the donut.

	if (false) 

		rating1_vertex(face).set_attribute "diary_points", "month", month
		rating1_vertex(face).set_attribute "diary_points", "rating", 1

		rating2_vertex(face).set_attribute "diary_points", "month", month
		rating2_vertex(face).set_attribute "diary_points", "rating", 2

	end

end

# Transform the donut:

	for month in 0...steps

		face = month_face(entities, month) 

		if face != nil

			t1 = Geom::Transformation.new([0,0,+((10-ratings1[month]).to_f/10.0+month/50.0)*height.to_f/3.0])
			t1 = Geom::Transformation.new([0,0,-0.3])

			# Apply the transformation, created from ratings1[month], to the top-left-most (viewed from the outside) vertex of the month's face
			# vertex = ?

			#entities.transform_entities(t1, vertex)

			# Apply the same thing from ratings2[] to the bottom side. (Same problem - I can't find the correct vertex.) 
			#t2 = Geom::Transformation.new([0,0,-((10-ratings2[month]).to_f/10.0+month/50.0)*height.to_f/3.0])

		end



end

Code Example 2 creates a nice shape, but tesselating seems to scramble the vertices, so I have a hard time to determine the correct one to move, according to the ratings array. When I save references to them in the first place, I often get errors á la “You’re trying to refer to a deleted Entity”, which - I assume - is because of AutoFold?

Also, I observed that the tapered edges at the donut’s top and bottom are of different size (even though both are set to 0.2*height) - is that because I apply a transformation to them?

Lastly, both these examples actually make Sketchup crash (I’m on OSX) when I run them 2-3 times. Am I doing something structurally wrong in the code?

Greetings, and thanks again!
Fabian


#4

Hello! And thank you for your help so far. I did some further experimentation, however, I was unable to achieve what I wanted to do.

Overall, what I am trying to achieve is a data-deformed sculpture. I have an array (“ratings”), which I want to use to deform a donut-shaped sculpture. Here is what I created in the first place:

# Code example 1


model = Sketchup.active_model
entities = model.active_entities

model.active_entities.clear!

diameter  = 24.cm
thickness = 2.cm
height    = 4.cm

steps        = 12
circle_steps = 365
radius       = diameter/2.0
base_points  = Array.new
hole_points  = Array.new

ratings1 = [1,2,3,4,5,6,7,8,9,8,7,6]


def month_face (entities, month)
# Find the face that corresponds to a month by its color.

	targetColor = Sketchup::Color.new(0, 255, month*20)
	
	faces = []
	entities.each do |entity|  
		if entity.is_a? Sketchup::Face
			if entity.material != nil 
				if entity.material.color.to_i == targetColor.to_i
					# If the face's color matches the target color: that's what we're looking for.
					return entity
				end
			end
		end
	end

	return nil

end


# Construct the basic shape.

for step in 1..steps

	x = (radius+thickness) * Math.sin(2 * Math::PI * (step / steps.to_f))
	y = (radius+thickness) * Math.cos(2 * Math::PI * (step / steps.to_f))

	base_points << [x, y,  0]

end

# Construct the hole in the middle (for later).

for step in 1..circle_steps

	x = (radius) * Math.sin(2 * Math::PI * (step / circle_steps.to_f))
	y = (radius) * Math.cos(2 * Math::PI * (step / circle_steps.to_f))

	hole_points << [x, y,  0]

end


edge_tapering = 0.96

edge_height = height*0.2
body_height = height*0.8


ring = entities.add_group
shape = ring.entities.add_face base_points # Start with the basic shape

normal_transformation = Geom::Transformation.scaling 1

edge_tapering_transformation = Geom::Transformation.scaling edge_tapering
entities.transform_entities(edge_tapering_transformation, shape)

shape.pushpull(edge_height, true)

faces = []
ring.entities.each do |e|
	if e.is_a? Sketchup::Face
		faces << e
	end
end
extrusionFace = faces[1]

undo_edge_tapering_transformation = edge_tapering_transformation.inverse
entities.transform_entities(undo_edge_tapering_transformation, extrusionFace)

extrusionFace.pushpull(body_height, false)

faces = []
ring.entities.each do |e|
	if e.is_a? Sketchup::Face
		faces << e
	end
end

extrusionFace = faces[13]
entities.transform_entities(normal_transformation, extrusionFace)

extrusionFace.pushpull(edge_height, true)


faces = []
ring.entities.each do |e|
	if e.is_a? Sketchup::Face
		faces << e
	end
end

extrusionFace = faces[26]

entities.transform_entities(edge_tapering_transformation, extrusionFace)

shape = ring.entities.add_face hole_points
shape.pushpull(ring.local_bounds.depth)


faces = []
ring.entities.each do |e|
	if e.is_a? Sketchup::Face
		faces << e
	end
end

faces[13].erase! # Remove the hole

ring.explode

faces = []
entities.each do |e|  
	if e.is_a? Sketchup::Face
		faces << e
	end
end


# Label the vertices:

for month in 0..11

	face = faces[12+month]
	face.material = [0, 255, month*20] # This works correctly: the colors' blue value increases around the donut.

	if (false) 

		rating1_vertex(face).set_attribute "diary_points", "month", month
		rating1_vertex(face).set_attribute "diary_points", "rating", 1

		rating2_vertex(face).set_attribute "diary_points", "month", month
		rating2_vertex(face).set_attribute "diary_points", "rating", 2

	end

end

# Transform the donut:

	for month in 0...steps

		face = month_face(entities, month) 

		if face != nil

			t1 = Geom::Transformation.new([0,0,+((10-ratings1[month]).to_f/10.0+month/50.0)*height.to_f/3.0])
			t1 = Geom::Transformation.new([0,0,-0.3])

			# Apply the transformation, created from ratings1[month], to the top-left-most (viewed from the outside) vertex of the month's face
			# vertex = ?

			#entities.transform_entities(t1, vertex)

			# Apply the same thing from ratings2[] to the bottom side. (Same problem - I can't find the correct vertex.) 
			#t2 = Geom::Transformation.new([0,0,-((10-ratings2[month]).to_f/10.0+month/50.0)*height.to_f/3.0])

		end

end

… and it works pretty well! If you change the values in the ratings array, the shape gets deformed accordingly. Great! However, the hole in the middle needs to be really round - and that started to make things a whole lot more complicated:

# Code example 2
model = Sketchup.active_model
entities = model.active_entities

model.active_entities.clear!

diameter  = 24.cm
thickness = 2.cm
height    = 4.cm

steps        = 12
circle_steps = 365
radius       = diameter/2.0
base_points  = Array.new
hole_points  = Array.new

ratings1 = [1,2,3,4,5,6,7,8,9,8,7,6]


def month_face (entities, month)
# Find the face that corresponds to a month by its color.

	targetColor = Sketchup::Color.new(0, 255, month*20)
	
	faces = []
	entities.each do |entity|  
		if entity.is_a? Sketchup::Face
			if entity.material != nil 
				if entity.material.color.to_i == targetColor.to_i
					# If the face's color matches the target color: that's what we're looking for.
					return entity
				end
			end
		end
	end

	return nil

end


# Construct the basic shape.

for step in 1..steps

	x = (radius+thickness) * Math.sin(2 * Math::PI * (step / steps.to_f))
	y = (radius+thickness) * Math.cos(2 * Math::PI * (step / steps.to_f))

	base_points << [x, y,  0]

end

# Construct the hole in the middle (for later).

for step in 1..circle_steps

	x = (radius) * Math.sin(2 * Math::PI * (step / circle_steps.to_f))
	y = (radius) * Math.cos(2 * Math::PI * (step / circle_steps.to_f))

	hole_points << [x, y,  0]

end


edge_tapering = 0.96

edge_height = height*0.2
body_height = height*0.8


ring = entities.add_group
shape = ring.entities.add_face base_points # Start with the basic shape

normal_transformation = Geom::Transformation.scaling 1

edge_tapering_transformation = Geom::Transformation.scaling edge_tapering
entities.transform_entities(edge_tapering_transformation, shape)

shape.pushpull(edge_height, true)

faces = []
ring.entities.each do |e|
	if e.is_a? Sketchup::Face
		faces << e
	end
end
extrusionFace = faces[1]

undo_edge_tapering_transformation = edge_tapering_transformation.inverse
entities.transform_entities(undo_edge_tapering_transformation, extrusionFace)

extrusionFace.pushpull(body_height, false)

faces = []
ring.entities.each do |e|
	if e.is_a? Sketchup::Face
		faces << e
	end
end

extrusionFace = faces[13]
entities.transform_entities(normal_transformation, extrusionFace)

extrusionFace.pushpull(edge_height, true)


faces = []
ring.entities.each do |e|
	if e.is_a? Sketchup::Face
		faces << e
	end
end

extrusionFace = faces[26]

entities.transform_entities(edge_tapering_transformation, extrusionFace)

shape = ring.entities.add_face hole_points
shape.pushpull(ring.local_bounds.depth)


faces = []
ring.entities.each do |e|
	if e.is_a? Sketchup::Face
		faces << e
	end
end

faces[13].erase! # Remove the hole

ring.explode

faces = []
entities.each do |e|  
	if e.is_a? Sketchup::Face
		faces << e
	end
end


# Label the vertices:

for month in 0..11

	face = faces[12+month]
	face.material = [0, 255, month*20] # This works correctly: the colors' blue value increases around the donut.

	if (false) 

		rating1_vertex(face).set_attribute "diary_points", "month", month
		rating1_vertex(face).set_attribute "diary_points", "rating", 1

		rating2_vertex(face).set_attribute "diary_points", "month", month
		rating2_vertex(face).set_attribute "diary_points", "rating", 2

	end

end

# Transform the donut:

	for month in 0...steps

		face = month_face(entities, month) 

		if face != nil

			t1 = Geom::Transformation.new([0,0,+((10-ratings1[month]).to_f/10.0+month/50.0)*height.to_f/3.0])
			t1 = Geom::Transformation.new([0,0,-0.3])

			# Apply the transformation, created from ratings1[month], to the top-left-most (viewed from the outside) vertex of the month's face
			# vertex = ?

			#entities.transform_entities(t1, vertex)

			# Apply the same thing from ratings2[] to the bottom side. (Same problem - I can't find the correct vertex.) 
			#t2 = Geom::Transformation.new([0,0,-((10-ratings2[month]).to_f/10.0+month/50.0)*height.to_f/3.0])

		end

end

In this one, I have a hard time finding the correct vertices to move - if I save references to them, I often get errors a la “You are trying to refer to a deleted Entity.”.

I also chamfer the donut’s edges in this one - however, I noticed that the edges’ heights are different. Is that because I apply a transformation to them? Both should be equal (0.2*height), but the top one is bigger.

Also, my script makes Sketchup crash quite often. Am I doing things structurally wrong?

If it’s easier (less tesselating?), an option could be to make a disc object, deform it, and then pushpull a hole into the middle of it. I’m not sure that this would solve my problem, though.

Again, thanks for all your help!
Fabian

(I’m not sure if my previous reply got uploaded, so I’m writing it again - I hope this doesn’t apply twice.)


#5

Hello! And thank you for your help so far. I did some further
experimentation, however, I was unable to achieve what I wanted to do.

Overall, what I am trying to achieve is a data-deformed sculpture. I have
an array (“ratings”), which I want to use to deform a donut-shaped
sculpture. Here is what I created in the first place:

	Sketchup.file_new

	model = Sketchup.active_model
	entities = model.active_entities

	model.active_entities.clear!

	diameter  = 24.cm
	thickness = 2.cm
	height    = 4.cm

	steps       = 12
	radius      = diameter/2.0
	base_points = Array.new
	hole_points = Array.new

	ratings1 = [7,2,7,4,5,6,7,8,9,7,2,3]
	ratings2 = [6,4,7,7,3,7,9,7,3,8,6,7]


	def month_face1 (entities, month)
		if defined? entities[month].faces
			entities[month].faces[1]
		end
	end

	def month_face2 (entities, month)
		if month==0 
			month = 12
		end

		if defined? entities[month-1].faces
			entities[month-1].faces[1]
		end
	end

	def rating1_vertex (face)
		face.vertices[2]
	end

	def rating2_vertex (face)
		face.vertices[2]
	end



	for step in 1..steps

		x = (radius+thickness) * Math.sin(2 * Math::PI * (step / steps.to_f))
		y = (radius+thickness) * Math.cos(2 * Math::PI * (step / steps.to_f))

		base_points << [x, y,  0]

	end

	for step in 1..steps

		x = radius * Math.sin(2 * Math::PI * (step / steps.to_f))
		y = radius * Math.cos(2 * Math::PI * (step / steps.to_f))

		hole_points << [x, y,  0]

	end



	top = entities.add_group

	top_base = top.entities.add_face base_points
	top_hole = top.entities.add_face hole_points
	top_base.pushpull(-height/2.0, true)
	top_hole.erase!

	bottom = entities.add_group

	bottom_base = bottom.entities.add_face base_points
	bottom_hole = bottom.entities.add_face hole_points
	bottom_base.pushpull(height/2.0, true)
	bottom_hole.erase!


	top.entities.each do |entity|
		if defined? entity.faces
			entity.faces.each do |face|
			#	face.material = [255, 0, 0]
			end
		end
	end

	for month in 0...steps

		puts "#{month} #{ratings2[month]}"

		edge1 = month_face1(top.entities, month)
		if edge1 != nil
			#edge1.material = [155, 20*month, 0]
			t1 = Geom::Transformation.new([0,0,-((10-ratings1[month]).to_f/10.0+month/50.0)*height.to_f/3.0])
			entities.transform_entities(t1, rating1_vertex(edge1) )
		end

		edge2 = month_face2(bottom.entities, month)
		if edge2 != nil
			#edge2.material = [0, 100, 20*month]
			t2 = Geom::Transformation.new([0,0,+((10-ratings2[month]).to_f/10.0+month/50.0)*height.to_f/3.0])
			entities.transform_entities(t2, rating2_vertex(edge2) )
		end

	end

… and it works pretty well! If you change the values in the ratings
array, the shape gets deformed accordingly. Great! However, the hole in the
middle needs to be really round - and that started to make things a whole
lot more complicated:

	model = Sketchup.active_model
	entities = model.active_entities

	model.active_entities.clear!

	diameter  = 24.cm
	thickness = 2.cm
	height    = 4.cm

	steps        = 12
	circle_steps = 365
	radius       = diameter/2.0
	base_points  = Array.new
	hole_points  = Array.new

	ratings1 = [1,2,3,4,5,6,7,8,9,8,7,6]


	def month_face (entities, month)
	# Find the face that corresponds to a month by its color.

		targetColor = Sketchup::Color.new(0, 255, month*20)
		
		faces = []
		entities.each do |entity|  
			if entity.is_a? Sketchup::Face
				if entity.material != nil 
					if entity.material.color.to_i == targetColor.to_i
						# If the face's color matches the target color: that's what we're looking for.
						return entity
					end
				end
			end
		end

		return nil

	end


	# Construct the basic shape.

	for step in 1..steps

		x = (radius+thickness) * Math.sin(2 * Math::PI * (step / steps.to_f))
		y = (radius+thickness) * Math.cos(2 * Math::PI * (step / steps.to_f))

		base_points << [x, y,  0]

	end

	# Construct the hole in the middle (for later).

	for step in 1..circle_steps

		x = (radius) * Math.sin(2 * Math::PI * (step / circle_steps.to_f))
		y = (radius) * Math.cos(2 * Math::PI * (step / circle_steps.to_f))

		hole_points << [x, y,  0]

	end


	edge_tapering = 0.96

	edge_height = height*0.2
	body_height = height*0.8


	ring = entities.add_group
	shape = ring.entities.add_face base_points # Start with the basic shape

	normal_transformation = Geom::Transformation.scaling 1

	edge_tapering_transformation = Geom::Transformation.scaling edge_tapering
	entities.transform_entities(edge_tapering_transformation, shape)

	shape.pushpull(edge_height, true)

	faces = []
	ring.entities.each do |e|
		if e.is_a? Sketchup::Face
			faces << e
		end
	end
	extrusionFace = faces[1]

	undo_edge_tapering_transformation = edge_tapering_transformation.inverse
	entities.transform_entities(undo_edge_tapering_transformation, extrusionFace)

	extrusionFace.pushpull(body_height, false)

	faces = []
	ring.entities.each do |e|
		if e.is_a? Sketchup::Face
			faces << e
		end
	end

	extrusionFace = faces[13]
	entities.transform_entities(normal_transformation, extrusionFace)

	extrusionFace.pushpull(edge_height, true)


	faces = []
	ring.entities.each do |e|
		if e.is_a? Sketchup::Face
			faces << e
		end
	end

	extrusionFace = faces[26]

	entities.transform_entities(edge_tapering_transformation, extrusionFace)

	shape = ring.entities.add_face hole_points
	shape.pushpull(ring.local_bounds.depth)


	faces = []
	ring.entities.each do |e|
		if e.is_a? Sketchup::Face
			faces << e
		end
	end

	faces[13].erase! # Remove the hole

	ring.explode

	faces = []
	entities.each do |e|  
		if e.is_a? Sketchup::Face
			faces << e
		end
	end


	# Label the vertices:

	for month in 0..11

		face = faces[12+month]
		face.material = [0, 255, month*20] # This works correctly: the colors' blue value increases around the donut.

		if (false) 

			rating1_vertex(face).set_attribute "diary_points", "month", month
			rating1_vertex(face).set_attribute "diary_points", "rating", 1

			rating2_vertex(face).set_attribute "diary_points", "month", month
			rating2_vertex(face).set_attribute "diary_points", "rating", 2

		end

	end

	# Transform the donut:

		for month in 0...steps

			face = month_face(entities, month) 

			if face != nil

				t1 = Geom::Transformation.new([0,0,+((10-ratings1[month]).to_f/10.0+month/50.0)*height.to_f/3.0])
				t1 = Geom::Transformation.new([0,0,-0.3])

				# Apply the transformation, created from ratings1[month], to the top-left-most (viewed from the outside) vertex of the month's face
				# vertex = ?

				#entities.transform_entities(t1, vertex)

				# Apply the same thing from ratings2[] to the bottom side. (Same problem - I can't find the correct vertex.) 
				#t2 = Geom::Transformation.new([0,0,-((10-ratings2[month]).to_f/10.0+month/50.0)*height.to_f/3.0])

			end



	end

In this one, I have a hard time finding the correct vertices to move - if I
save references to them, I often get errors a la “You are trying to refer
to a deleted Entity.”.

I also chamfer the donut’s edges in this one - however, I noticed that the
edges’ heights are different. Is that because I apply a transformation to
them? Both should be equal (0.2*height), but the top one is bigger.

Also, my script makes Sketchup crash quite often. Am I doing things
structurally wrong?

If it’s easier (less tesselating?), an option could be to make a disc
object, deform it, and then pushpull a hole into the middle of it. I’m not
sure that this would solve my problem, though.

Again, thanks for all your help!
Fabian


#6

Oh - now that’s interesting. What version of SketchUp and what OS? Did you submit the BugSplats? Did you enter any info I use to look up the crash data?


#7

I’m scanning over you script. (The last code block you posted.) I ran it in SU2015 and it ran without errors.
What I did notice was that you are generating rather small geometry. The inner circle has edges of 2mm. Now, that should still be fine - but beware that you are close to SketchUp’s tolerance. When two points are 1/1000" apart SketchUp consider them to be the same. So if you create things much smaller than 1mm-ish you will quickly start to find tolerance issues where faces and edges will merge when you don’t really intend to.
Currently the only workaround for this is to create the geometry 10 or 100 times larger - then you counter-scale the instance. This means that the component definition and the actual geometry it at larger scale, but the instance representation is in 1:1 scale.


#8

Ok, I ran into the crash myself now, with the first code segment. Looking into that. Initial thing I see is that it happens with Entities.transform_entities.

In the second one, I couldn’t see any effect on adjusting the ratings. Got any examples?

Do you have an example of the final result you try to produce?