symcad.parts.endcaps.Semiellipsoid

  1#!/usr/bin/env python3
  2# Copyright (C) 2022, Will Hedgecock
  3#
  4# This program is free software: you can redistribute it and/or modify
  5# it under the terms of the GNU General Public License as published by
  6# the Free Software Foundation, either version 3 of the License, or
  7# (at your option) any later version.
  8#
  9# This program is distributed in the hope that it will be useful,
 10# but WITHOUT ANY WARRANTY; without even the implied warranty of
 11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12# GNU General Public License for more details.
 13#
 14# You should have received a copy of the GNU General Public License
 15# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 16
 17from __future__ import annotations
 18from PyFreeCAD.FreeCAD import FreeCAD, Part
 19from typing import Dict, Optional, Tuple, Union
 20from sympy import Expr, Symbol
 21from . import EndcapShape
 22import math
 23
 24class Semiellipsoid(EndcapShape):
 25   """Model representing a hollow, parametric, semiellipsoidal endcap.
 26
 27   By default, the endcap is oriented such that its base is perpendicular to the z-axis:
 28
 29   ![Semiellipsoid](https://symbench.github.io/SymCAD/images/Semiellipsoid.png)
 30
 31   The minor axis of this shape spans the open face of the endcap to its tip, while the major
 32   axis spans the radius of the open face itself.
 33
 34   The `geometry` of this shape includes the following parameters:
 35
 36   - `major_radius`: Major radius (in `m`) of the Semiellipsoid along the x- and y-axis
 37   - `minor_radius`: Minor radius (in `m`) of the Semiellipsoid along the z-axis
 38   - `thickness`: Thickness (in `m`) of the shell of the Semiellipsoid
 39
 40   Note that the above dimensions should be interpreted as if the Semiellipsoid is unrotated.
 41   In other words, any shape rotation takes place *after* the Semiellipsoid dimensions have been
 42   specified.
 43   """
 44
 45   # Constructor ----------------------------------------------------------------------------------
 46
 47   def __init__(self, identifier: str,
 48                      material_density_kg_m3: Optional[float] = 1.0,
 49                      major_minor_axis_ratio: Optional[float] = 2.0,
 50                      minor_depends_on_major: bool = True) -> None:
 51      """Initializes a hollow, parametric, ellipsoidal endcap object.
 52
 53      The `major_minor_axis_ratio` and `minor_depends_on_major` parameters are used to determine
 54      the relative axis lengths of the Semiellipsoid when one or more of its geometric parameters
 55      are symbolic. If all parameters are concretely defined, then these parameters are
 56      meaningless.
 57
 58      The minor axis of this shape spans the open face of the endcap to its tip, while the major
 59      axis spans the radius of the open face itself.
 60
 61      Parameters
 62      ----------
 63      identifier : `str`
 64         Unique identifying name for the object.
 65      material_density_kg_m3 : `float`, optional, default=1.0
 66         Uniform material density in `kg/m^3` to be used in mass property calculations.
 67      major_minor_axis_ratio : `float`, optional, default=2.0
 68         Desired major-to-minor axis ratio of the semiellipsoid.
 69      minor_depends_on_major : `bool`, optional, default=True
 70         Whether the radius of the minor axis depends on the major axis or vice versa.
 71      """
 72      super().__init__(identifier,
 73                       self.__create_cad__,
 74                       'Semiellipsoid.tar.xz',
 75                       material_density_kg_m3)
 76      setattr(self.geometry, 'major_radius', Symbol(self.name + '_major_radius'))
 77      setattr(self.geometry, 'minor_radius', Symbol(self.name + '_minor_radius'))
 78      setattr(self.geometry, 'thickness', Symbol(self.name + '_thickness'))
 79      self.set_geometry(major_axis_radius_m=None,
 80                        minor_axis_radius_m=None,
 81                        thickness_m=None,
 82                        major_minor_axis_ratio=major_minor_axis_ratio,
 83                        minor_depends_on_major=minor_depends_on_major)
 84
 85
 86   # CAD generation function ----------------------------------------------------------------------
 87
 88   @staticmethod
 89   def __create_cad__(params: Dict[str, float], fully_displace: bool) -> Part.Solid:
 90      """Scripted CAD generation method for a `Semiellipsoid`."""
 91      doc = FreeCAD.newDocument('Temp')
 92      thickness_mm = 1000.0 * params['thickness']
 93      outer_major_radius_mm = 1000.0 * params['major_radius']
 94      outer_minor_radius_mm = 1000.0 * params['minor_radius']
 95      inner_major_radius_mm = outer_major_radius_mm - thickness_mm
 96      inner_minor_radius_mm = outer_minor_radius_mm - thickness_mm
 97      outer = doc.addObject('Part::Ellipsoid', 'Ellipsoid')
 98      outer.Radius1 = outer_minor_radius_mm
 99      outer.Radius2 = outer_major_radius_mm
100      outer.Radius3 = outer_major_radius_mm
101      outer.Angle1 = 0.0
102      if not fully_displace:
103         inner = doc.addObject('Part::Ellipsoid', 'Ellipsoid')
104         inner.Radius1 = inner_minor_radius_mm
105         inner.Radius2 = inner_major_radius_mm
106         inner.Radius3 = inner_major_radius_mm
107         inner.Angle1 = 0.0
108         doc.recompute()
109         endcap = outer.Shape.cut(inner.Shape)
110      else:
111         doc.recompute()
112         endcap = outer.Shape
113      FreeCAD.closeDocument(doc.Name)
114      return endcap
115
116
117   # Geometry setter ------------------------------------------------------------------------------
118
119   def set_geometry(self, *, major_axis_radius_m: Union[float, None],
120                             minor_axis_radius_m: Union[float, None],
121                             thickness_m: Union[float, None],
122                             major_minor_axis_ratio: float = 2.0,
123                             minor_depends_on_major: bool = True) -> Semiellipsoid:
124      """Sets the physical geometry of the current `Semiellipsoid` object.
125
126      The `major_minor_axis_ratio` and `minor_depends_on_major` parameters are used to determine
127      the relative axis lengths of the Semiellipsoid when one or more of its geometric parameters
128      are symbolic. If all parameters are concretely defined, then these parameters are
129      meaningless.
130
131      See the `Semiellipsoid` class documentation for a description of each geometric parameter.
132      """
133      self.geometry.set(major_radius=major_axis_radius_m,
134                        minor_radius=minor_axis_radius_m,
135                        thickness=thickness_m)
136      if major_axis_radius_m is not None and minor_axis_radius_m is None:
137         self.geometry.minor_radius = major_axis_radius_m / major_minor_axis_ratio
138      elif major_axis_radius_m is None and minor_axis_radius_m is not None:
139         self.geometry.major_radius = minor_axis_radius_m * major_minor_axis_ratio
140      elif major_axis_radius_m is None and minor_axis_radius_m is None:
141         if minor_depends_on_major:
142            self.geometry.minor_radius = self.geometry.major_radius / major_minor_axis_ratio
143         else:
144            self.geometry.major_radius = self.geometry.minor_radius * major_minor_axis_ratio
145      return self
146
147   def get_geometric_parameter_bounds(self, parameter: str) -> Tuple[float, float]:
148      parameter_bounds = {
149         'major_radius': (0.0, 2.0),
150         'minor_radius': (0.0, 2.0),
151         'thickness': (0.0, 0.05)
152      }
153      return parameter_bounds.get(parameter, (0.0, 0.0))
154
155
156   # Geometric properties -------------------------------------------------------------------------
157
158   @property
159   def material_volume(self) -> Union[float, Expr]:
160      volume = self.displaced_volume
161      volume -= (2.0 * math.pi * (self.geometry.major_radius - self.geometry.thickness)**2
162                               * (self.geometry.minor_radius - self.geometry.thickness) / 3.0)
163      return volume
164
165   @property
166   def displaced_volume(self) -> Union[float, Expr]:
167      return 2.0 * math.pi * self.geometry.major_radius**2 * self.geometry.minor_radius / 3.0
168
169   @property
170   def surface_area(self) -> Union[float, Expr]:
171      numerator = (2.0 * (self.geometry.minor_radius * self.geometry.major_radius)**1.6) + \
172                  self.geometry.major_radius**3.2
173      return 2.0 * math.pi * (numerator / 3.0)**(1.0 / 1.6)
174
175   @property
176   def unoriented_center_of_gravity(self) -> Tuple[Union[float, Expr],
177                                                   Union[float, Expr],
178                                                   Union[float, Expr]]:
179      return (self.geometry.major_radius,
180              self.geometry.major_radius,
181              self.__neural_net__.evaluate('cg_z', **self.geometry.as_dict()))
182
183   @property
184   def unoriented_center_of_buoyancy(self) -> Tuple[Union[float, Expr],
185                                                    Union[float, Expr],
186                                                    Union[float, Expr]]:
187      return (self.geometry.major_radius,
188              self.geometry.major_radius,
189              3.0 * self.geometry.minor_radius / 8.0)
190
191   @property
192   def unoriented_length(self) -> Union[float, Expr]:
193      return 2.0 * self.geometry.major_radius
194
195   @property
196   def unoriented_width(self) -> Union[float, Expr]:
197      return self.unoriented_length
198
199   @property
200   def unoriented_height(self) -> Union[float, Expr]:
201      return self.geometry.minor_radius
202
203   @property
204   def oriented_length(self) -> Union[float, Expr]:
205      # TODO: Implement this
206      return 0
207
208   @property
209   def oriented_width(self) -> Union[float, Expr]:
210      # TODO: Implement this
211      return 0
212
213   @property
214   def oriented_height(self) -> Union[float, Expr]:
215      # TODO: Implement this
216      return 0
class Semiellipsoid(symcad.parts.endcaps.EndcapShape):
 25class Semiellipsoid(EndcapShape):
 26   """Model representing a hollow, parametric, semiellipsoidal endcap.
 27
 28   By default, the endcap is oriented such that its base is perpendicular to the z-axis:
 29
 30   ![Semiellipsoid](https://symbench.github.io/SymCAD/images/Semiellipsoid.png)
 31
 32   The minor axis of this shape spans the open face of the endcap to its tip, while the major
 33   axis spans the radius of the open face itself.
 34
 35   The `geometry` of this shape includes the following parameters:
 36
 37   - `major_radius`: Major radius (in `m`) of the Semiellipsoid along the x- and y-axis
 38   - `minor_radius`: Minor radius (in `m`) of the Semiellipsoid along the z-axis
 39   - `thickness`: Thickness (in `m`) of the shell of the Semiellipsoid
 40
 41   Note that the above dimensions should be interpreted as if the Semiellipsoid is unrotated.
 42   In other words, any shape rotation takes place *after* the Semiellipsoid dimensions have been
 43   specified.
 44   """
 45
 46   # Constructor ----------------------------------------------------------------------------------
 47
 48   def __init__(self, identifier: str,
 49                      material_density_kg_m3: Optional[float] = 1.0,
 50                      major_minor_axis_ratio: Optional[float] = 2.0,
 51                      minor_depends_on_major: bool = True) -> None:
 52      """Initializes a hollow, parametric, ellipsoidal endcap object.
 53
 54      The `major_minor_axis_ratio` and `minor_depends_on_major` parameters are used to determine
 55      the relative axis lengths of the Semiellipsoid when one or more of its geometric parameters
 56      are symbolic. If all parameters are concretely defined, then these parameters are
 57      meaningless.
 58
 59      The minor axis of this shape spans the open face of the endcap to its tip, while the major
 60      axis spans the radius of the open face itself.
 61
 62      Parameters
 63      ----------
 64      identifier : `str`
 65         Unique identifying name for the object.
 66      material_density_kg_m3 : `float`, optional, default=1.0
 67         Uniform material density in `kg/m^3` to be used in mass property calculations.
 68      major_minor_axis_ratio : `float`, optional, default=2.0
 69         Desired major-to-minor axis ratio of the semiellipsoid.
 70      minor_depends_on_major : `bool`, optional, default=True
 71         Whether the radius of the minor axis depends on the major axis or vice versa.
 72      """
 73      super().__init__(identifier,
 74                       self.__create_cad__,
 75                       'Semiellipsoid.tar.xz',
 76                       material_density_kg_m3)
 77      setattr(self.geometry, 'major_radius', Symbol(self.name + '_major_radius'))
 78      setattr(self.geometry, 'minor_radius', Symbol(self.name + '_minor_radius'))
 79      setattr(self.geometry, 'thickness', Symbol(self.name + '_thickness'))
 80      self.set_geometry(major_axis_radius_m=None,
 81                        minor_axis_radius_m=None,
 82                        thickness_m=None,
 83                        major_minor_axis_ratio=major_minor_axis_ratio,
 84                        minor_depends_on_major=minor_depends_on_major)
 85
 86
 87   # CAD generation function ----------------------------------------------------------------------
 88
 89   @staticmethod
 90   def __create_cad__(params: Dict[str, float], fully_displace: bool) -> Part.Solid:
 91      """Scripted CAD generation method for a `Semiellipsoid`."""
 92      doc = FreeCAD.newDocument('Temp')
 93      thickness_mm = 1000.0 * params['thickness']
 94      outer_major_radius_mm = 1000.0 * params['major_radius']
 95      outer_minor_radius_mm = 1000.0 * params['minor_radius']
 96      inner_major_radius_mm = outer_major_radius_mm - thickness_mm
 97      inner_minor_radius_mm = outer_minor_radius_mm - thickness_mm
 98      outer = doc.addObject('Part::Ellipsoid', 'Ellipsoid')
 99      outer.Radius1 = outer_minor_radius_mm
100      outer.Radius2 = outer_major_radius_mm
101      outer.Radius3 = outer_major_radius_mm
102      outer.Angle1 = 0.0
103      if not fully_displace:
104         inner = doc.addObject('Part::Ellipsoid', 'Ellipsoid')
105         inner.Radius1 = inner_minor_radius_mm
106         inner.Radius2 = inner_major_radius_mm
107         inner.Radius3 = inner_major_radius_mm
108         inner.Angle1 = 0.0
109         doc.recompute()
110         endcap = outer.Shape.cut(inner.Shape)
111      else:
112         doc.recompute()
113         endcap = outer.Shape
114      FreeCAD.closeDocument(doc.Name)
115      return endcap
116
117
118   # Geometry setter ------------------------------------------------------------------------------
119
120   def set_geometry(self, *, major_axis_radius_m: Union[float, None],
121                             minor_axis_radius_m: Union[float, None],
122                             thickness_m: Union[float, None],
123                             major_minor_axis_ratio: float = 2.0,
124                             minor_depends_on_major: bool = True) -> Semiellipsoid:
125      """Sets the physical geometry of the current `Semiellipsoid` object.
126
127      The `major_minor_axis_ratio` and `minor_depends_on_major` parameters are used to determine
128      the relative axis lengths of the Semiellipsoid when one or more of its geometric parameters
129      are symbolic. If all parameters are concretely defined, then these parameters are
130      meaningless.
131
132      See the `Semiellipsoid` class documentation for a description of each geometric parameter.
133      """
134      self.geometry.set(major_radius=major_axis_radius_m,
135                        minor_radius=minor_axis_radius_m,
136                        thickness=thickness_m)
137      if major_axis_radius_m is not None and minor_axis_radius_m is None:
138         self.geometry.minor_radius = major_axis_radius_m / major_minor_axis_ratio
139      elif major_axis_radius_m is None and minor_axis_radius_m is not None:
140         self.geometry.major_radius = minor_axis_radius_m * major_minor_axis_ratio
141      elif major_axis_radius_m is None and minor_axis_radius_m is None:
142         if minor_depends_on_major:
143            self.geometry.minor_radius = self.geometry.major_radius / major_minor_axis_ratio
144         else:
145            self.geometry.major_radius = self.geometry.minor_radius * major_minor_axis_ratio
146      return self
147
148   def get_geometric_parameter_bounds(self, parameter: str) -> Tuple[float, float]:
149      parameter_bounds = {
150         'major_radius': (0.0, 2.0),
151         'minor_radius': (0.0, 2.0),
152         'thickness': (0.0, 0.05)
153      }
154      return parameter_bounds.get(parameter, (0.0, 0.0))
155
156
157   # Geometric properties -------------------------------------------------------------------------
158
159   @property
160   def material_volume(self) -> Union[float, Expr]:
161      volume = self.displaced_volume
162      volume -= (2.0 * math.pi * (self.geometry.major_radius - self.geometry.thickness)**2
163                               * (self.geometry.minor_radius - self.geometry.thickness) / 3.0)
164      return volume
165
166   @property
167   def displaced_volume(self) -> Union[float, Expr]:
168      return 2.0 * math.pi * self.geometry.major_radius**2 * self.geometry.minor_radius / 3.0
169
170   @property
171   def surface_area(self) -> Union[float, Expr]:
172      numerator = (2.0 * (self.geometry.minor_radius * self.geometry.major_radius)**1.6) + \
173                  self.geometry.major_radius**3.2
174      return 2.0 * math.pi * (numerator / 3.0)**(1.0 / 1.6)
175
176   @property
177   def unoriented_center_of_gravity(self) -> Tuple[Union[float, Expr],
178                                                   Union[float, Expr],
179                                                   Union[float, Expr]]:
180      return (self.geometry.major_radius,
181              self.geometry.major_radius,
182              self.__neural_net__.evaluate('cg_z', **self.geometry.as_dict()))
183
184   @property
185   def unoriented_center_of_buoyancy(self) -> Tuple[Union[float, Expr],
186                                                    Union[float, Expr],
187                                                    Union[float, Expr]]:
188      return (self.geometry.major_radius,
189              self.geometry.major_radius,
190              3.0 * self.geometry.minor_radius / 8.0)
191
192   @property
193   def unoriented_length(self) -> Union[float, Expr]:
194      return 2.0 * self.geometry.major_radius
195
196   @property
197   def unoriented_width(self) -> Union[float, Expr]:
198      return self.unoriented_length
199
200   @property
201   def unoriented_height(self) -> Union[float, Expr]:
202      return self.geometry.minor_radius
203
204   @property
205   def oriented_length(self) -> Union[float, Expr]:
206      # TODO: Implement this
207      return 0
208
209   @property
210   def oriented_width(self) -> Union[float, Expr]:
211      # TODO: Implement this
212      return 0
213
214   @property
215   def oriented_height(self) -> Union[float, Expr]:
216      # TODO: Implement this
217      return 0

Model representing a hollow, parametric, semiellipsoidal endcap.

By default, the endcap is oriented such that its base is perpendicular to the z-axis:

Semiellipsoid

The minor axis of this shape spans the open face of the endcap to its tip, while the major axis spans the radius of the open face itself.

The geometry of this shape includes the following parameters:

  • major_radius: Major radius (in m) of the Semiellipsoid along the x- and y-axis
  • minor_radius: Minor radius (in m) of the Semiellipsoid along the z-axis
  • thickness: Thickness (in m) of the shell of the Semiellipsoid

Note that the above dimensions should be interpreted as if the Semiellipsoid is unrotated. In other words, any shape rotation takes place after the Semiellipsoid dimensions have been specified.

Semiellipsoid( identifier: str, material_density_kg_m3: Optional[float] = 1.0, major_minor_axis_ratio: Optional[float] = 2.0, minor_depends_on_major: bool = True)
48   def __init__(self, identifier: str,
49                      material_density_kg_m3: Optional[float] = 1.0,
50                      major_minor_axis_ratio: Optional[float] = 2.0,
51                      minor_depends_on_major: bool = True) -> None:
52      """Initializes a hollow, parametric, ellipsoidal endcap object.
53
54      The `major_minor_axis_ratio` and `minor_depends_on_major` parameters are used to determine
55      the relative axis lengths of the Semiellipsoid when one or more of its geometric parameters
56      are symbolic. If all parameters are concretely defined, then these parameters are
57      meaningless.
58
59      The minor axis of this shape spans the open face of the endcap to its tip, while the major
60      axis spans the radius of the open face itself.
61
62      Parameters
63      ----------
64      identifier : `str`
65         Unique identifying name for the object.
66      material_density_kg_m3 : `float`, optional, default=1.0
67         Uniform material density in `kg/m^3` to be used in mass property calculations.
68      major_minor_axis_ratio : `float`, optional, default=2.0
69         Desired major-to-minor axis ratio of the semiellipsoid.
70      minor_depends_on_major : `bool`, optional, default=True
71         Whether the radius of the minor axis depends on the major axis or vice versa.
72      """
73      super().__init__(identifier,
74                       self.__create_cad__,
75                       'Semiellipsoid.tar.xz',
76                       material_density_kg_m3)
77      setattr(self.geometry, 'major_radius', Symbol(self.name + '_major_radius'))
78      setattr(self.geometry, 'minor_radius', Symbol(self.name + '_minor_radius'))
79      setattr(self.geometry, 'thickness', Symbol(self.name + '_thickness'))
80      self.set_geometry(major_axis_radius_m=None,
81                        minor_axis_radius_m=None,
82                        thickness_m=None,
83                        major_minor_axis_ratio=major_minor_axis_ratio,
84                        minor_depends_on_major=minor_depends_on_major)

Initializes a hollow, parametric, ellipsoidal endcap object.

The major_minor_axis_ratio and minor_depends_on_major parameters are used to determine the relative axis lengths of the Semiellipsoid when one or more of its geometric parameters are symbolic. If all parameters are concretely defined, then these parameters are meaningless.

The minor axis of this shape spans the open face of the endcap to its tip, while the major axis spans the radius of the open face itself.

Parameters
  • identifier (str): Unique identifying name for the object.
  • material_density_kg_m3 (float, optional, default=1.0): Uniform material density in kg/m^3 to be used in mass property calculations.
  • major_minor_axis_ratio (float, optional, default=2.0): Desired major-to-minor axis ratio of the semiellipsoid.
  • minor_depends_on_major (bool, optional, default=True): Whether the radius of the minor axis depends on the major axis or vice versa.
def set_geometry( self, *, major_axis_radius_m: Optional[float], minor_axis_radius_m: Optional[float], thickness_m: Optional[float], major_minor_axis_ratio: float = 2.0, minor_depends_on_major: bool = True) -> Semiellipsoid:
120   def set_geometry(self, *, major_axis_radius_m: Union[float, None],
121                             minor_axis_radius_m: Union[float, None],
122                             thickness_m: Union[float, None],
123                             major_minor_axis_ratio: float = 2.0,
124                             minor_depends_on_major: bool = True) -> Semiellipsoid:
125      """Sets the physical geometry of the current `Semiellipsoid` object.
126
127      The `major_minor_axis_ratio` and `minor_depends_on_major` parameters are used to determine
128      the relative axis lengths of the Semiellipsoid when one or more of its geometric parameters
129      are symbolic. If all parameters are concretely defined, then these parameters are
130      meaningless.
131
132      See the `Semiellipsoid` class documentation for a description of each geometric parameter.
133      """
134      self.geometry.set(major_radius=major_axis_radius_m,
135                        minor_radius=minor_axis_radius_m,
136                        thickness=thickness_m)
137      if major_axis_radius_m is not None and minor_axis_radius_m is None:
138         self.geometry.minor_radius = major_axis_radius_m / major_minor_axis_ratio
139      elif major_axis_radius_m is None and minor_axis_radius_m is not None:
140         self.geometry.major_radius = minor_axis_radius_m * major_minor_axis_ratio
141      elif major_axis_radius_m is None and minor_axis_radius_m is None:
142         if minor_depends_on_major:
143            self.geometry.minor_radius = self.geometry.major_radius / major_minor_axis_ratio
144         else:
145            self.geometry.major_radius = self.geometry.minor_radius * major_minor_axis_ratio
146      return self

Sets the physical geometry of the current Semiellipsoid object.

The major_minor_axis_ratio and minor_depends_on_major parameters are used to determine the relative axis lengths of the Semiellipsoid when one or more of its geometric parameters are symbolic. If all parameters are concretely defined, then these parameters are meaningless.

See the Semiellipsoid class documentation for a description of each geometric parameter.

def get_geometric_parameter_bounds(self, parameter: str) -> Tuple[float, float]:
148   def get_geometric_parameter_bounds(self, parameter: str) -> Tuple[float, float]:
149      parameter_bounds = {
150         'major_radius': (0.0, 2.0),
151         'minor_radius': (0.0, 2.0),
152         'thickness': (0.0, 0.05)
153      }
154      return parameter_bounds.get(parameter, (0.0, 0.0))

Abstract method that must be overridden by a concrete SymPart class to return the minimum and maximum expected bounds for a given geometric parameter.

Parameters
  • parameter (str): Name of the geometric parameter for which to return the minimum and maximum bounds.
Returns
  • Tuple[float, float]: Minimum and maximum bounds for the specified geometric parameter.
material_volume: Union[float, sympy.core.expr.Expr]

Material volume (in m^3) of the SymPart (read-only).

displaced_volume: Union[float, sympy.core.expr.Expr]

Displaced volume (in m^3) of the SymPart (read-only).

surface_area: Union[float, sympy.core.expr.Expr]

Surface/wetted area (in m^2) of the SymPart (read-only).

unoriented_center_of_gravity: Tuple[Union[float, sympy.core.expr.Expr], Union[float, sympy.core.expr.Expr], Union[float, sympy.core.expr.Expr]]

Center of gravity (in m) of the unoriented SymPart (read-only).

unoriented_center_of_buoyancy: Tuple[Union[float, sympy.core.expr.Expr], Union[float, sympy.core.expr.Expr], Union[float, sympy.core.expr.Expr]]

Center of buoyancy (in m) of the unoriented SymPart (read-only).

unoriented_length: Union[float, sympy.core.expr.Expr]

X-axis length (in m) of the bounding box of the unoriented SymPart (read-only).

unoriented_width: Union[float, sympy.core.expr.Expr]

Y-axis width (in m) of the bounding box of the unoriented SymPart (read-only).

unoriented_height: Union[float, sympy.core.expr.Expr]

Z-axis height (in m) of the bounding box of the unoriented SymPart (read-only).

oriented_length: Union[float, sympy.core.expr.Expr]

X-axis length (in m) of the bounding box of the oriented SymPart (read-only).

oriented_width: Union[float, sympy.core.expr.Expr]

Y-axis length (in m) of the bounding box of the oriented SymPart (read-only).

oriented_height: Union[float, sympy.core.expr.Expr]

Z-axis length (in m) of the bounding box of the oriented SymPart (read-only).