# How to make components origin attached to the component instead of the model origin

**URL:** <https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301>\
**Category:** Ruby API\
**Tags:** axes\
**Created:** [November 4, 2021, 8:44pm UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301 "2021-11-04T20:44:18Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![ForestCityBuild](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/forestcitybuild/32/131509_2.png) [@ForestCityBuild](https://forums.sketchup.com/u/ForestCityBuild)\
**Post date:** [November 4, 2021, 8:44pm UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301/1 "2021-11-04T20:44:18Z")

</div>

I’m working on a tool to draw cubes and turn them into components. Once I add the component instance, if I go into the model and right click my component and “Change Axes”, I see that the components axes are attached to the models origin instead of the component itself.

I’ve tested the sample hellocube example and turned it’s result into a component just to ensure it wasn’t some other bug in my custom tool.

```auto
group = model.active_entities.add_group
entities = group.entities
points = [
    Geom::Point3d.new(1, 1, 1),
    Geom::Point3d.new(2, 1, 1),
    Geom::Point3d.new(2, 2, 1),
    Geom::Point3d.new(1, 2, 1)
]
face = entities.add_face(points)
face.pushpull(-1)
group.to_component

```

My goal is to have the origin set at the first point, and Z axis in the chosen direction. My cube tool can be drawn at any angle, so I want to set the Z axis to be set to the vector I pushpulled my cube. I already have my vector, I just don’t now how to force my components origin to be where the component was initially created and set the Z axis to my vector.

Screenshot showing the components axis are attached to the models origin.

 ![screenshot-nimbus-capture-2021.11.04-16_39_09](https://global.discourse-cdn.com/sketchup/original/3X/e/1/e128187746d914be921eca9691372a2933b09fb3.jpeg)

---

<div class="post-metadata">

**Author:** ![DanRathbun](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/danrathbun/32/500_2.png) [@DanRathbun](https://forums.sketchup.com/u/DanRathbun)\
**Post date:** [November 5, 2021, 4:39am UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301/2 "2021-11-05T04:39:21Z")

</div>

> [@ForestCityBuild](#):
>
> `group = model.active_entities.add_group`

This statement adds an empty instance of a new group definition at the the `ORIGIN`.

> [@ForestCityBuild](#):
>
> `entities = group.entities`

This statement is a shorthand wrapper for:

```ruby
entities = group.definition.entities

```

These statements …

> [@ForestCityBuild](#):
>
> ```ruby
> points = [
> Geom::Point3d.new(1, 1, 1),
> Geom::Point3d.new(2, 1, 1),
> Geom::Point3d.new(2, 2, 1),
> Geom::Point3d.new(1, 2, 1)
> ]
> face = entities.add_face(points)
> 
> ```

… add a face using the group definition’s local coordinate system.

So it is **you** that are drawing the cube offset from the group’s local origin.

Also leverage mapping methods …

```ruby
points = [
  [0,0,0], [1,0,0], [1,1,0], [0,1,0] 
].map(&Geom::Point3d.method(:new))

```

> [@ForestCityBuild](#):
>
> My cube tool can be drawn at any angle, …

You draw it normally as above within it’s own local coordinate system, and **afterward** you apply a transformation to instances.

See:

[`Geom::Transformation`](https://ruby.sketchup.com/Geom/Transformation.html) class and [`Entities#add_instance()`](https://ruby.sketchup.com/Sketchup/Entities.html#add_instance-instance_method) method.

> [@ForestCityBuild](#):
>
> `group.to_component`

This is frivolous to go through a group phase.

**Instead** , just create a new component definition and draw geometry into it’s entities collection. Then **afterward** , place an instance using a transformation.

See [`DefinitionList#add()`](https://ruby.sketchup.com/Sketchup/DefinitionList.html#add-instance_method)

```ruby
model = Sketchup.active_model

points = [
  [0,0,0], [1,0,0], [1,1,0], [0,1,0] 
].map(&Geom::Point3d.method(:new))

comp = model.definitions.add("MyCube")
ents = comp.entities
face = ents.add_face(points)
face.pushpull(-1) if face

inst = model.active_entities.add_instance(comp, [1,1,1])

```

The frivolity comes from the fact that if you continue the group pattern, you’ll have to transform the instance away from the model `ORIGIN` anyway.

**ADD** : I also showed an API “Easter Egg” where the `#add_instance` method accepts a coordinate array as a point for a translational transformation. (This is not well documented.)

---

<div class="post-metadata">

**Author:** ![MikeWayzovski](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/mikewayzovski/32/98346_2.png) [@MikeWayzovski](https://forums.sketchup.com/u/MikeWayzovski)\
**Post date:** [November 5, 2021, 9:54am UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301/3 "2021-11-05T09:54:37Z")

</div>

@DanRathbun On a side note, is this the reason why in the normal UI, resetting the axis in the context of an object will place it on the world axis?  
 ![axis](https://global.discourse-cdn.com/sketchup/original/3X/1/8/18a9a563afb08f6e1a43d8e910f2276fd57cb22d.gif)

---

<div class="post-metadata">

**Author:** ![Wo3Dan](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/wo3dan/32/7450_2.png) [@Wo3Dan](https://forums.sketchup.com/u/Wo3Dan)\
**Post date:** [November 5, 2021, 10:47am UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301/4 "2021-11-05T10:47:03Z")

</div>

> [@MikeWayzovski](#):
>
> … resetting the axis in the context of an object will place it on the world axis?

Resetting the axes has no effect whatsoever on group’s local axes and origin nor on component’s local axes and origin.

Only the ‘Axes’ tool can be used to relocate their local axes system.  
(With components you get an extra question to make sure you do agree with the changes)

(Or with components you also have the more direct option in the ‘Right click’ context menu: ‘Change Axes’ to do so.)

@MikeWayzovski, I bet you already know all this.

---

<div class="post-metadata">

**Author:** ![ForestCityBuild](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/forestcitybuild/32/131509_2.png) [@ForestCityBuild](https://forums.sketchup.com/u/ForestCityBuild)\
**Post date:** [November 5, 2021, 1:26pm UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301/5 "2021-11-05T13:26:40Z")

</div>

Thanks for the mapping tip.

I only used to\_component to quickly showcase my problem. I’m not sure your solution exactly works though. I’m not statically drawing a cube so I can’t just fallback to starting the cube at 0,0,0 then translate it.

Here is my tools create\_cube method after the user selects their 4 points

```auto
comp = Sketchup.active_model.definitions.add("TEST")
face = comp.entities.add_face @pts
face.reverse! unless face.normal.samedirection?(@lenvec)
face.pushpull(@length)

trans = Geom::Transformation.new
instance = Sketchup.active_model.active_entities.add_instance(comp, trans);

```

I’m aware my trans = Geom::Transformation.new line is placing my axes at the origin. But this leaves the component instance in the correct position the user drew it at.

I’ve tried the below code. This one positions and rotates my axes correctly in the direction I pushpulled, but it moves and rotates my component instance from it’s original drawn position.

```auto
trans = Geom::Transformation.new(@pts[0], face.normal.reverse)
instance = Sketchup.active_model.active_entities.add_instance(comp, trans);

```

![screencast-nimbus-capture-2021.11.05-09_16_27](https://global.discourse-cdn.com/sketchup/original/3X/b/9/b962c3d916fe0e0b29ed26a525e5b0f4cf8031eb.gif)

How do I get my cube to stay where it was drawn and my axes in the correct position like the video above? I’m sure I’m overlooking something simple or some other simple way to achieve this. Thanks for your help.

---

<div class="post-metadata">

**Author:** ![slbaumgartner](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/slbaumgartner/32/7302_2.png) [@slbaumgartner](https://forums.sketchup.com/u/slbaumgartner)\
**Post date:** [November 5, 2021, 1:40pm UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301/6 "2021-11-05T13:40:24Z")

</div>

If I understand what you wrote, the user is inputting corner points in some manner and you want to make a cube at those locations? If that is correct, I think the issue is that the user inputs will be in the model’s global coordinates whereas you need to add geometry in the definition’s abstract local coordinates. You need to decide where the cube origin needs to be relative to the input points (e.g. at one of them, centered on a face defined by some of them, etc.) and add geometry to your component definition based on offsets from that reference point. Then place an instance at the reference point in the model using a transformation to that point.

---

<div class="post-metadata">

**Author:** ![ForestCityBuild](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/forestcitybuild/32/131509_2.png) [@ForestCityBuild](https://forums.sketchup.com/u/ForestCityBuild)\
**Post date:** [November 5, 2021, 4:03pm UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301/7 "2021-11-05T16:03:44Z")

</div>

Yes you described it correctly. If you watch my gif, the user clicks 4 points to create the cube. I can get the cube to be drawn in the correct position, but then the origins are wrong **OR** I can get the origins correct, but the cube gets translated. That gif is the latter (correct origin placement, incorrect cube placement)

I think I understand what your are saying about the offset, but am unsure how to approach that. I’m currently attempting to choose the users first selected point as my comp origin and the pushpull direction as the Z axis in this line of code.

```auto
trans = Geom::Transformation.new(@pts[0], face.normal.reverse)

```

Let me know if this is what you meant

- User clicks 4 points
- I get the offset of all 8 cube points from the models origin
- I then create my comp def using the offset points instead of the clicked points
- I an add instance which will be at the model origin now instead of where the user clicked
- Then use the translate I’m already using? Which in theory brings it back to the original drawn position?

I guess in theory I could also do my pushpull after I get the first 4 offset points.

I’ll try to test this once I’m off work.

---

<div class="post-metadata">

**Author:** ![slbaumgartner](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/slbaumgartner/32/7302_2.png) [@slbaumgartner](https://forums.sketchup.com/u/slbaumgartner)\
**Post date:** [November 5, 2021, 4:35pm UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301/8 "2021-11-05T16:35:14Z")

</div>

In your second step, use offsets from a point in the model where you want the component origin to be, not from the model origin. E.g. one of the user-picked points.

---

<div class="post-metadata">

**Author:** ![BruceYoung](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/bruceyoung/32/7523_2.png) [@BruceYoung](https://forums.sketchup.com/u/BruceYoung)\
**Post date:** [November 9, 2021, 12:52am UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301/9 "2021-11-09T00:52:56Z")

</div>

To expand upon what @slbaumgartner said, you need to take your transformation’s inverse and apply it to the points in order to put them into local coordinates, then create the face.

Question: Why do you use the “face.normal.inverse” in the constructor, as opposed to just the Z\_AXIS? Or, just skip the axis and just use:

```nohighlight
trans = Geom::Transformation.new( @pts[0] )

```

---

<div class="post-metadata">

**Author:** ![ForestCityBuild](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/forestcitybuild/32/131509_2.png) [@ForestCityBuild](https://forums.sketchup.com/u/ForestCityBuild)\
**Post date:** [November 10, 2021, 2:51am UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301/10 "2021-11-10T02:51:48Z")

</div>

I’m not sure what transformation you are saying I should take the inverse of.

Here is what I have so far.

```auto
comp = Sketchup.active_model.definitions.add("TEST")
                    
origvec = @pts[0].vector_to(Geom::Point3d.new(0,0,0))
# Move points to orgin
newpts = []
newpts[0] = @pts[0].offset(origvec)
newpts[1] = @pts[1].offset(origvec)
newpts[2] = @pts[2].offset(origvec)
newpts[3] = @pts[3].offset(origvec)
newpts[4] = @pts[4].offset(origvec)

face = comp.entities.add_face newpts
# @lenvec is the vector for the direction the cube was pushpulled
face.reverse! unless face.normal.samedirection?(@lenvec)
face.pushpull(@length)

trans = Geom::Transformation.new(@pts[0])
#trans = Geom::Transformation.new(@pts[0], face.normal.reverse)
instance = Sketchup.active_model.active_entities.add_instance(comp, trans)

```

This screenshot is **“trans = Geom::Transformation.new(@pts[0])”** which keeps the cube in the correct spot, but the Z\_AXIS is wrong. It should be angled the direction I pushpulled.

 ![screenshot-nimbus-capture-2021.11.09-21_39_48](https://global.discourse-cdn.com/sketchup/original/3X/2/9/29622e641af4d642a2b54415c92b5486be1ddb03.jpeg)

This screenshot is **trans = Geom::Transformation.new(@pts[0], face.normal.reverse)** which has the Z\_AXIS and origin point correct, but the transformation rotated my cube. It should be pointed the same direction as the cube in photo 1.

 ![screenshot-nimbus-capture-2021.11.09-21_41_50](https://global.discourse-cdn.com/sketchup/original/3X/a/a/aae977b22dbeba3170a088426778d070001803bb.jpeg)

All I’m trying to accomplish is changing the component instance’s origin without moving the component just like “Change Axes” does.

---

<div class="post-metadata">

**Author:** ![BruceYoung](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/bruceyoung/32/7523_2.png) [@BruceYoung](https://forums.sketchup.com/u/BruceYoung)\
**Post date:** [November 10, 2021, 6:08am UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301/11 "2021-11-10T06:08:33Z")

</div>

You said you want the local Z axis in the same direction as the push pull, but you are sometimes reversing the face normal, which will affect the transformation. We would like to figure out if the face’s normal is being reversed before the face is created. Since I don’t understand the entire process, I will attempt to create the face first, and then convert the component’s entities to local coordinates:

```nohighlight
comp = Sketchup.active_model.definitions.add("TEST")
face = comp.entities.add_face( @pts )
if face.normal.samedirection?( @lenvec ) then
  face_normal = @lenvec
else
  face_normal = @lenvec.reverse
  face.reverse!
end
face.pushpull( @length )
# The face is now defined, but not assigned to a component instance,
# lets work with it a bit more.
. . .
trans = Geom::Transformation.new( @pts[0], face_normal )
comp.entities.transform_entities( trans.inverse, comp.entities.to_a ) # Put into local coords
instance = Sketchup.active_model.active_entities.add_instance(comp, trans)

```

I can’t load this into Sketchup to check my logic or even the syntax, so keep us updated.

---

<div class="post-metadata">

**Author:** ![ForestCityBuild](https://sea2.discourse-cdn.com/sketchup/user_avatar/forums.sketchup.com/forestcitybuild/32/131509_2.png) [@ForestCityBuild](https://forums.sketchup.com/u/ForestCityBuild)\
**Post date:** [November 10, 2021, 4:37pm UTC](https://forums.sketchup.com/t/how-to-make-components-origin-attached-to-the-component-instead-of-the-model-origin/180301/12 "2021-11-10T16:37:29Z")

</div>

That did the trick!!

This was the magic line.

```auto
comp.entities.transform_entities( trans.inverse, comp.entities.to_a )

```

I ended up tweaking it slightly to align the local X and Y too, which wasn’t required for my applicaiton but looks much neater on the final component.

```auto
trans = Geom::Transformation.new(@pts[0].vector_to(@pts[1]), @pts[0].vector_to(@pts[3]), face.normal.reverse, @pts[0])

```

Though I have no idea why, but the **face.normal.reverse** was still required. When I used **face\_normal** from your code, the Z axis was the correct angle but backwards.
