I’m looking to put a frame of 2x10 (which is actually 1.5 x 9.5") boards on top of a rectangular face. For each board, I create a face by specifying the four corners then pushpull it up. When the face is parallel to the axes, I can just subtract 1.5" to specify the coordinates. How do I do this when the face is at an arbitrary angle?
From looking at the documentation, it seems that I need a transform, which requires a vector. I can’t seem to find a way to create a vector from either an edge or a pair of vertexes.
Also, how do I create a face so that it’s pointing up towards the sky? I’ve specified the points clockwise and counterclockwise and it’s always pointing down so I have to pushpull it a negative amount.
A vector will be created from the subtraction of two positions. Since it is possible to confuse which point to subtract from, you can use the “vector_to” method. Given an API entity called “edge”, you can use the following statement:
SketchUp defaults to creating faces facing down, on the XY “ground plane”, because it thinks you wish to PushPull them up, as the next operation.
You can reverse faces:
face.reverse! if face.normal.dot(Z_AXIS) < 0
The dot product function multiplies (the product of the vectors) by the cosine of the angle between the vectors. The cosine of 0 is 1, and the cosine of 90 is 0, so the dot product will be between 1 (if the vectors have the same direction,) and 0 if they are perpendicular (ie, 90 degrees apart.)
If the vectors are parallel, but opposite in direction, then their dot product will be -1, as the cosine of 180 is -1.
The global constant Z_AXIS is defined by the API, and points straight up. If your face’s normal vector points downward at all, the dot product between it and the Z_AXIS will be negative (less than 0, because the cosine of any angle greater than 90 and less than 270 is negative.)
When you draw geometry with the API, you should likely draw it inside a group so it will not interact with other geometry, until you want it to. But you must add a temporary Cpoint to the group to keep it from being garbage collected. Later you can delete the Cpoint.
ents = Sketchup::active_model.entities
grp = ents.add_group
gents = grp.entities
cpt = gents.add_cpoint(0,0,0)
# Add geometry to "gents",
# when done, apply a transform to "grp".
… later:
cpt.erase!
And if you no longer need the group you can explode it.
For people who find this thread later, here’s what I did. It turns out that in my case the rectangle would always have a long and short side (they would never be square). I only needed the 2x10 put along the two long sides of the rectangle. So what I did was use outer_loop to get an array of edges, then find the index into the array of the short side.
loop = face.outer_loop
edges = loop.edges
if (edges[0].length > edges[1].length)
longedgeindex = 0
else
longedgeindex = 1
end
for i in 0..3
if (i == longedgeindex)
next
end
if (edges[i].end.position == edges[longedgeindex].start.position)
shortedgeindex = i
end
end
vector = edges[shortedgeindex].start.position.vector_to(edges[shortedgeindex].end.position)
newvertex = edges[longedgeindex].start.position.offset(vector, 1.5)
newvertex2 = edges[longedgeindex].end.position.offset(vector, 1.5)
entities.add_face edges[longedgeindex].start, newvertex, newvertex2, edges[longedgeindex].end