Insert skp file - Class: Geom::Transformation

Please, I would like to insert a .skp file which concerns the three-dimensional drawing of a knob.
I wonder if it’s possible to insert the knob with its X-axis perpendicular to the face,
thus avoiding the use of the method “trf_rotz = Geom::Transformation.rotation(pts_a_insknob, Z_AXIS, -90.degrees)”, that presupposes the value of the angle of rotation…
in this way, whatever the angle of the face on the xy plane, the knob would always be positioned correctly…
some help…

thank you

Joseph


depth = 50.cm
height = 15.cm
model = Sketchup.active_model
entities = model.active_entities
pts = []
pts[0] = [0, 0, 0]
pts[1] = [0, depth, 0]
pts[2] = [0, depth, height]
pts[3] = [0, 0, height]

# Add the face to the entities in the model
face_1 = entities.add_face(pts)
#
grp_1 = entities.add_group(face_1)
grp_1.name = 'grp1'
#
pts_a = []
pts_a[0] = [20.cm, 50.cm, 0]
pts_a[1] = pts_a[0].transform([depth, 0, 0])
pts_a[2] = pts_a[1].transform([0, 0, height])
pts_a[3] = pts_a[2].transform([-depth, 0, 0])

# Add the face to the entities in the model
face_2 = entities.add_face(pts_a)
#
grp_2 = entities.add_group(face_2)
grp_2.name = 'grp2'

# Knob insertion point "face_1"...name = 'grpknob'
pts_insknob = pts[0].transform([0, depth / 2, height / 2])
#
grp_knob = entities.add_group
grp_knob.name = 'grpknob'
#
transform_1 = Geom::Transformation.new(pts_insknob)
#
filepath_knob = File.join(File.dirname(__FILE__), 'Pom_1.skp')
defComp_knob1 = model.definitions
compDef1 = defComp_knob1.load(filepath_knob)
grp_knob.entities.add_instance(compDef1, transform_1)
#
# Knob insertion point "face_2"...name = 'grpknob'
pts_a_insknob = pts_a[0].transform([depth / 2, 0, height / 2])
#
grp_knob1 = entities.add_group
grp_knob1.name = 'grpknob1'
#
transform_2 = Geom::Transformation.new(pts_a_insknob)
#
defComp_knob2 = model.definitions
compDef2 = defComp_knob2.load(filepath_knob)
grp_knob1.entities.add_instance(compDef2, transform_2)
#
trf_rotz = Geom::Transformation.rotation(pts_a_insknob, Z_AXIS, -90.degrees)
grp_knob1.transform! trf_rotz

You could construct a transformation in world coordinates that would position and orient correctly.

face_center = face_1.center.transform( grp_1.transformation ) #In world coordinates
x_axis = face_1.normal.transform( grp_1.transformation )  # World coords
# Assuming that the drawer's normal is always parallel to X-Y plane,
#    then knobs Z axis => Z_AXIS
# Otherwise, use the grp_1 transformation's Z axis and convert to world coordinates.
y_axis = Z_AXIS.cross( x_axis)
transform_1 = Geom::Transformation.axes( face_center, x_axis, y_axis, Z_AXIS )

Use something similar for grp_2.
Your approach is having the knob outside of both grouped objects. At some point you may want to add the knob to the definition of the grouped object, then you want transform_1 and/or transform_2 in local coordinates of the desired group.

I wonder if making this a gluing component would help?
Then you just move to the point on the face and call knob.glue_to= face

If using SketchUp 2021.1+ then you can also glue to another group or instance from outside. (Prior to this you had to glue directly to the face inside a component if using the API.)

Thank you very much for your valuable advice…

:wink: :wink:

I tried some changes, added a face3, perpendicular to the xy plane, but rotated…
I managed to align the x-axis of the knob perpendicular to the face3…
some other help… thank you.

Joseph.


depth = 50.cm
height = 15.cm
model = Sketchup.active_model
entities = model.active_entities
pta = []
pta[0] = [10.cm, 10.cm, 0]
pta[1] = pta[0].transform([0, depth, 0])
pta[2] = pta[1].transform([0, 0, height])
pta[3] = pta[0].transform([0, 0, height])

# Add the face to the entities in the model
face1 = entities.add_face(pta)
#
# Center point of the face1...central point insertion of the knob
pt_centerFace1 = pta[0].transform([0, depth / 2, height / 2])
#
# Container group of face1 entities
grp_1 = entities.add_group(face1)
grp_1.name = 'grp1'
#
x_axis = face1.normal.transform(grp_1.transformation)
y_axis = Z_AXIS.cross(x_axis)
#
transform_1 = Geom::Transformation.axes(pt_centerFace1, x_axis, y_axis, Z_AXIS)
#
# Container group of the knob
grp_knob = entities.add_group
grp_knob.name = 'grpknob'
#
filepath_knob = File.join(File.dirname(__FILE__), 'Pom_1.skp')
defComp_knob = model.definitions
compDef1 = defComp_knob.load(filepath_knob)
grp_knob.entities.add_instance(compDef1, transform_1)
#
ptb = []
ptb[0] = [20.cm, 50.cm, 0]
ptb[1] = ptb[0].transform([depth, 0, 0])
ptb[2] = ptb[1].transform([0, 0, height])
ptb[3] = ptb[2].transform([-depth, 0, 0])

# Add the face to the entities in the model
face2 = entities.add_face(ptb)
#
# Center point of the face2...central point insertion of the knob
pt_centerFace2 = ptb[0].transform([depth / 2, 0, height / 2])
#
# Container group of face2 entities
grp_2 = entities.add_group(face2)
grp_2.name = 'grp2'
#
x_axis = face2.normal.transform(grp_2.transformation)
y_axis = Z_AXIS.cross(x_axis)
#
transform_2 = Geom::Transformation.axes(pt_centerFace2, x_axis, y_axis, Z_AXIS)
#
defComp_knob2 = model.definitions
compDef2 = defComp_knob2.load(filepath_knob)
grp_knob.entities.add_instance(compDef2, transform_2)
#
ptc = []
ptc[0] = [35.cm, 65.cm, 15.cm]
ptc[1] = ptc[0].transform([15.cm, depth, 0])
ptc[2] = ptc[1].transform([0, 0, height])
ptc[3] = ptc[0].transform([0, 0, height])
#
# Extract the value of x and y of the point ptc[0]
ptc0_x = ptc[0].x
ptc0_y = ptc[0].y
#
# Extract the value of x and y of the point ptc[2]
ptc2_x = ptc[2].x
ptc2_y = ptc[2].y
#
# Imagine joining the two points (ptc[0] and ptc[2]) with an imaginary line...
#...this imaginary line between the two points also corresponds to one of the two diagonals of the face3...
#...then we can calculate the mean point of the diagonal, which also corresponds to the center of the face3.
#
# Add the face to the entities in the model
face3 = entities.add_face(ptc)
#
dist_ptc0_ptc3 = ptc[0].distance(ptc[3])
#
# Center point(center of gravity of the face) of the face3...central point insertion of the knob
ptbar_face3 = Geom::Point3d.new(ptc0_x + ptc2_x / 2, ptc0_y + ptc2_y / 2, dist_ptc0_ptc3 / 2)

# ********** ptbar_face3 = [ptc0_x + ptc2_x / 2, ptc0_y + ptc2_y / 2, dist_ptc0_ptc3 / 2] *********
#
#trf_ptbarF3 = Geom::Transformation.new(ptbar_face3)
#
# Container group of face_1 entities
grp_3 = entities.add_group(face3)
grp_3.name = 'grp3'
#
x_axis = face3.normal.transform(grp_3.transformation)
y_axis = Z_AXIS.cross(x_axis)
#
transform_3 = Geom::Transformation.axes(ptbar_face3, x_axis, y_axis, Z_AXIS)
#
defComp_knob3 = model.definitions
compDef3 = defComp_knob3.load(filepath_knob)
grp_knob.entities.add_instance(compDef3, transform_3)
#

Hi, I couldn’t get this piece of recommended code to work “face_center = face_1.center.transform( grp_1.transformation )”…
I tried these code changes…


depth = 50.cm
height = 15.cm
model = Sketchup.active_model
entities = model.active_entities
pta = []
pta[0] = [10.cm, 10.cm, 0]
pta[1] = pta[0].transform([0, depth, 0])
pta[2] = pta[1].transform([0, 0, height])
pta[3] = pta[0].transform([0, 0, height])

# Add the face to the entities in the model
face1 = entities.add_face(pta)
#
# Center point of the face1...central point insertion of the knob
pt_centerFace1 = pta[0].transform([0, depth / 2, height / 2])
#
# Container group of face1 entities
grp_1 = entities.add_group(face1)
grp_1.name = 'grp1'
#
x_axis = face1.normal.transform(grp_1.transformation)
y_axis = Z_AXIS.cross(x_axis)
#
transform_1 = Geom::Transformation.axes(pt_centerFace1, x_axis, y_axis, Z_AXIS)
#
# Container group of the knob
grp_knob = entities.add_group
grp_knob.name = 'grpknob'
#
filepath_knob = File.join(File.dirname(__FILE__), 'Pom_1.skp')
defComp_knob = model.definitions
compDef1 = defComp_knob.load(filepath_knob)
grp_knob.entities.add_instance(compDef1, transform_1)
#
ptb = []
ptb[0] = [20.cm, 50.cm, 0]
ptb[1] = ptb[0].transform([depth, 0, 0])
ptb[2] = ptb[1].transform([0, 0, height])
ptb[3] = ptb[2].transform([-depth, 0, 0])

# Add the face to the entities in the model
face2 = entities.add_face(ptb)
#
# Center point of the face2...central point insertion of the knob
pt_centerFace2 = ptb[0].transform([depth / 2, 0, height / 2])
#
# Container group of face2 entities
grp_2 = entities.add_group(face2)
grp_2.name = 'grp2'
#
x_axis = face2.normal.transform(grp_2.transformation)
y_axis = Z_AXIS.cross(x_axis)
#
transform_2 = Geom::Transformation.axes(pt_centerFace2, x_axis, y_axis, Z_AXIS)
#
defComp_knob2 = model.definitions
compDef2 = defComp_knob2.load(filepath_knob)
grp_knob.entities.add_instance(compDef2, transform_2)
#
ptc = []
ptc[0] = [35.cm, 65.cm, 15.cm]
ptc[1] = ptc[0].transform([15.cm, depth, 0])
ptc[2] = ptc[1].transform([0, 0, height])
ptc[3] = ptc[0].transform([0, 0, height])
#
# Extract the value of x y and z of the point ptc[0]
ptc0_x = ptc[0].x
ptc0_y = ptc[0].y
ptc0_z = ptc[0].z
#
# Extract the value of x y and z of the point ptc[2]
ptc2_x = ptc[2].x
ptc2_y = ptc[2].y
ptc2_z = ptc[2].z
#
# Imagine joining the two points (ptc[0] and ptc[2]) with an imaginary line...
#...this imaginary line between the two points also corresponds to one of the two diagonals of the face3...
#...then we can calculate the mean point of the diagonal, which also corresponds to the center of the face3.
#
# Add the face to the entities in the model
face3 = entities.add_face(ptc)
#
# Center point(center of gravity of the face) of the face3...central point insertion of the knob
ptbar_face3 = Geom::Point3d.new((ptc0_x + ptc2_x) / 2, (ptc0_y + ptc2_y) / 2,  (ptc0_z + ptc2_z) / 2)
#
# Container group of face_1 entities
grp_3 = entities.add_group(face3)
grp_3.name = 'grp3'
#
x_axis = face3.normal.transform(grp_3.transformation)
y_axis = Z_AXIS.cross(x_axis)
#
transform_3 = Geom::Transformation.axes(ptbar_face3, x_axis, y_axis, Z_AXIS)
#
defComp_knob3 = model.definitions
compDef3 = defComp_knob3.load(filepath_knob)
grp_knob.entities.add_instance(compDef3, transform_3)
#

Please do not embolden all your text in forum postings.

To get the center of a primitive, you would need to access the entity’s bounding box and ask it for the center.

face_center = face_1.bounds.center

But be aware that the bounding box is oriented to the parent axes. If the primitive or object is rotated away from the contextual axes, then the center point may not actually lie upon the primitive.

This subject has come up before here in this category and there are topics on how to code a method that returns the true centroid of a face. Use the search feature at top right and search on the word “centroid”.

Okay, thank you.

Modified code…thank you… :wink: :wink:


depth = 50.cm
height = 15.cm
model = Sketchup.active_model
entities = model.active_entities
pta = []
pta[0] = [10.cm, 10.cm, 0]
pta[1] = pta[0].transform([0, depth, 0])
pta[2] = pta[1].transform([0, 0, height])
pta[3] = pta[0].transform([0, 0, height])

# Add the face to the entities in the model
face1 = entities.add_face(pta)
#
# Center point of the face1...central point insertion of the knob
#pt_centerFace1 = pta[0].transform([0, depth / 2, height / 2])
pt_centerFace1 = face1.bounds.center
#
# Container group of face1 entities
grp_1 = entities.add_group(face1)
grp_1.name = 'grp1'
#
x_axis = face1.normal.transform(grp_1.transformation)
y_axis = Z_AXIS.cross(x_axis)
#
transform_1 = Geom::Transformation.axes(pt_centerFace1, x_axis, y_axis, Z_AXIS)
#
# Container group of the knob
grp_knob = entities.add_group
grp_knob.name = 'grpknob'
#
filepath_knob = File.join(File.dirname(__FILE__), 'Pom_1.skp')
defComp_knob = model.definitions
compDef1 = defComp_knob.load(filepath_knob)
grp_knob.entities.add_instance(compDef1, transform_1)
#
ptb = []
ptb[0] = [20.cm, 50.cm, 0]
ptb[1] = ptb[0].transform([depth, 0, 0])
ptb[2] = ptb[1].transform([0, 0, height])
ptb[3] = ptb[2].transform([-depth, 0, 0])

# Add the face to the entities in the model
face2 = entities.add_face(ptb)
#
# Center point of the face2...central point insertion of the knob
#pt_centerFace2 = ptb[0].transform([depth / 2, 0, height / 2])
pt_centerFace2 = face2.bounds.center
#
# Container group of face2 entities
grp_2 = entities.add_group(face2)
grp_2.name = 'grp2'
#
x_axis = face2.normal.transform(grp_2.transformation)
y_axis = Z_AXIS.cross(x_axis)
#
transform_2 = Geom::Transformation.axes(pt_centerFace2, x_axis, y_axis, Z_AXIS)
#
defComp_knob2 = model.definitions
compDef2 = defComp_knob2.load(filepath_knob)
grp_knob.entities.add_instance(compDef2, transform_2)
#
ptc = []
ptc[0] = [35.cm, 65.cm, 15.cm]
ptc[1] = ptc[0].transform([15.cm, depth, 0])
ptc[2] = ptc[1].transform([0, 0, height])
ptc[3] = ptc[0].transform([0, 0, height])
#

# Extract the value of x and y of the point ptc[0]
#ptc0_x = ptc[0].x
#ptc0_y = ptc[0].y
#ptc0_z = ptc[0].z
#
# Extract the value of x and y of the point ptc[2]
#ptc2_x = ptc[2].x
#ptc2_y = ptc[2].y
#ptc2_z = ptc[2].z
#

# Imagine joining the two points (ptc[0] and ptc[2]) with an imaginary line...
#...this imaginary line between the two points also corresponds to one of the two diagonals of the face3...
#...then we can calculate the mean point of the diagonal, which also corresponds to the center of the face3.
#
# Add the face to the entities in the model
face3 = entities.add_face(ptc)
#
# Center point(center of gravity of the face) of the face3...central point insertion of the knob
#ptbar_face3 = Geom::Point3d.new((ptc0_x + ptc2_x) / 2, (ptc0_y + ptc2_y) / 2,  (ptc0_z + ptc2_z) / 2)
ptbar_face3 = face3.bounds.center
#
# Container group of face_1 entities
grp_3 = entities.add_group(face3)
grp_3.name = 'grp3'
#
x_axis = face3.normal.transform(grp_3.transformation)
y_axis = Z_AXIS.cross(x_axis)
#
transform_3 = Geom::Transformation.axes(ptbar_face3, x_axis, y_axis, Z_AXIS)
#
defComp_knob3 = model.definitions
compDef3 = defComp_knob3.load(filepath_knob)
grp_knob.entities.add_instance(compDef3, transform_3)
#