Face not selectable after transform?


#1

See test ruby snippet below which transforms a face (which is positioned at an arbitrary angle in 3D space) so that it is flat on the XY plane at the origin. Everything works as expected except that, after the transform, the face is not selectable(??) Red face on right is a copy in the original position, Left is new position. Edges are still selectable. (White platform is a group and shown for spatial clarity) If I double click an edge the face and all 4 edges select, But I can’t select the face itself. What could cause this? If I save file and reload, then face is selectable.

mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
status = mod.start_operation(“originate”, false)
selface = sel[0]
xyznormal = selface.normal
faceoriginpt = selface.edges[0].start.position
origintrans = self.originate xyznormal, faceoriginpt
ent.transform_entities(origintrans.inverse, selface)
status = mod.commit_operation

Barry Milliken


#2

hm… Got a self-contained snippet to reproduce? I can’t run that snippet because of missing methods:

Error: #<NoMethodError: undefined method `originate' for main:Object>
<main>:7:in `<main>'
SketchUp:1:in `eval'

The example model would be nice as well.


#3

originate.skp (1.2 MB) I’ve uploaded model and here is full code. To run, first select the left red face, then execute.

module Bm_test
	def self.originate(xyznormal, faceoriginpt)
		# rotate face to global XY
		
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection

#normal is the z axis

#define axes of face
# create xaxis vector
ptx = Geom::Point3d.new(1,0,0)
xaxis = Geom::Vector3d.new(1,0,0)
#create yaxis vector first create 2 points
pt0 = Geom::Point3d.new(0,0,0)
pty = Geom::Point3d.new(1,0,0)
cpty = ent.add_cpoint pty
#rotate pty by 90 degrees around normal at pt0 
transz90 = Geom::Transformation.rotation pt0, xyznormal, 90.degrees
ent.transform_entities(transz90, cpty)
pty = cpty.position
# erase const point		
ent.erase_entities cpty
yaxis = Geom::Vector3d.new(pty.to_a)
#=begin
#draw to confirm: omit in final version
		clinex = ent.add_cline pt0, ptx
		cptx = ent.add_cpoint ptx
		cliney = ent.add_cline pt0, pty
		cpty = ent.add_cpoint pty
		ptz = Geom::Point3d.new(xyznormal.to_a)
		clinez = ent.add_cline pt0, ptz
		cptz = ent.add_cpoint ptz
#=end

#use start position of face as rotation point
origintrans = Geom::Transformation.axes faceoriginpt, xaxis, yaxis, xyznormal

return origintrans

	end #def
	
	#test: for one selected face

	mod = Sketchup.active_model # Open model
	ent = mod.entities # All entities in model
	sel = mod.selection # Current selection
	status = mod.start_operation("originate", false)	
	selface = sel[0]	
	xyznormal = selface.normal
	faceoriginpt = selface.edges[0].start.position
	origintrans = self.originate xyznormal, faceoriginpt	
	ent.transform_entities(origintrans.inverse, selface)
	#ent.transform_entities(origintrans, selface)
	status = mod.commit_operation	
	
end #module

#4

It seems # in first position creates headings(??) so here’s another try:

module Bm_test
	def self.originate(xyznormal, faceoriginpt)
		# rotate face to global XY
		
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection

 #normal is the z axis

 #define axes of face
 # create xaxis vector
ptx = Geom::Point3d.new(1,0,0)
xaxis = Geom::Vector3d.new(1,0,0)
 #create yaxis vector first create 2 points
pt0 = Geom::Point3d.new(0,0,0)
pty = Geom::Point3d.new(1,0,0)
cpty = ent.add_cpoint pty
 #rotate pty by 90 degrees around normal at pt0 
transz90 = Geom::Transformation.rotation pt0, xyznormal, 90.degrees
ent.transform_entities(transz90, cpty)
pty = cpty.position
 # erase const point		
ent.erase_entities cpty
yaxis = Geom::Vector3d.new(pty.to_a)
 #=begin
 #draw to confirm: omit in final version
		clinex = ent.add_cline pt0, ptx
		cptx = ent.add_cpoint ptx
		cliney = ent.add_cline pt0, pty
		cpty = ent.add_cpoint pty
		ptz = Geom::Point3d.new(xyznormal.to_a)
		clinez = ent.add_cline pt0, ptz
		cptz = ent.add_cpoint ptz
 #=end

 #use start position of face as rotation point
origintrans = Geom::Transformation.axes faceoriginpt, xaxis, yaxis, xyznormal

return origintrans

	end #def
	
	#test: for one selected face

	mod = Sketchup.active_model # Open model
	ent = mod.entities # All entities in model
	sel = mod.selection # Current selection
	status = mod.start_operation("originate", false)	
	selface = sel[0]	
	xyznormal = selface.normal
	faceoriginpt = selface.edges[0].start.position
	origintrans = self.originate xyznormal, faceoriginpt	
	ent.transform_entities(origintrans.inverse, selface)
	#ent.transform_entities(origintrans, selface)
	status = mod.commit_operation	
	
end #module

#5

I see I made a mistake where the 3 axes I passed to Geom::Transformation.axes are not actually perpendicular to each other. Apparently that method doesn’t check for that problem, resulting in a warped face?


#6

Yes, SketchUp allows you to create a skewed Transformation.


#7

Barry - I edited your posts so that your code snippets properly formats.

Easy to create non-orthogonal transformations with the Scale tool as well - it’s a valid scenario: