Measurement#

projected_area(draft, *, surfaces, direction='X', render_quality='medium')[source]#

Compute the rasterized projected silhouette area of selected surfaces.

Parameters:
  • draft (DraftContext) – Draft created from a Geometry resource; supplies the tessellation and any coordinate-system transforms applied to the selected surfaces.

  • surfaces (SurfaceSelection) – Surfaces to project. Accepts a single Surface, a single SurfaceSelector, a list mixing the two, or an EntityList[Surface] (for example my_wall.entities, to reuse a boundary condition’s assignment). Duplicates are removed automatically – there is no need to deduplicate before calling.

  • direction (ProjectionDirection) – Global axis to project along.

  • render_quality (RenderQuality) – Raster resolution preset, and therefore how accurate the result is. The area is measured by counting whole pixels of a rasterized silhouette, so the error is proportional to pixel size: each step up halves it, at roughly four times the computation. Raise this when a small discrepancy matters.

Returns:

Projected area expressed in the geometry’s project length unit squared. Overlapping surfaces are counted once – the result is the silhouette union, not a sum of per-surface areas.

Return type:

unyt_quantity

Example

>>> import flow360 as fl
>>> geometry = fl.Geometry.from_cloud(id="...")
>>> with fl.create_draft(new_run_from=geometry, face_grouping="faceId") as draft:
...     wheels = fl.SurfaceSelector(name="wheels").match("*rim*")
...     body = fl.SurfaceSelector(name="body").match("*body*")
...     area = fl.measure.projected_area(draft, surfaces=[body, wheels], direction="X")

oriented_bounding_box(draft, *, surfaces)[source]#

Compute a PCA-oriented bounding box for selected geometry surfaces.

Parameters:
  • draft (DraftContext) – Draft created from a Geometry resource.

  • surfaces (SurfaceSelection) – Surfaces to bound. Accepts a single Surface, a single SurfaceSelector, a list mixing the two, or an EntityList[Surface]. Duplicates are removed automatically.

Returns:

center and extents are expressed in the geometry’s project length unit; axes stays dimensionless.

Return type:

OBBResult

Example

>>> import flow360 as fl
>>> geometry = fl.Geometry.from_cloud(id="...")
>>> with fl.create_draft(new_run_from=geometry, face_grouping="faceId") as draft:
...     wheel = fl.SurfaceSelector(name="wheel_FL").match("*rim*FL*")
...     obb = fl.measure.oriented_bounding_box(draft, surfaces=wheel)
...     rotation = obb.get_rotation_axis_and_radius(rotation_axis_hint=(0, 1, 0))

projected_area returns a concrete value immediately, which makes it useful for inspecting a geometry or comparing candidate surface sets. The result is the silhouette union of the selected surfaces: overlapping surfaces are counted once, and duplicates in the input are ignored, so there is no need to deduplicate first. It accepts a single Surface, a single SurfaceSelector, a list mixing the two, or an EntityList[Surface].

For a reference area, prefer the recipe: assign ProjectedArea to ReferenceGeometry.area instead of computing a number and storing it. The recipe keeps the surface selection in the uploaded simulation.json, and it is the only path that accounts for half-body meshing automatically – see Reference Geometry.

The result is rasterized rather than integrated exactly, so it carries a small discretization error – on the order of 0.1% at the default settings.

Half-body domains

projected_area measures exactly the surfaces it is given and knows nothing about the meshing settings. With a half_body_* domain its result therefore describes the geometry as uploaded, not the half that gets meshed. Use ProjectedArea rather than scaling the returned value by hand.

DraftContext.compute_obb() remains as a deprecated wrapper around measure.oriented_bounding_box() and is scheduled for removal in release 26.