# Is there a way to find faces found in a z range?

Is there a way to make this only find the faces that have a z value between 0.5 and 90?

issue

``````zface = cabinet.entities.find {|ent| ent.is_a?(Sketchup::Face) &&    ent.normal == [0, 0, 1]}
``````

main code

``````SKETCHUP_CONSOLE.clear
# Default code, use or delete...
mod = Sketchup.active_model # Open model
ents = mod.entities # All entities in model
sel = mod.selection # Current selection

o_width= 26.0 # outer width
o_depth= 24.25 # inner depth

i_width= 22.0 # inner width
i_depth= 23.25 # inner depth

top_opening_width = 18.75
top_opening_depth = 0.5

bottom_opening_width = top_opening_width
bottom_opening_depth = top_opening_depth

top_height= 29 # height of top cavity
bottom_height = 60 # height of bottom cavity

top_opening_height = 26.5
bottom_opening_height = 59.5

cabinet_height = 94
def upright(face)
if face.normal.z == -1
face.reverse!
end
end

pts=[0,0,0],[0,o_depth,0],[o_width,o_depth,0],[o_width,0,0]
# create substrate
cabinet = ents.add_group # add substrate group
#cabinet.name = "cabinet" # name substrate group
cabinet_face = cabinet.entities.add_face pts
upright(cabinet_face)
cabinet_face.pushpull cabinet_height

offset_x = (o_width-i_width) / 2
offset_y = (o_depth-i_depth) / 2

pts=[0,0,0],[0,i_depth,0],[i_width,i_depth,0],[i_width,0,0]
vector_bottom=Geom::Vector3d.new(offset_x,offset_y,3.5)
vector_top = Geom::Vector3d.new(offset_x,offset_y,64)

#bottom_main.name= "bottom_main"
bottom_face = bottom_main.entities.add_face pts.map{|pt| Geom::Point3d.new(pt)+vector_bottom}
upright(bottom_face)
bottom_face.pushpull bottom_height

#top_main.name= "top_main"
top_face = top_main.entities.add_face pts.map{|pt| Geom::Point3d.new(pt)+vector_top}
upright(top_face)
top_face.pushpull top_height

# small jutting peice
w = 1
d = 2.5
pts=[0,0,0],[0,d,0],[w,d,0],[w,0,0]
jut_vector = Geom::Vector3d.new(offset_x,offset_y,0)
jutting_face = jutting_peice.entities.add_face pts.map{|pt| Geom::Point3d.new(pt)+jut_vector}
upright(jutting_face)
jutting_face.pushpull cabinet_height

pts=[0,0,0],[0,top_opening_depth,0],[top_opening_width,top_opening_depth,0],[top_opening_width,0,0]
offset_x= 4
vector_top = Geom::Vector3d.new(offset_x,0,64)
#top_opening.name= "top_opening"
top_face2 = top_opening.entities.add_face pts.map{|pt| Geom::Point3d.new(pt)+vector_top}
upright(top_face2)
top_face2.pushpull top_opening_height

vector_bottom=Geom::Vector3d.new(offset_x,0,3.5)
#bottom_opening.name= "bottom_opening"
bottom_face2 = bottom_opening.entities.add_face pts.map{|pt| Geom::Point3d.new(pt)+vector_bottom}
upright(bottom_face2)
bottom_face2.pushpull bottom_opening_height

bottom = bottom_opening.union(bottom_main)
#bottom.name = "bottom"
top = top_opening.union(top_main)
#top.name = "top"
cabinet = top.subtract(cabinet)
cabinet = bottom.subtract(cabinet)
cabinet = cabinet.union(jutting_peice)
cabinet.name = "cabinet"
cabinet.material = "blue"
# find a face in the cabinet
zface = cabinet.entities.find {|ent| ent.is_a?(Sketchup::Face) &&    ent.normal == [0, 0, 1]}

# get the points from the face.
pts = zface.vertices.uniq.map(&:position)

shelf_face = shelf.entities.add_face pts
upright(shelf_face)
shelf_face.pushpull 0.5
new_transform = Geom::Transformation.new([0,0,12])
shelf.transformation = new_transform
shelf_copy = shelf.parent.entities.add_instance(shelf.definition, shelf.transformation)
``````

(A small note: the `.find` is give only one ( the first ) face which fulfill the condition.
If you want to get array of all possible faces therefore `.find_all` should be usedâ€¦)
.
To get faces that have a z value between 0.5 and 90, You need to
#1 find one of the vertices of face:

e.g. :
``````  vertex = face.vertices[0]
``````

#2 Then you need to get this vertex position:

e.g. :
``````  position = vertex.position
``````

#3 Then you need to get this point z coordinate:

(Note that the above documentation for Point3d is wrong: z = point.x >> z = point.z )
e.g. :
``````  value_z = position.z
``````

Then you can make a condition about `value_z`â€¦
So. e.g. the additional conditions can be something like this:

``````  ent.vertices[0].position.z>0.5 && ent.vertices[0].position.z<90.0

``````

You might also use the `#between?` method.

``````faces = cabinet.entities.grep(Sketchup::Face)
zface = faces.find {|face| face.normal.z.between?(0.5, 90.0) }
``````

`#between?` uses a comparable classâ€™ `#<=>` method which the SketchUp API defines especially for the `Length` class to do comparisons within SketchUpâ€™s internal tolerance. (Ie, `Geom::Vector3d#z` returns a `Length` class object.)

You also do not need to create extra literal vector arrays for the common model axes, like `[0, 0, 1]` because they are already defined globally as `X_AXIS`, `Y_AXIS` and `Z_AXIS`. (See the API doc page for the constants defined in the TopLevel Namespace.)

Also beware that because SketchUp uses floating point representation for numbers, exact comparison of values is risky. Iâ€™ve even found an example some years ago in which y=x, y==x failed because one of values had been saved out of the floating point accelerator (80-bit) into an ordinary register (64-bit) and lost trailing bits! I had quite an argument with a Microsoft engineer over whether that was a semantic failure in their compiler (my opinion) vs an acceptable floating point behavior (his opinion). Thatâ€™s the reason why many SketchUp Ruby API classes have their own comparison operators that include a tolerance.

1 Like

Thanks, I figured it out with your suggestion. I was trying to grab the points from the face at the bottom and use those to make shelves.

``````SKETCHUP_CONSOLE.clear
# Default code, use or delete...
mod = Sketchup.active_model # Open model
ents = mod.entities # All entities in model
sel = mod.selection # Current selection

o_width= 26.0 # outer width
o_depth= 24.25 # inner depth

i_width= 22.0 # inner width
i_depth= 23.25 # inner depth

top_opening_width = 18.75
top_opening_depth = 0.5
top_opening_height = 26.5

bottom_opening_width = top_opening_width
bottom_opening_depth = top_opening_depth
bottom_opening_height = 59.5

top_height= 29 # height of top cavity
bottom_height = 60 # height of bottom cavity

cabinet_height = 94
def upright(face)
if face.normal.z == -1
face.reverse!
end
end

pts=[0,0,0],[0,o_depth,0],[o_width,o_depth,0],[o_width,0,0]
# create substrate
cabinet = ents.add_group # add substrate group
#cabinet.name = "cabinet" # name substrate group
cabinet_face = cabinet.entities.add_face pts
upright(cabinet_face)
cabinet_face.pushpull cabinet_height

offset_x = (o_width-i_width) / 2
offset_y = (o_depth-i_depth) / 2

pts=[0,0,0],[0,i_depth,0],[i_width,i_depth,0],[i_width,0,0]
vector_bottom=Geom::Vector3d.new(offset_x,offset_y,3.5)
vector_top = Geom::Vector3d.new(offset_x,offset_y,64)

#bottom_main.name= "bottom_main"
bottom_face = bottom_main.entities.add_face pts.map{|pt| Geom::Point3d.new(pt)+vector_bottom}
upright(bottom_face)
bottom_face.pushpull bottom_height

#top_main.name= "top_main"
top_face = top_main.entities.add_face pts.map{|pt| Geom::Point3d.new(pt)+vector_top}
upright(top_face)
top_face.pushpull top_height

# small jutting peice
w = 1
d = 2.5
pts=[0,0,0],[0,d,0],[w,d,0],[w,0,0]
jut_vector = Geom::Vector3d.new(offset_x,offset_y,0)
jutting_face = jutting_peice.entities.add_face pts.map{|pt| Geom::Point3d.new(pt)+jut_vector}
upright(jutting_face)
jutting_face.pushpull cabinet_height

pts=[0,0,0],[0,top_opening_depth,0],[top_opening_width,top_opening_depth,0],[top_opening_width,0,0]
offset_x= 4
vector_top = Geom::Vector3d.new(offset_x,0,64)
#top_opening.name= "top_opening"
top_face2 = top_opening.entities.add_face pts.map{|pt| Geom::Point3d.new(pt)+vector_top}
upright(top_face2)
top_face2.pushpull top_opening_height

vector_bottom=Geom::Vector3d.new(offset_x,0,3.5)
#bottom_opening.name= "bottom_opening"
bottom_face2 = bottom_opening.entities.add_face pts.map{|pt| Geom::Point3d.new(pt)+vector_bottom}
upright(bottom_face2)
bottom_face2.pushpull bottom_opening_height

bottom = bottom_opening.union(bottom_main)
#bottom.name = "bottom"
top = top_opening.union(top_main)
#top.name = "top"
cabinet = top.subtract(cabinet)
cabinet = bottom.subtract(cabinet)
cabinet = cabinet.union(jutting_peice)
cabinet.name = "cabinet"
cabinet.material = "blue"
# find a face in the cabinet
zface = cabinet.entities.find {|ent| ent.is_a?(Sketchup::Face) &&    ent.normal == [0, 0, 1] && ent.vertices[0].position.z.between?(0.5,60)}

# get the points for the face.
pts = zface.vertices.uniq.map(&:position)

shelf_face = shelf.entities.add_face pts
upright(shelf_face)
shelf_face.pushpull 0.5
new_transform = Geom::Transformation.new([0,0,24])
shelf.transformation = new_transform
shelf2 = shelf.parent.entities.add_instance(shelf.definition, shelf.transformation)
shelf2.transformation = Geom::Transformation.new([0,0,36])
shelf3 = shelf.parent.entities.add_instance(shelf.definition, shelf.transformation)
shelf3.transformation = Geom::Transformation.new([0,0,48])
shelf4 = shelf.parent.entities.add_instance(shelf.definition, shelf.transformation)
shelf4.transformation = Geom::Transformation.new([0,0,69.5])
shelf5 = shelf.parent.entities.add_instance(shelf.definition, shelf.transformation)
shelf5.transformation = Geom::Transformation.new([0,0,78.5])
``````