Skip to content

Commit 13ad732

Browse files
FrederikFrederik
authored andcommitted
Updated documentation
1 parent 554a394 commit 13ad732

File tree

5 files changed

+280
-0
lines changed

5 files changed

+280
-0
lines changed

docs/source/nxopentse.cad.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ nxopentse.cad.code module
1212
:undoc-members:
1313
:show-inheritance:
1414

15+
nxopentse.cad.assemblies module
16+
-------------------------
17+
18+
.. automodule:: nxopentse.cad.assemblies
19+
:members:
20+
:undoc-members:
21+
:show-inheritance:
22+
1523
Module contents
1624
---------------
1725

docs/source/nxopentse.tools.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ nxopentse.tools.general module
2020
:undoc-members:
2121
:show-inheritance:
2222

23+
nxopentse.tools.vector_arithmetic module
24+
------------------------------
25+
26+
.. automodule:: nxopentse.tools.vector_arithmetic
27+
:members:
28+
:undoc-members:
29+
:show-inheritance:
30+
2331
Module contents
2432
---------------
2533

src/nxopentse/cad/assemblies.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,32 @@ def create_component_from_bodies(bodies: List[NXOpen.Body],
162162

163163
return component
164164

165+
166+
def add_parts_to_assembly(parts: List[NXOpen.Part], assembly: NXOpen.Part) -> None:
167+
"""
168+
Add a part to an assembly.
169+
170+
Parameters
171+
----------
172+
part : NXOpen.Part
173+
The part to add to the assembly.
174+
assembly : NXOpen.Part
175+
The assembly to add the part to.
176+
177+
NOTES
178+
-----
179+
Tested in Simcenter 2406
180+
"""
181+
add_component_builder: NXOpen.Assemblies.AddComponentBuilder = assembly.AssemblyManager.CreateAddComponentBuilder()
182+
add_component_builder.SetCount(1)
183+
add_component_builder.SetComponentAnchor(NXOpen.Assemblies.ProductInterface.InterfaceObject.Null)
184+
add_component_builder.SetInitialLocationType(NXOpen.Assemblies.AddComponentBuilder.LocationType.WorkPartAbsolute)
185+
add_component_builder.ReferenceSet = "Use Model"
186+
add_component_builder.Layer = -1
187+
add_component_builder.SetPartsToAdd(parts)
188+
add_component_builder.ComponentName = assembly.Name
189+
190+
add_component_builder.Commit()
191+
add_component_builder.ResetPartsToAdd()
192+
add_component_builder.Destroy()
193+

src/nxopentse/cad/code.py

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,126 @@
33
from typing import List, Tuple, Optional, cast, Union
44

55
import NXOpen
6+
import NXOpen.UF
67
import NXOpen.Features
78
import NXOpen.GeometricUtilities
89
import NXOpen.Assemblies
910

1011
from ..tools.vector_arithmetic import dot_product_vector3d
1112

1213
the_session: NXOpen.Session = NXOpen.Session.GetSession()
14+
the_uf_session: NXOpen.UF.UFSession = NXOpen.UF.UFSession.GetUFSession()
1315
the_lw: NXOpen.ListingWindow = the_session.ListingWindow
1416

1517

18+
class MassProps3d:
19+
'''
20+
Object to store the mass properties of a body and easily access and compare them.
21+
'''
22+
def __init__(
23+
self,
24+
surface_area: float = 0.0,
25+
volume: float = 0.0,
26+
mass: float = 0.0,
27+
center_of_mass: Optional[List[float]] = None,
28+
first_moments: Optional[List[float]] = None,
29+
moments_of_inertia_wcs: Optional[List[float]] = None,
30+
moments_of_inertia_centroidal: Optional[List[float]] = None,
31+
spherical_moment_of_inertia: float = 0.0,
32+
inertia_products_wcs: Optional[List[float]] = None,
33+
inertia_products_centroidal: Optional[List[float]] = None,
34+
principal_axes_wcs: Optional[List[float]] = None,
35+
principal_moments_centroidal: Optional[List[float]] = None,
36+
radii_of_gyration_wcs: Optional[List[float]] = None,
37+
radii_of_gyration_centroidal: Optional[List[float]] = None,
38+
spherical_radius_of_gyration: float = 0.0,
39+
density: float = 0.0,
40+
):
41+
self.surface_area = surface_area
42+
self.volume = volume
43+
self.mass = mass
44+
self.center_of_mass = center_of_mass or [0.0, 0.0, 0.0]
45+
self.first_moments = first_moments or [0.0, 0.0, 0.0]
46+
self.moments_of_inertia_wcs = moments_of_inertia_wcs or [0.0, 0.0, 0.0]
47+
self.moments_of_inertia_centroidal = moments_of_inertia_centroidal or [0.0, 0.0, 0.0]
48+
self.spherical_moment_of_inertia = spherical_moment_of_inertia
49+
self.inertia_products_wcs = inertia_products_wcs or [0.0, 0.0, 0.0]
50+
self.inertia_products_centroidal = inertia_products_centroidal or [0.0, 0.0, 0.0]
51+
self.principal_axes_wcs = principal_axes_wcs or [0.0, 0.0, 0.0]
52+
self.principal_moments_centroidal = principal_moments_centroidal or [0.0, 0.0, 0.0]
53+
self.radii_of_gyration_wcs = radii_of_gyration_wcs or [0.0, 0.0, 0.0]
54+
self.radii_of_gyration_centroidal = radii_of_gyration_centroidal or [0.0, 0.0, 0.0]
55+
self.spherical_radius_of_gyration = spherical_radius_of_gyration
56+
self.density = density
57+
58+
59+
def __str__(self) -> str:
60+
return (
61+
f"MassProps3d(\n"
62+
f" Surface Area={self.surface_area},\n"
63+
f" Volume (0.0 For Thin Shell)={self.volume},\n"
64+
f" Mass={self.mass},\n"
65+
f" Center Of Mass (COFM), WCS={self.center_of_mass},\n"
66+
f" First Moments (centroidal)={self.first_moments},\n"
67+
f" Moments Of Inertia, WCS={self.moments_of_inertia_wcs},\n"
68+
f" Moments Of Inertia (centroidal)={self.moments_of_inertia_centroidal},\n"
69+
f" Spherical Moment Of Inertia={self.spherical_moment_of_inertia},\n"
70+
f" Inertia Products, WCS={self.inertia_products_wcs},\n"
71+
f" Inertia Products (centroidal)={self.inertia_products_centroidal},\n"
72+
f" Principal Axes, WCS={self.principal_axes_wcs},\n"
73+
f" Principal Moments (centroidal)={self.principal_moments_centroidal},\n"
74+
f" Radii Of Gyration, WCS={self.radii_of_gyration_wcs},\n"
75+
f" Radii Of Gyration (centroidal)={self.radii_of_gyration_centroidal},\n"
76+
f" Spherical Radius Of Gyration={self.spherical_radius_of_gyration},\n"
77+
f" Density={self.density}\n"
78+
f")"
79+
)
80+
81+
82+
def __eq__(self, other) -> bool:
83+
if not isinstance(other, MassProps3d):
84+
return False
85+
return (
86+
self.surface_area == other.surface_area
87+
and self.volume == other.volume
88+
and self.mass == other.mass
89+
and self.center_of_mass == other.center_of_mass
90+
and self.first_moments == other.first_moments
91+
and self.moments_of_inertia_wcs == other.moments_of_inertia_wcs
92+
and self.moments_of_inertia_centroidal == other.moments_of_inertia_centroidal
93+
and self.spherical_moment_of_inertia == other.spherical_moment_of_inertia
94+
and self.inertia_products_wcs == other.inertia_products_wcs
95+
and self.inertia_products_centroidal == other.inertia_products_centroidal
96+
and self.principal_axes_wcs == other.principal_axes_wcs
97+
and self.principal_moments_centroidal == other.principal_moments_centroidal
98+
and self.radii_of_gyration_wcs == other.radii_of_gyration_wcs
99+
and self.radii_of_gyration_centroidal == other.radii_of_gyration_centroidal
100+
and self.spherical_radius_of_gyration == other.spherical_radius_of_gyration
101+
and self.density == other.density
102+
)
103+
104+
105+
def __hash__(self) -> int:
106+
return hash((
107+
self.surface_area,
108+
self.volume,
109+
self.mass,
110+
tuple(self.center_of_mass),
111+
tuple(self.first_moments),
112+
tuple(self.moments_of_inertia_wcs),
113+
tuple(self.moments_of_inertia_centroidal),
114+
self.spherical_moment_of_inertia,
115+
tuple(self.inertia_products_wcs),
116+
tuple(self.inertia_products_centroidal),
117+
tuple(self.principal_axes_wcs),
118+
tuple(self.principal_moments_centroidal),
119+
tuple(self.radii_of_gyration_wcs),
120+
tuple(self.radii_of_gyration_centroidal),
121+
self.spherical_radius_of_gyration,
122+
self.density,
123+
))
124+
125+
16126
def nx_hello():
17127
"""
18128
Print a greeting message to the listing window.
@@ -46,6 +156,68 @@ def get_all_bodies_in_part(work_part: NXOpen.Part=None # type: ignore
46156
return all_bodies
47157

48158

159+
def get_body_properties(body: NXOpen.Body) -> MassProps3d:
160+
'''
161+
Get the properties of a body In METER and KG!!!!
162+
163+
Parameters
164+
----------
165+
body : NXOpen.Body
166+
The body to get the properties of.
167+
168+
Returns
169+
-------
170+
MassProps3d
171+
A MassProps3d object with the properties of the body.
172+
173+
NOTES
174+
-----
175+
This is based on the GUI funcionality of getting the properties of a body.
176+
Tested in Simcenter 2406
177+
'''
178+
# should update the code to use workpart.MeasureManager
179+
(massProps, Stats) = the_uf_session.Modeling.AskMassProps3d([body.Tag], 1, 1, 4, 0.0, 1, [0.99,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0])
180+
# Mass properties
181+
# [0] = Surface Area
182+
# [1] = Volume (0.0 For Thin Shell)
183+
# [2] = Mass
184+
# [3-5] = Center Of Mass (COFM), WCS
185+
# [6-8] = First Moments (centroidal)
186+
# [9-11] = Moments Of Inertia, WCS
187+
# [12-14] = Moments Of Inertia (centroidal)
188+
# [15] = Spherical Moment Of Inertia
189+
# [16-18] = Inertia Products, WCS
190+
# [19-21] = Inertia Products (centroidal)
191+
# [22-30] = Principal Axes, WCS
192+
# [31-33] = Principal Moments (centroidal)
193+
# [34-36] = Radii Of Gyration, WCS
194+
# [37-39] = Radii Of Gyration (centroidal)
195+
# [40] = Spherical Radius Of Gyration
196+
# [41-45] = Unused
197+
# [46] = Density
198+
# the_lw.WriteFullline(f"MassProps: {massProps}")
199+
200+
properties = MassProps3d(massProps[0],
201+
massProps[1],
202+
massProps[2],
203+
massProps[3:6],
204+
massProps[6:9],
205+
massProps[9:12],
206+
massProps[12:15],
207+
massProps[15],
208+
massProps[16:19],
209+
massProps[19:22],
210+
massProps[22:31],
211+
massProps[31:34],
212+
massProps[34:37],
213+
massProps[37:40],
214+
massProps[40],
215+
massProps[46])
216+
217+
return properties
218+
219+
220+
49221
def get_all_vertices_in_body(body: NXOpen.Body) -> List[NXOpen.Point3d]:
50222
'''
51223
Get all the unique vertices in a body.

src/nxopentse/tools/general.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,66 @@ def get_expression_by_name(name: str,
303303
else:
304304
# something wrong
305305
raise ValueError(f'Found {len(expression)} with name {name}')
306+
307+
308+
def save_view_to_file(file_path: str) -> str:
309+
"""
310+
Saves the current view of the model to a file in TIFF format.
311+
312+
This function exports the current view of the model to an image file in TIFF format. If the specified file already exists,
313+
it is deleted to ensure that the new image overwrites the previous one. The image export options are set to enhance edges,
314+
make the background transparent, and save in the TIFF file format.
315+
316+
Parameters
317+
----------
318+
file_name : str
319+
The full paht of the file to save the image to. File extension will be updated in line with the type.
320+
type : NXOpen.Gateway.ImageExportBuilder.FileFormats, optional
321+
The file format to save the image as. The default is `.Tiff`.
322+
323+
Returns
324+
-------
325+
str
326+
The full path of the saved image file. Note that the file extension is not included in the return value.
327+
328+
Raises
329+
------
330+
FileNotFoundError
331+
If the file path is invalid or the file cannot be created.
332+
333+
IOError
334+
If an error occurs during the image export process.
335+
336+
Notes
337+
-----
338+
- The function currently only supports saving images in TIFF format.
339+
- If the file already exists, it will be deleted and overwritten with the new image.
340+
- Tested in SC2312. SC2406
341+
- Errors on a second run "Gateway does not Exist on NXOpen" because of NXOpen.Gateway.ImageExportBuilder.FileFormats.Tiff
342+
NXOpen.Gateway.ImageExportBuilder.BackgroundOptions.Transparent
343+
"""
344+
if not os.path.isabs(file_path):
345+
raise FileNotFoundError(f"Invalid file path: {file_path}")
346+
347+
file_path_without_extension = os.path.splitext(file_path)[0] # NX adds the extension for the specific file format
348+
# delete existing file to mimic overwriting
349+
if (os.path.exists(file_path)):
350+
os.remove(file_path)
351+
352+
image_export_builder: NXOpen.Gateway.ImageExportBuilder = the_UI.CreateImageExportBuilder()
353+
try:
354+
# Options
355+
image_export_builder.EnhanceEdges = True
356+
image_export_builder.RegionMode = False
357+
# image_export_builder.FileFormat = NXOpen.Gateway.ImageExportBuilder.FileFormats.Tiff
358+
image_export_builder.FileName = file_path_without_extension # NX adds the extension for the specific file format
359+
# image_export_builder.BackgroundOption = NXOpen.Gateway.ImageExportBuilder.BackgroundOptions.Transparent
360+
# Commit the builder
361+
image_export_builder.Commit()
362+
except Exception as e:
363+
the_lw.WriteFullline(str(e))
364+
365+
file_name = image_export_builder.FileName
366+
image_export_builder.Destroy()
367+
return file_name
368+

0 commit comments

Comments
 (0)