-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added example notebooks for sweeps and body transforms
- Loading branch information
1 parent
9020717
commit 6599d1c
Showing
2 changed files
with
279 additions
and
0 deletions.
There are no files selected for viewing
146 changes: 146 additions & 0 deletions
146
doc/source/examples/03_modeling/scale_map_bodies.mystnb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
133
doc/source/examples/03_modeling/sweep_chain_profile.mystnb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
||
``` |