Skip to content

Commit

Permalink
added example notebooks for sweeps and body transforms
Browse files Browse the repository at this point in the history
  • Loading branch information
dastan-ansys committed Mar 25, 2024
1 parent 9020717 commit 6599d1c
Show file tree
Hide file tree
Showing 2 changed files with 279 additions and 0 deletions.
146 changes: 146 additions & 0 deletions doc/source/examples/03_modeling/scale_map_bodies.mystnb
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
---
jupytext:
text_representation:
extension: .mystnb
format_name: myst
format_version: 0.13
jupytext_version: 1.16.1
kernelspec:
display_name: .venv
language: python
name: python3
---

# Design: Scale and Map Bodies

The purpose of this notebook is to demonstrate the `map` and `scale` functions and their usage for transforming bodies.

```{code-cell} ipython3
# Imports
import numpy as np
from ansys.geometry.core import Modeler
from ansys.geometry.core.math.point import Point2D, Point3D
from ansys.geometry.core.sketch.sketch import Sketch
from ansys.geometry.core.math.frame import Frame
from ansys.geometry.core.math.vector import UnitVector3D
```

```{code-cell} ipython3
# Initialize the modeler for this example notebook
m = Modeler()
```

## Scale Body

The `scale` function is designed to modify the size of 3D bodies by a specified scale factor. This function is a important part of geometric transformations, allowing for the dynamic resizing of bodies.

### Usage

To use the `scale` function, you call it on an instance of a geometry body, passing a single argument: the scale value. This value is a real number (`Real`) that determines the factor by which the body's size will be changed.

```python
body.scale(value)

+++

## Example: Making a Cube
The code snippets below demonstrates how to change the size of a cube using the `scale` function in `body.py`. The process involves initializing a sketch design for the cube, defining the shape parameters, and then performing rescaling operation to generate the new shape.
1. **Initialize the Cube Sketch Design:**
- A new design sketch named "cube" is created.

```{code-cell} ipython3
design = m.create_design("cube")
```

2. **Define Cube Parameters:**
- `side_length` is set to 10 units, representing the side length of the cube.

```{code-cell} ipython3
# Cube parameters
side_length = 10
```

3. **Create the Profile Cube:**
- A square box is created centered on the origin using `side_length` as the side length of the square.

```{code-cell} ipython3
# Square with side length 10
box_sketch = Sketch().box(Point2D([0, 0]), side_length, side_length)
```

4. **Create Cube Body:**
- `extrude_sktech` on the `box_sketch`, as the base sktech, creates the 3D cube with `distance` being `side_length`.

```{code-cell} ipython3
cube = design.extrude_sketch("box", box_sketch, side_length)
design.plot()
```

4. **Making the cube twice as large:**
- Using `scale`, with value of 2, will double the side lengths of the cube inturn making it twice as large.

```{code-cell} ipython3
# Double the original length
cube.scale(2)
design.plot()
```

4. **Halfing the size of the *original* cube:**
- Using `scale`, with value of 0.25, will give us half the side length of the original cube, which is 5.
- Note: Since we doubled the size of the cube in the previous cell, we need to use the 0.25 factor which in turn will translate to half the size of the original cube.

```{code-cell} ipython3
# Half the original length
cube.scale(0.25)
design.plot()
```

## Map Function

The `map` function enables the reorientation of 3D bodies by mapping them onto a new specified frame. This function is used for adjusting the orientation of geometric bodies within 3D space to match specific reference frames.

### Usage

To use the `map` function, invoke it on an instance of a geometry body with a single argument: the new frame to which the body should be mapped. The frame is a structure or object that defines the new orientation parameters for the body.

```python
body.map(new_frame)

+++

## Example: Creating a Asymmetric Cube
The code snippets below demonstrates how to reframe a cube body using `map` function in `body.py`. The process involves initializing a sketch design for the custom body, extruding the profile by a distance, and then performing the mapping operation to rotate the shape.
1. **Initialize the Shape Sketch Design:**
- A new design sketch named "asymmetric_cube" is created.

```{code-cell} ipython3
# Initialize the sketch design
design = m.create_design("asymmetric_cube")
```

2. **Create Asymmetric Sketch Profile:**
- We will make a sketch profile which is basically a cube centered on the origin with side length 2 with a cutout.

```{code-cell} ipython3
# Create the cube profile with a cut through it
asymmetric_profile = Sketch().segment(Point2D([1, 1]), Point2D([-1, 1])).segment_to_point(Point2D(
[0, 0.5])).segment_to_point(Point2D([-1, -1])).segment_to_point(Point2D([1, -1])).segment_to_point(Point2D([1, 1]))
```

4. **Create Asymmetric Body:**
- `extrude_sktech` on the `asymmetric_profile`, as the base sktech, creating the 3D cube, with a cutout, with `distance` being 1.

```{code-cell} ipython3
# Extrude the asymmetric profile by distance of 1 unit
body = design.extrude_sketch("box", asymmetric_profile, 1)
design.plot()
```

3. **Apply Map Reframing:**
- The below map uses the default x direction, but the y direction is swapped with the z direction, effectively rotating the original shape so that it is standing vertically.

```{code-cell} ipython3
# Apply the reframing
body.map(Frame(Point3D([0, 0, 0]), UnitVector3D([1, 0, 0]), UnitVector3D([0, 0, 1])))
design.plot()
```
133 changes: 133 additions & 0 deletions doc/source/examples/03_modeling/sweep_chain_profile.mystnb
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
jupytext:
text_representation:
extension: .mystnb
format_name: myst
format_version: 0.13
jupytext_version: 1.16.1
kernelspec:
display_name: .venv
language: python
name: python3
---

# Design: Sweep Chain and Sweep Sketch
The purpose of this notebook is to demonstrate the `sweep_sktech` and `sweep_chain` functions and their usage for creating more complex extrusion profiles.

```{code-cell} ipython3
# Imports
import numpy as np
from ansys.geometry.core import Modeler
from ansys.geometry.core.math.point import Point2D, Point3D
from ansys.geometry.core.shapes.curves.circle import Circle
from ansys.geometry.core.shapes.parameterization import Interval
from ansys.geometry.core.sketch.sketch import Sketch
from ansys.geometry.core.math.plane import Plane
from ansys.geometry.core.shapes.curves.ellipse import Ellipse
```

```{code-cell} ipython3
# Initialize the modeler for this example notebook
m = Modeler()
```

## Example: Creating a Donut

The code snippets below demonstrates how to create a 3D donut shape using the `sweep_sketch` function in `design.py`. The process involves initializing a sketch design for the donut, defining two circles for the profile and path, and then performing a sweep operation to generate the donut shape.
1. **Initialize the Donut Sketch Design:**
- A new design sketch named "donut" is created.

```{code-cell} ipython3
# Initialize the donut sketch design
design_sketch = m.create_design("donut")
```

2. **Define Circle Parameters:**
- `path_radius` is set to 5 units, representing the radius of the circular path the profile circle will sweep along.
- `profile_radius` is set to 2 units, representing the radius of the profile circle that sweeps along the path to create the donut body.

```{code-cell} ipython3
# Donut parameters
path_radius = 5
profile_radius = 2
```

3. **Create the Profile Circle:**
- A circle is created on the XZ-plane centered at the coordinates (5, 0, 0) with a radius defined by `profile_radius`. This circle serves as the profile or cross-sectional shape of the donut.

```{code-cell} ipython3
# Create the circlular profile on the XZ-plane centered at (5, 0, 0) with radius 2
profile = Sketch(plane=Plane(direction_x=[1, 0, 0], direction_y=[0, 0, 1])).circle(
Point2D([path_radius, 0]), profile_radius
)
```

4. **Create the Path Circle:**
- Another circle, representing the path along which the profile circle will be swept, is created on the XY-plane centered at (0, 0, 0). The radius of this circle is defined by `path_radius`.

```{code-cell} ipython3
# Create the circlular path on the XY-plane centered at (0, 0, 0) with radius 5
path = [Circle(Point3D([0, 0, 0]), path_radius).trim(Interval(0, 2 * np.pi))]
```

5. **Perform the Sweep Operation:**
- The sweep operation uses the profile circle and sweeps it along the path circle to create the 3D body of the donut. The result is stored in the variable `body`.

```{code-cell} ipython3
# Perform the sweep and examine the final body created
body = design_sketch.sweep_sketch("donutsweep", profile, path)
design_sketch.plot()
```

## Example: Creating a Bowl

This code demonstrates the process of creating a 3D model of a stretched bowl using the `sweep_chain` function in `design.py`. The model is generated by defining a quarter-ellipse as a profile and sweeping it along a circular path, creating a bowl shape with a stretched profile.

1. **Initialize the Bowl Design:**
- A design chain named "bowl" is created to initiate the bowl design process.

```{code-cell} ipython3
# Initialize the bowl sketch design
design_chain = m.create_design("bowl")
```

2. **Define Parameters:**
- `radius` is set to 10 units, used for both the profile and path definitions.

```{code-cell} ipython3
# Define the radius parameter
radius = 10
```

3. **Create the Profile Shape:**
- A quarter-ellipse profile is created with a major radius equal to 10 units and a minor radius equal to 5 units. The ellipse is defined in a 3D space with specific orientation and then trimmed to a quarter using an interval from 0 to π/2 radians. This profile will shape the bowl's side.

```{code-cell} ipython3
# Create quarter-ellipse profile with major radius = 10, minor radius = 5
profile = [
Ellipse(
Point3D([0, 0, radius / 2]), radius, radius / 2, reference=[1, 0, 0], axis=[0, 1, 0]
).trim(Interval(0, np.pi / 2))
]
```

4. **Create the Path:**
- A circular path is created, positioned parallel to the XY-plane but shifted upwards by 5 units (half the major radius). The circle has a radius of 10 units and is trimmed to form a complete loop with an interval from 0 to 2π radians. This path defines the sweeping trajectory for the profile to create the bowl.

```{code-cell} ipython3
# Create circle on the plane parallel to the XY-plane but moved up by 5 units with radius 10
path = [Circle(Point3D([0, 0, radius / 2]), radius).trim(Interval(0, 2 * np.pi))]
```

5. **Perform the Sweep Operation:**
- The bowl body is generated by sweeping the quarter-ellipse profile along the circular path. The sweep operation molds the profile shape along the path to form the stretched bowl. The result of this operation is stored in the variable `body`.

```{code-cell} ipython3
# Create the bowl body
body = design_chain.sweep_chain("bowlsweep", path, profile)
design_chain.plot()
```

```{code-cell} ipython3

```

0 comments on commit 6599d1c

Please sign in to comment.