Skip to content

Commit 2b3a262

Browse files
chadqueenRobPasMue
andauthored
Design organization example (#181)
Co-authored-by: Roberto Pastor Muela <roberto.pastormuela@ansys.com>
1 parent b463cd6 commit 2b3a262

File tree

7 files changed

+118
-12
lines changed

7 files changed

+118
-12
lines changed
Loading

doc/source/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
nbsphinx_thumbnails = {
123123
"examples/basic_usage": "_static/thumbnails/basic_usage.png",
124124
"examples/dynamic_sketch_plane": "_static/thumbnails/dynamic_sketch_plane.png",
125+
"examples/design_organization": "_static/thumbnails/design_organization.png",
125126
}
126127

127128
typehints_defaults = "comma"

doc/source/examples.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ All examples are collected in this page.
55

66
.. nbgallery::
77

8+
examples/design_organization.mystnb
89
examples/dynamic_sketch_plane.mystnb
910
examples/basic_usage.mystnb
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
---
2+
jupytext:
3+
text_representation:
4+
extension: .mystnb
5+
format_name: myst
6+
format_version: 0.13
7+
jupytext_version: 1.14.1
8+
kernelspec:
9+
display_name: Python 3 (ipykernel)
10+
language: python
11+
name: python3
12+
---
13+
14+
# Design Organization
15+
16+
The ``Design`` instance creates a new design project within the remote Geometry Service to
17+
complete all CAD modeling against.
18+
19+
All of the solid and surface bodies within each design can be organized within a customizable
20+
component hierarchy.
21+
22+
The top-level design node and each child-component node can have one or more bodies assigned
23+
and one or more components assigned.
24+
25+
The API requires each component of the design hierarchy to be given a user-defined name.
26+
27+
There are several design operations that result in a new body being created within the design.
28+
Executing each of these methods against a specific component instance explicitly specifies the
29+
node of the design tree to which the new body should be organized under.
30+
31+
+++
32+
33+
Start by importing the fundamental objects:
34+
35+
```{code-cell} ipython3
36+
from ansys.geometry.core import Modeler
37+
from ansys.geometry.core.math import UNITVECTOR3D_X, Point2D
38+
from ansys.geometry.core.misc import UNITS, Distance
39+
from ansys.geometry.core.sketch import Sketch
40+
```
41+
42+
## Design organization
43+
44+
Two sketches are extruded to create bodies. The cylinder is assigned to the
45+
top-level design component. The slot is assigned to the component nested
46+
one level beneath the top-level design component.
47+
48+
```{code-cell} ipython3
49+
modeler = Modeler()
50+
51+
design = modeler.create_design("DesignHierarchyExample")
52+
53+
circle_sketch = Sketch()
54+
circle_sketch.circle(Point2D([10, 10], UNITS.mm), Distance(10, UNITS.mm))
55+
56+
cylinder_body = design.extrude_sketch("10mmCylinder", circle_sketch, Distance(10, UNITS.mm))
57+
58+
slot_sketch = Sketch()
59+
slot_sketch.slot(Point2D([40, 10], UNITS.mm), Distance(20, UNITS.mm), Distance(10, UNITS.mm))
60+
61+
nested_component = design.add_component("NestedComponent")
62+
slot_body = nested_component.extrude_sketch("SlotExtrusion", slot_sketch, Distance(20, UNITS.mm))
63+
64+
design.plot()
65+
```
66+
67+
## Another Nested Component
68+
69+
A component is simply an organization mechanism. The following creates a component nested
70+
under the previously created component and then creates another cylinder from the previously
71+
used sketch.
72+
73+
```{code-cell} ipython3
74+
75+
double_nested_component = nested_component.add_component("DoubleNestedComponent")
76+
77+
circle_surface_body = double_nested_component.create_surface("CircularSurfaceBody", circle_sketch)
78+
circle_surface_body.translate(UNITVECTOR3D_X, Distance(-10, UNITS.mm))
79+
80+
design.plot()
81+
```
82+
83+
## Cross Component Targets
84+
85+
Surfaces from any body across the entire design can be used as a reference for creating new bodies.
86+
87+
This example extrudes a cylinder from the surface body assigned to the child component.
88+
89+
```{code-cell} ipython3
90+
91+
cylinder_from_face = nested_component.extrude_face("CylinderFromFace", circle_surface_body.faces[0], Distance(30, UNITS.mm))
92+
cylinder_from_face.translate(UNITVECTOR3D_X, Distance(-25, UNITS.mm))
93+
94+
design.plot()
95+
```

src/ansys/geometry/core/designer/body.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -307,21 +307,19 @@ def translate(self, direction: UnitVector3D, distance: Union[Quantity, Distance]
307307
"""
308308
check_type(direction, UnitVector3D)
309309
check_type(distance, (Quantity, Distance))
310-
check_pint_unit_compatibility(distance, SERVER_UNIT_LENGTH)
311310

312-
magnitude = (
313-
distance.m_as(SERVER_UNIT_LENGTH)
314-
if not isinstance(distance, Distance)
315-
else distance.value.m_as(SERVER_UNIT_LENGTH)
316-
)
311+
translate_distance = distance if isinstance(distance, Quantity) else distance.value
312+
check_pint_unit_compatibility(translate_distance.units, SERVER_UNIT_LENGTH)
313+
314+
translation_magnitude = translate_distance.m_as(SERVER_UNIT_LENGTH)
317315

318316
self._grpc_client.log.debug(f"Translating body {self.id}.")
319317

320318
self._bodies_stub.Translate(
321319
TranslateRequest(
322320
bodies=[self.id],
323321
direction=unit_vector_to_grpc_direction(direction),
324-
distance=magnitude,
322+
distance=translation_magnitude,
325323
)
326324
)
327325

src/ansys/geometry/core/designer/component.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def extrude_sketch(
216216

217217
# Perform extrusion request
218218
request = CreateExtrudedBodyRequest(
219-
distance=distance.m_as(SERVER_UNIT_LENGTH),
219+
distance=extrude_distance.m_as(SERVER_UNIT_LENGTH),
220220
parent=self.id,
221221
plane=plane_to_grpc_plane(sketch._plane),
222222
geometries=sketch_shapes_to_grpc_geometries(sketch._plane, sketch.edges, sketch.faces),
@@ -262,7 +262,7 @@ def extrude_face(self, name: str, face: Face, distance: Union[Quantity, Distance
262262

263263
# Take the face source directly. No need to verify the source of the face.
264264
request = CreateExtrudedBodyFromFaceProfileRequest(
265-
distance=distance.m_as(SERVER_UNIT_LENGTH),
265+
distance=extrude_distance.m_as(SERVER_UNIT_LENGTH),
266266
parent=self.id,
267267
face=face.id,
268268
name=name,

tests/integration/test_design.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from ansys.geometry.core.materials import Material, MaterialProperty, MaterialPropertyType
1515
from ansys.geometry.core.math import UNITVECTOR3D_Z, Frame, Plane, Point2D, Point3D, UnitVector3D
1616
from ansys.geometry.core.misc import UNITS
17+
from ansys.geometry.core.misc.measurements import Distance
1718
from ansys.geometry.core.sketch import Sketch
1819

1920

@@ -114,13 +115,23 @@ def test_face_to_body_creation(modeler: Modeler):
114115
assert len(design.bodies) == 2
115116
assert longer_body.volume.m == pytest.approx(Quantity(2e-6, UNITS.m**3).m, rel=1e-6, abs=1e-8)
116117

118+
longest_body = design.extrude_face(
119+
"LongestBoxFromFace", box_body.faces[0], Distance(30, UNITS.mm)
120+
)
121+
122+
assert len(design.components) == 0
123+
assert len(design.bodies) == 3
124+
assert longest_body.volume.m == pytest.approx(
125+
Quantity(3e-6, UNITS.m**3).m, rel=1e-6, abs=1e-8
126+
)
127+
117128
nested_component = design.add_component("NestedComponent")
118129
surface_body = nested_component.create_surface_from_face(
119130
"SurfaceFromFace", longer_body.faces[2]
120131
)
121132

122133
assert len(design.components) == 1
123-
assert len(design.bodies) == 2
134+
assert len(design.bodies) == 3
124135
assert len(nested_component.components) == 0
125136
assert len(nested_component.bodies) == 1
126137
assert surface_body.volume.m == Quantity(0, UNITS.m**3).m
@@ -665,7 +676,7 @@ def test_single_body_translation(modeler: Modeler):
665676
polygon_comp = design.add_component("PolygonComponent")
666677
body_polygon_comp = polygon_comp.extrude_sketch("Polygon", sketch_2, Quantity(30, UNITS.mm))
667678

668-
body_circle_comp.translate(UnitVector3D([1, 0, 0]), Quantity(50, UNITS.mm))
679+
body_circle_comp.translate(UnitVector3D([1, 0, 0]), Distance(50, UNITS.mm))
669680
body_polygon_comp.translate(UnitVector3D([-1, 1, -1]), Quantity(88, UNITS.mm))
670681

671682

@@ -757,7 +768,7 @@ def test_slot_extrusion(modeler: Modeler):
757768
sketch.slot(Point2D([10, 10], UNITS.mm), Quantity(10, UNITS.mm), Quantity(5, UNITS.mm))
758769

759770
# Extrude the sketch
760-
body = design.extrude_sketch(name="MySlot", sketch=sketch, distance=Quantity(50, UNITS.mm))
771+
body = design.extrude_sketch(name="MySlot", sketch=sketch, distance=Distance(50, UNITS.mm))
761772

762773
# A slot has 6 faces and 12 edges
763774
assert len(body.faces) == 6

0 commit comments

Comments
 (0)