Rotating and translating the model

This example shows how to rotate the model around a specified axis and point. To allow adding shapes in other planes than the default x-y plane. We also demonstrate how to translate the model.

from qtcad.builder import Builder
from qtcad.builder import Mask, Polygon, Circle, Direction

Rotation

First we create a mask with two shapes, a large base and a smaller shape on top of it.

footprint = Polygon.box(10, 10, name="base").centered()
small = Circle(name="small", center=(0, 0), radius=2)

example_mask = Mask("footprint")
example_mask.add_shape(footprint)
example_mask.add_shape(small)
Circle(name='small', id=1, radius=2, center=(0, 0))

We create a Builder with this mask, extrude the base shape and then extrude the smaller shape on top of it.

builder = (
    Builder()
    .add_mask(example_mask)
    .use_shape("base")
    .extrude(10)
    .use_shape("small")
    .extrude(2)
    .view(
        volume_labels=True,
        surfaces=True,
        angles=(-45, 0, 45),
        save="figs/unrotated_model.svg",
        font_size=20,
        zoom=0.7,
    )
)
rotation
[01:53:05 PM] INFO     Extruding shape 0 from mask 'footprint' with name 'base' by 10 at z=0                                                               builder.py:2695
              INFO     Creating new physical group with name 'base_bottom'                                                                                 builder.py:2482
              INFO     Creating new physical group with name 'base_side'                                                                                   builder.py:2482
              INFO     Creating new physical group with name 'base_top'                                                                                    builder.py:2482
              INFO     Creating new physical group with name 'base'                                                                                        builder.py:2482
              INFO     Setting z-coordinate to 10                                                                                                           builder.py:849
              INFO     Extruding shape 1 from mask 'footprint' with name 'small' by 2 at z=10                                                              builder.py:2695
              INFO     Creating new physical group with name 'small_bottom'                                                                                builder.py:2482
              INFO     Creating new physical group with name 'small_side'                                                                                  builder.py:2482
              INFO     Creating new physical group with name 'small_top'                                                                                   builder.py:2482
              INFO     Fragmenting...                                                                                                                    fragmenter.py:234
              INFO     Creating new physical group with name 'small'                                                                                       builder.py:2482
/home/hiro/Documents/org/roam/code/qtcad_flake/qtcad/packages/builder/src/qtcad/builder/core/builder.py:3552: UserWarning: Removing orphaned entities: [(1, 14)]
  warnings.warn(
              INFO     Setting z-coordinate to 12                                                                                                           builder.py:849
[01:53:06 PM] INFO     Saving /home/hiro/Documents/org/roam/code/qtcad_flake/qtcad/packages/builder/examples/operations/figs/unrotated_model.svg           builder.py:1863

Now, we rotate the model 90 degrees around the x axis, using the base shape as the point to rotate around. We then extrude the small shape again on top of the rotated base shape.

builder.rotate_model(angle=90, axis=Direction.x, around="base").extrude(2).view(
    volume_labels=True,
    angles=(-45, 0, 45),
    save="figs/rotated_model.svg",
    font_size=20,
    zoom=0.8,
    surfaces=True,
)
rotation
[01:53:07 PM] INFO     Rotating model around [1. 0. 0.] based at [-4.19775326e-16 -1.88331090e-17  5.00000000e+00] by 90 degrees                            builder.py:630
              INFO     Extruding shape 1 from mask 'footprint' with name 'small' by 2 at z=10.0                                                            builder.py:2695
              INFO     Fragmenting...                                                                                                                    fragmenter.py:234
/home/hiro/Documents/org/roam/code/qtcad_flake/qtcad/packages/builder/src/qtcad/builder/core/builder.py:3552: UserWarning: Removing orphaned entities: [(1, 17), (1, 14)]
  warnings.warn(
              INFO     Setting z-coordinate to 12.0                                                                                                         builder.py:849
              INFO     Saving /home/hiro/Documents/org/roam/code/qtcad_flake/qtcad/packages/builder/examples/operations/figs/rotated_model.svg             builder.py:1863

<qtcad.builder.builder.Builder object at 0x7f026d8ea850>

Finally, we rotate the model 20 degrees around a tilted axis defined by the vector (1, 1, 1), again using the base shape as the point to rotate around. We then extrude the small shape in the middle of the rotated base shape.

builder.rotate_model(angle=20, axis=[1, 1, 1], around="base").set_z(5).extrude(2).view(
    volume_labels=True,
    angles=(-60, 0, 45),
    save="figs/rotated_model_arbitrary_axis.svg",
    font_size=20,
    zoom=0.8,
    surfaces=True,
    axes=3,
)
rotation
[01:53:09 PM] INFO     Rotating model around [1. 1. 1.] based at [-8.34887715e-17 -6.82121026e-16  5.00000000e+00] by 20 degrees                            builder.py:630
              INFO     Could not find any points nearby to snap to. Falling back to bounding box value...                                                  builder.py:2230
              INFO     Setting z-coordinate to 5                                                                                                            builder.py:849
              INFO     Extruding shape 1 from mask 'footprint' with name 'small' by 2 at z=5                                                               builder.py:2695
              INFO     Fragmenting...                                                                                                                    fragmenter.py:234
/home/hiro/Documents/org/roam/code/qtcad_flake/qtcad/packages/builder/src/qtcad/builder/core/builder.py:3552: UserWarning: Removing orphaned entities: [(1, 17), (1, 14), (1, 20)]
  warnings.warn(
[01:53:10 PM] INFO     Setting z-coordinate to 7                                                                                                            builder.py:849
              INFO     Saving                                                                                                                              builder.py:1863
                       /home/hiro/Documents/org/roam/code/qtcad_flake/qtcad/packages/builder/examples/operations/figs/rotated_model_arbitrary_axis.svg

<qtcad.builder.builder.Builder object at 0x7f026d8ea850>

Translation

We can also translate the model. As an example, we first undo the previous rotation.

builder.rotate_model(angle=-20, axis=[1, 1, 1], around="base").view(
    volume_labels=True,
    angles=(-60, 0, 45),
    save="figs/befro_rotation.svg",
    font_size=20,
    zoom=0.8,
    surfaces=True,
    axes=3,
)
rotation
[01:53:12 PM] INFO     Rotating model around [1. 1. 1.] based at [ 5.19313470e-16 -9.63690918e-16  4.97421932e+00] by -20 degrees                           builder.py:630
              INFO     Saving /home/hiro/Documents/org/roam/code/qtcad_flake/qtcad/packages/builder/examples/operations/figs/befro_rotation.svg            builder.py:1863

<qtcad.builder.builder.Builder object at 0x7f026d8ea850>

Then, we translate the model 5 units in the x direction and then extrude a scaled down version of the circle on top of the translated base shape.

builder.translate_model((6, 0, 0)).use_shape("small").copy_shape(
    scale=0.5, name="smaller"
).extrude(2).view(
    volume_labels=True,
    angles=(-60, 0, 45),
    save="figs/translated_model.svg",
    font_size=20,
    zoom=0.8,
    surfaces=True,
    axes=3,
)
rotation
[01:53:14 PM] INFO     Translating model by [6. 0. 0.]                                                                                                      builder.py:579
              INFO     Extruding shape 2 from mask 'footprint' with name 'smaller' by 2 at z=11.998963489820566                                            builder.py:2695
              INFO     Creating new physical group with name 'smaller_bottom'                                                                              builder.py:2482
              INFO     Creating new physical group with name 'smaller_side'                                                                                builder.py:2482
              INFO     Creating new physical group with name 'smaller_top'                                                                                 builder.py:2482
              INFO     Fragmenting...                                                                                                                    fragmenter.py:234
              INFO     Creating new physical group with name 'smaller'                                                                                     builder.py:2482
/home/hiro/Documents/org/roam/code/qtcad_flake/qtcad/packages/builder/src/qtcad/builder/core/builder.py:3552: UserWarning: Removing orphaned entities: [(1, 17), (1, 23), (1, 14), (1, 20)]
  warnings.warn(
              INFO     Setting z-coordinate to 13.998963489820566                                                                                           builder.py:849
              INFO     Saving /home/hiro/Documents/org/roam/code/qtcad_flake/qtcad/packages/builder/examples/operations/figs/translated_model.svg          builder.py:1863

<qtcad.builder.builder.Builder object at 0x7f026d8ea850>

Total running time of the script: (0 minutes 11.992 seconds)

Gallery generated by Sphinx-Gallery