Skip to content

Commit db5f7bc

Browse files
committed
cutting plane no longer crashes if a model isn't loaded
1 parent 9bcb1d3 commit db5f7bc

File tree

3 files changed

+123
-65
lines changed

3 files changed

+123
-65
lines changed

pyNastran/bdf/mesh_utils/cut_edge_model_by_plane.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,13 @@ def _setup_edges(bdf_filename: str) -> tuple[NDArrayNint, NDArrayN3float, NDArra
9393
def _cut_model(nids: NDArrayNint,
9494
xyz_cp: NDArrayN3float,
9595
edges: NDArrayN2int,
96-
view_up: NDArray3float, p1: NDArray3float, p2: NDArray3float,
96+
view_up: NDArray3float,
97+
p1: NDArray3float,
98+
p2: NDArray3float,
9799
tol: float,
98-
nodal_result, plane_atol=1e-5, plane_bdf_filename=None):
100+
nodal_result: np.ndarray,
101+
plane_atol: float=1e-5,
102+
plane_bdf_filename: Optional[str]=None):
99103
"""
100104
Helper method for cut_edge_model_by_axes
101105
@@ -153,9 +157,14 @@ def _cut_model(nids: NDArrayNint,
153157
plane_atol=plane_atol, plane_bdf_filename=plane_bdf_filename)
154158
return local_points_array, global_points_array, result_array
155159

156-
def _cut_edge_model_by_coord(nids, xyz_cid0, edges, coord, tol,
157-
nodal_result, plane_atol=1e-5,
158-
plane_bdf_filename=None):
160+
def _cut_edge_model_by_coord(nids: np.ndarray,
161+
xyz_cid0: np.ndarray,
162+
edges: np.ndarray,
163+
coord: CORD2R,
164+
tol: float,
165+
nodal_result: np.ndarray,
166+
plane_atol: float=1e-5,
167+
plane_bdf_filename: Optional[str]=None):
159168
"""
160169
Cuts a Nastran model with a cutting plane
161170

pyNastran/bdf/mesh_utils/cutting_plane_plotter.py

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
"""Plots a model cutting plane"""
2+
from __future__ import annotations
3+
from typing import Optional, TYPE_CHECKING
24
import numpy as np
5+
36
from pyNastran.utils import int_version
47
try:
58
import matplotlib.pyplot as plt
@@ -13,14 +16,23 @@
1316
from pyNastran.bdf.mesh_utils.cut_model_by_plane import (
1417
cut_edge_model_by_coord, cut_face_model_by_coord, export_face_cut)
1518

16-
17-
def cut_and_plot_model(title, p1, p2, zaxis,
18-
model, coord, nodal_result,
19-
log, ytol,
20-
plane_atol=1e-5,
21-
csv_filename=None,
22-
invert_yaxis=False,
23-
cut_type='edge', plot=True, show=True):
19+
if TYPE_CHECKING:
20+
from cpylog import SimpleLogger
21+
from pyNastran.bdf.bdf import BDF, CORD2R
22+
23+
def cut_and_plot_model(title: str,
24+
p1: np.ndarray,
25+
p2: np.ndarray,
26+
zaxis: np.ndarray,
27+
model: BDF, coord: CORD2R,
28+
nodal_result: np.ndarray,
29+
log: SimpleLogger,
30+
ytol: float,
31+
plane_atol: float=1e-5,
32+
csv_filename: Optional[str]=None,
33+
invert_yaxis: bool=False,
34+
cut_type: str='edge',
35+
plot: bool=True, show: bool=True):
2436
"""
2537
Cuts a Nastran model with a cutting plane
2638
@@ -63,14 +75,16 @@ def cut_and_plot_model(title, p1, p2, zaxis,
6375
local_points_array, global_points_array, result_array = cut_edge_model_by_coord(
6476
model, coord, ytol,
6577
nodal_result, plane_atol=plane_atol, csv_filename=csv_filename_edge)
78+
6679
if len(local_points_array) == 0:
6780
log.error('No elements were piereced. Check your cutting plane.')
6881
return
6982
if plot or csv_filename:
70-
plot_cutting_plane_edges(title, p1, p2, zaxis,
71-
local_points_array, global_points_array, result_array,
72-
csv_filename=csv_filename, invert_yaxis=invert_yaxis,
73-
plot=plot, show=show)
83+
plot_cutting_plane_edges(
84+
title, p1, p2, zaxis,
85+
local_points_array, global_points_array, result_array,
86+
csv_filename=csv_filename, invert_yaxis=invert_yaxis,
87+
plot=plot, show=show)
7488
elif cut_type == 'face':
7589
csv_filename_face = None
7690
if csv_filename:
@@ -82,15 +96,22 @@ def cut_and_plot_model(title, p1, p2, zaxis,
8296

8397
plot_cutting_plane_faces(title, p1, p2, zaxis,
8498
geometry_arrays, results_arrays,
85-
csv_filename=csv_filename, invert_yaxis=invert_yaxis,
99+
csv_filename=csv_filename,
100+
invert_yaxis=invert_yaxis,
86101
show=show)
87102
else: # pragma: no cover
88103
raise NotImplementedError(f'cut_type={cut_type!r} and must be [edge, face]')
89104

90105

91-
def plot_cutting_plane_faces(title, p1, p2, zaxis,
92-
geometry_arrays, result_arrays,
93-
csv_filename=None, invert_yaxis=False, show=True):
106+
def plot_cutting_plane_faces(title: str,
107+
p1: np.ndarray,
108+
p2: np.ndarray,
109+
zaxis: np.ndarray,
110+
geometry_arrays: np.ndarray,
111+
result_arrays: np.ndarray,
112+
csv_filename: Optional[str]=None,
113+
invert_yaxis: bool=False,
114+
show: bool=True):
94115
"""for faces"""
95116
try:
96117
local_x = result_arrays[:, 0]
@@ -146,11 +167,20 @@ def plot_cutting_plane_faces(title, p1, p2, zaxis,
146167
#with open(csv_filename, 'w') as csv_file:
147168
#np.savetxt(csv_filename, result_arrays[0], delimiter=',', header=header, comments='# ',
148169
# encoding=None)
149-
export_face_cut(csv_filename, geometry_arrays, result_arrays, header=header)
150-
151-
def plot_cutting_plane_edges(title, p1, p2, zaxis,
152-
local_points_array, global_points_array, result_array,
153-
csv_filename=None, invert_yaxis=False, plot=True, show=True):
170+
export_face_cut(csv_filename, geometry_arrays, result_arrays,
171+
header=header)
172+
173+
def plot_cutting_plane_edges(title: str,
174+
p1: np.ndarray,
175+
p2: np.ndarray,
176+
zaxis: np.ndarray,
177+
local_points_array: np.ndarray,
178+
global_points_array: np.ndarray,
179+
result_array: np.ndarray,
180+
csv_filename: Optional[str]=None,
181+
invert_yaxis: bool=False,
182+
plot: bool=True,
183+
show: bool=True):
154184
"""for edges"""
155185
local_x = local_points_array[:, 0]
156186

pyNastran/gui/menus/cutting_plane/cutting_plane_object.py

Lines changed: 58 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,19 @@ def make_cutting_plane(self,
152152
gui: MainWindow = self.gui
153153
log = gui.log
154154

155+
try:
156+
model_objs = gui.load_actions.model_objs
157+
except AttributeError:
158+
log.error('Load a model')
159+
return
160+
161+
origin = np.array([0., 0., 0.])
162+
zaxis = np.array([0., 0., 1.])
163+
xzplane = np.array([1., 0., 0.])
164+
default_coords = {
165+
0: CORD2R(0, origin, zaxis, xzplane),
166+
}
167+
155168
model = gui.models[model_name]
156169
class_name = model.__class__.__name__
157170
if class_name in {'BDF', 'OP2Geom'}:
@@ -166,7 +179,7 @@ def make_cutting_plane(self,
166179
# elif class_name in {'Fluent'}:
167180
# xyz_cid0 = model.xyz
168181
else:
169-
model_obj = gui.load_actions.model_objs['main']
182+
model_obj = model_objs['main']
170183
model = model_obj.model
171184
if model is None:
172185
msg = f'{class_name!r} is not supported'
@@ -177,20 +190,14 @@ def make_cutting_plane(self,
177190

178191
class_name = model.__class__.__name__
179192
if not hasattr(model, 'cut_model_node'): # pragma: no cover
180-
raise NotImplementedError(model)
193+
log.error(f'Cutting plane is not supported for {class_name}.')
194+
#raise NotImplementedError(model)
195+
return
181196
#if not hasattr(model, 'cut_model_centroid'): # pragma: no cover
182197
#raise NotImplementedError(res_format)
183198

184-
if class_name in {'Cart3D'}:
185-
origin = np.array([0., 0., 0.])
186-
zaxis = np.array([0., 0., 1.])
187-
xzplane = np.array([1., 0., 0.])
188-
model.coords = {
189-
0: CORD2R(0, origin, zaxis, xzplane),
190-
}
191-
xyz_cid0 = model.points
192-
else: # pragma: no cover
193-
raise RuntimeError(class_name)
199+
model.coords = default_coords
200+
xyz_cid0 = get_xyz_cid0(model, class_name)
194201

195202
#xyz_min, xyz_max = model.xyz_limits
196203
xyz_min = xyz_cid0.min(axis=0)
@@ -306,33 +313,7 @@ def make_cutting_plane(self,
306313
else:
307314
xyz_rel2, res2 = model.cut_model_node(
308315
nodal_result, yslices, xyz=xyz_rel)
309-
310-
fig1 = plt.figure()
311-
fig2 = plt.figure()
312-
fig3 = plt.figure()
313-
ax1 = fig1.gca()
314-
ax2 = fig2.gca()
315-
ax3 = fig3.gca()
316-
xs = xyz_rel2[:, 0]
317-
ys = xyz_rel2[:, 1]
318-
zs = xyz_rel2[:, 2]
319-
320-
ax1.plot(xs, zs, 'o')
321-
ax2.plot(xs, res2, 'o', label=title)
322-
323-
ax1.set_xlabel('X Coord')
324-
ax1.set_ylabel('Z Coord')
325-
326-
ax2.set_xlabel('X Coord')
327-
ax2.set_ylabel(title)
328-
329-
ax3.plot(ys, zs, 'o')
330-
ax3.set_xlabel('Y Coord')
331-
ax3.set_ylabel('Z Coord')
332-
ax1.grid(True)
333-
ax2.grid(True)
334-
ax3.grid(True)
335-
plt.show()
316+
plot_cuts(title, xyz_rel2, res2)
336317

337318

338319
#def create_plane_actor(self,
@@ -368,3 +349,41 @@ def make_cutting_plane(self,
368349
#plane_actor.VisibilityOn()
369350
#gui.rend.Render()
370351
#return plane_actor, prop
352+
353+
def get_xyz_cid0(model, class_name: str) -> np.ndarray:
354+
if class_name in {'Cart3D'}:
355+
xyz_cid0 = model.points
356+
else: # pragma: no cover
357+
raise RuntimeError(class_name)
358+
return xyz_cid0
359+
360+
361+
def plot_cuts(title: str,
362+
xyz_rel2: np.ndarray,
363+
res2: np.ndarray) -> None:
364+
fig1 = plt.figure()
365+
fig2 = plt.figure()
366+
fig3 = plt.figure()
367+
ax1 = fig1.gca()
368+
ax2 = fig2.gca()
369+
ax3 = fig3.gca()
370+
xs = xyz_rel2[:, 0]
371+
ys = xyz_rel2[:, 1]
372+
zs = xyz_rel2[:, 2]
373+
374+
ax1.plot(xs, zs, 'o')
375+
ax2.plot(xs, res2, 'o', label=title)
376+
377+
ax1.set_xlabel('X Coord')
378+
ax1.set_ylabel('Z Coord')
379+
380+
ax2.set_xlabel('X Coord')
381+
ax2.set_ylabel(title)
382+
383+
ax3.plot(ys, zs, 'o')
384+
ax3.set_xlabel('Y Coord')
385+
ax3.set_ylabel('Z Coord')
386+
ax1.grid(True)
387+
ax2.grid(True)
388+
ax3.grid(True)
389+
plt.show()

0 commit comments

Comments
 (0)