656 lines
14 KiB
Mathematica
656 lines
14 KiB
Mathematica
(* ::Package:: *)
|
|
|
|
(* ::Title:: *)
|
|
(*Getters*)
|
|
|
|
|
|
(* ::Subtitle:: *)
|
|
(*Get various properties about a grid.*)
|
|
|
|
|
|
(* ::Text:: *)
|
|
(*Copyright Contributors to the OpenVDB Project*)
|
|
(*SPDX-License-Identifier: Apache-2.0*)
|
|
|
|
|
|
(* ::Section:: *)
|
|
(*Initialization & Usage*)
|
|
|
|
|
|
Package["OpenVDBLink`"]
|
|
|
|
|
|
PackageExport["OpenVDBProperty"]
|
|
|
|
|
|
OpenVDBProperty::usage = "OpenVDBProperty[expr, \"prop\"] returns the value of property \"prop\" for the given OpenVDB grid.";
|
|
|
|
|
|
(* ::Section:: *)
|
|
(*Utilities*)
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*getterPropertyFunctions*)
|
|
|
|
|
|
$getterPropertyAssoc = <|
|
|
"ActiveLeafVoxelCount" -> openVDBGetActiveLeafVoxelCount,
|
|
"ActiveTileCount" -> openVDBGetActiveTileCount,
|
|
"ActiveVoxelCount" -> openVDBGetActiveVoxelCount,
|
|
"BackgroundValue" -> openVDBGetBackgroundValue,
|
|
"BoundingGridVoxelCount" -> openVDBGetBoundingGridVoxelCount,
|
|
"CreationDate" -> openVDBGetCreationDate,
|
|
"Creator" -> openVDBGetCreator,
|
|
"Description" -> openVDBGetDescription,
|
|
"Empty" -> openVDBGetEmpty,
|
|
"ExpressionID" -> openVDBGetExpressionID,
|
|
"GammaAdjustment" -> openVDBGetGammaAdjustment,
|
|
"GrayscaleWidth" -> openVDBGetGrayscaleWidth,
|
|
"GridClass" -> openVDBGetGridClass,
|
|
"GridType" -> openVDBGetGridType,
|
|
"HalfWidth" -> openVDBGetHalfwidth,
|
|
"IndexBoundingBox" -> openVDBGetGridBoundingBox,
|
|
"IndexDimensions" -> openVDBGetGridDimensions,
|
|
"LastModifiedDate" -> openVDBGetLastModifiedDate,
|
|
"MaxValue" -> openVDBGetMaxValue,
|
|
"MemoryUsage" -> openVDBGetMemoryUsage,
|
|
"MinValue" -> openVDBGetMinValue,
|
|
"MinMaxValues" -> openVDBGetMinMaxValues,
|
|
"Name" -> openVDBGetName,
|
|
"Properties" -> openVDBGetProperties,
|
|
"PropertyValueGrid" -> openVDBGetPropertyValueGrid,
|
|
"UniformVoxels" -> openVDBGetUniformVoxels,
|
|
"VoxelSize" -> openVDBGetVoxelSize,
|
|
"WorldBoundingBox" -> openVDBGetBoundingBox,
|
|
"WorldDimensions" -> openVDBGetDimensions
|
|
|>;
|
|
|
|
|
|
$allProperties = DeleteCases[Keys[$getterPropertyAssoc], "Properties" | "PropertyValueGrid" | "MinValue" | "MaxValue"];
|
|
|
|
|
|
getterPropertyFunctions[All] := getterPropertyFunctions[$allProperties]
|
|
|
|
|
|
getterPropertyFunctions[props_] :=
|
|
With[{funcs = Lookup[$getterPropertyAssoc, props, $Failed]},
|
|
funcs /; FreeQ[funcs, $Failed, {1}]
|
|
]
|
|
|
|
|
|
getterPropertyFunctions[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*formatProperties*)
|
|
|
|
|
|
formatProperties[Automatic, prop_String, measurement_] := measurement
|
|
formatProperties[Automatic, props_List, measurements_] := formatProperties["List", props, measurements]
|
|
formatProperties[Automatic, All, measurements_] := formatProperties["Association", $allProperties, measurements]
|
|
|
|
|
|
formatProperties[format_, prop_String, measurement_] := formatProperties[format, {prop}, {measurement}]
|
|
formatProperties[format_, All, measurements_] := formatProperties[format, $allProperties, measurements]
|
|
|
|
|
|
formatProperties["Association", props_List, measurements_] := AssociationThread[props, measurements]
|
|
|
|
|
|
formatProperties["Dataset", props_List, measurements_] := Dataset[formatProperties["Association", props, measurements]]
|
|
|
|
|
|
formatProperties["List", props_List, measurements_] := measurements
|
|
|
|
|
|
formatProperties["RuleList", props_List, measurements_] := Thread[props -> measurements]
|
|
|
|
|
|
formatProperties[___] = $Failed
|
|
|
|
|
|
validReturnFormatQ["Association"] = True;
|
|
validReturnFormatQ["Dataset"] = True;
|
|
validReturnFormatQ["List"] = True;
|
|
validReturnFormatQ["RuleList"] = True;
|
|
validReturnFormatQ[Automatic] = True;
|
|
validReturnFormatQ[___] = False;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*OpenVDBGrid overload*)
|
|
|
|
|
|
(vdb_OpenVDBGrid)[key:(_List | _String)] :=
|
|
Block[{lookup, res},
|
|
lookup = Lookup[$getterPropertyAssoc, key];
|
|
(
|
|
res = If[ListQ[lookup],
|
|
Through[lookup[vdb]],
|
|
lookup[vdb]
|
|
];
|
|
|
|
res /; res =!= $Failed
|
|
|
|
) /; !MissingQ[lookup]
|
|
]
|
|
|
|
|
|
(vdb_OpenVDBGrid)[key:(_List | _String), format_] :=
|
|
Block[{res},
|
|
res = OpenVDBProperty[vdb, key, format];
|
|
|
|
res /; res =!= $Failed
|
|
]
|
|
|
|
|
|
(vdb_OpenVDBGrid)[args___] := mOpenVDBProperty[vdb, args]
|
|
|
|
|
|
(* ::Section:: *)
|
|
(*OpenVDBProperty*)
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*Main*)
|
|
|
|
|
|
OpenVDBProperty[args___] /; !CheckArgs[OpenVDBProperty[args], {2, 3}] = $Failed;
|
|
|
|
|
|
OpenVDBProperty[args___] :=
|
|
With[{res = iOpenVDBProperty[args]},
|
|
res /; res =!= $Failed
|
|
]
|
|
|
|
|
|
OpenVDBProperty[args___] := mOpenVDBProperty[args]
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*iOpenVDBProperty*)
|
|
|
|
|
|
iOpenVDBProperty[vdb_?OpenVDBGridQ, props_, format_:Automatic] :=
|
|
Block[{propfuncs, measurements, res},
|
|
propfuncs = getterPropertyFunctions[props];
|
|
(
|
|
measurements = queryVDBProperty[vdb, propfuncs];
|
|
(
|
|
res = formatProperties[format, props, measurements];
|
|
|
|
res /; res =!= $Failed
|
|
|
|
) /; measurements =!= $Failed
|
|
|
|
) /; propfuncs =!= $Failed
|
|
]
|
|
|
|
|
|
iOpenVDBProperty[___] = $Failed;
|
|
|
|
|
|
queryVDBProperty[vdb_, pfunc_List] := Through[pfunc[vdb]]
|
|
|
|
|
|
queryVDBProperty[vdb_, pfunc_] := pfunc[vdb]
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*Argument conform & completion*)
|
|
|
|
|
|
registerForLevelSet[iOpenVDBProperty, 1];
|
|
|
|
|
|
SyntaxInformation[OpenVDBProperty] = {"ArgumentsPattern" -> {_, _, _.}};
|
|
|
|
|
|
addCodeCompletion[OpenVDBProperty][None, Keys[$getterPropertyAssoc], None];
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*Messages*)
|
|
|
|
|
|
mOpenVDBProperty[expr_, ___] /; messageGridQ[expr, OpenVDBProperty] = $Failed;
|
|
|
|
|
|
mOpenVDBProperty[_, props_, ___] /; getterPropertyFunctions[props] === $Failed :=
|
|
(
|
|
If[ListQ[props],
|
|
Message[OpenVDBProperty::props, props],
|
|
Message[OpenVDBProperty::prop, props]
|
|
];
|
|
$Failed
|
|
)
|
|
|
|
|
|
mOpenVDBProperty[_, _, format_] /; !validReturnFormatQ[format] :=
|
|
(
|
|
Message[OpenVDBProperty::frmt, format, 3];
|
|
$Failed
|
|
)
|
|
|
|
|
|
mOpenVDBProperty[___] = $Failed;
|
|
|
|
|
|
OpenVDBProperty::prop = "`1` is not a valid property. Use \"Properties\" to see the list of available properties.";
|
|
OpenVDBProperty::props = "`1` is not a valid list of properties. Use \"Properties\" to see the list of available properties.";
|
|
OpenVDBProperty::frmt = "`1` at position `2` is not one of \"Association\", \"Dataset\", \"List\", \"RuleList\", or Automatic."
|
|
|
|
|
|
(* ::Section:: *)
|
|
(*Getters*)
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetActiveLeafVoxelCount*)
|
|
|
|
|
|
openVDBGetActiveLeafVoxelCount[vdb_] :=
|
|
With[{cnt = vdb["getActiveLeafVoxelCount"[]]},
|
|
cnt /; IntegerQ[cnt] && NonNegative[cnt]
|
|
]
|
|
|
|
|
|
openVDBGetActiveLeafVoxelCount[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetActiveTileCount*)
|
|
|
|
|
|
openVDBGetActiveTileCount[vdb_] :=
|
|
With[{cnt = vdb["getActiveTileCount"[]]},
|
|
cnt /; IntegerQ[cnt] && NonNegative[cnt]
|
|
]
|
|
|
|
|
|
openVDBGetActiveTileCount[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetActiveVoxelCount*)
|
|
|
|
|
|
openVDBGetActiveVoxelCount[vdb_] :=
|
|
With[{cnt = vdb["getActiveVoxelCount"[]]},
|
|
cnt /; IntegerQ[cnt] && NonNegative[cnt]
|
|
]
|
|
|
|
|
|
openVDBGetActiveVoxelCount[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetBackgroundValue*)
|
|
|
|
|
|
openVDBGetBackgroundValue[vdb_?nonMaskGridQ] :=
|
|
With[{bg = vdb["getBackgroundValue"[]]},
|
|
bg /; NumericQ[bg] || ListQ[bg]
|
|
]
|
|
|
|
|
|
openVDBGetBackgroundValue[_?OpenVDBMaskGridQ] = Missing["NotApplicable"];
|
|
|
|
|
|
openVDBGetBackgroundValue[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetBoundingBox*)
|
|
|
|
|
|
openVDBGetBoundingBox[vdb_] :=
|
|
Block[{griddims, voxsize},
|
|
griddims = openVDBGetGridBoundingBox[vdb];
|
|
(
|
|
voxsize = openVDBGetVoxelSize[vdb];
|
|
|
|
voxsize * griddims /; voxsize =!= $Failed
|
|
|
|
) /; griddims =!= $Failed
|
|
]
|
|
|
|
|
|
openVDBGetBoundingBox[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetBoundingGridVoxelCount*)
|
|
|
|
|
|
openVDBGetBoundingGridVoxelCount[vdb_] :=
|
|
With[{dims = openVDBGetGridDimensions[vdb]},
|
|
Times @@ dims /; dims =!= $Failed
|
|
]
|
|
|
|
|
|
openVDBGetBoundingGridVoxelCount[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetCreationDate*)
|
|
|
|
|
|
openVDBGetCreationDate[vdb_] :=
|
|
Block[{res},
|
|
res = Quiet @ vdb["getIntegerMetadata"["creation_date"]];
|
|
If[IntegerQ[res],
|
|
FromUnixTime[res],
|
|
Missing["NotAvailable"]
|
|
]
|
|
]
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetCreator*)
|
|
|
|
|
|
openVDBGetCreator[vdb_] :=
|
|
With[{name = vdb["getCreator"[]]},
|
|
If[StringQ[name] && StringLength[name] > 0,
|
|
name,
|
|
Missing["NotAvailable"]
|
|
]
|
|
]
|
|
|
|
|
|
openVDBGetCreator[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetDescription*)
|
|
|
|
|
|
openVDBGetDescription[vdb_] :=
|
|
Block[{res},
|
|
res = Quiet @ vdb["getStringMetadata"["description"]];
|
|
If[StringQ[res] && StringLength[res] > 0,
|
|
res,
|
|
Missing["NotAvailable"]
|
|
]
|
|
]
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetDimensions*)
|
|
|
|
|
|
openVDBGetDimensions[vdb_] :=
|
|
Block[{griddims, voxsize},
|
|
griddims = openVDBGetGridDimensions[vdb];
|
|
(
|
|
voxsize = openVDBGetVoxelSize[vdb];
|
|
|
|
voxsize * griddims /; voxsize =!= $Failed
|
|
|
|
) /; griddims =!= $Failed
|
|
]
|
|
|
|
|
|
openVDBGetDimensions[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetEmpty*)
|
|
|
|
|
|
openVDBGetEmpty[vdb_] := emptyVDBQ[vdb]
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetExpressionID*)
|
|
|
|
|
|
openVDBGetExpressionID[_[id_, ___]] := id
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetGammaAdjustment*)
|
|
|
|
|
|
openVDBGetGammaAdjustment[vdb_?fogVolumeQ] :=
|
|
Block[{res},
|
|
res = Quiet @ vdb["getRealMetadata"["gamma_adjustment"]];
|
|
If[NumberQ[res],
|
|
res,
|
|
Missing["NotAvailable"]
|
|
]
|
|
]
|
|
|
|
|
|
openVDBGetGammaAdjustment[___] = Missing["NotApplicable"];
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetGrayscaleWidth*)
|
|
|
|
|
|
openVDBGetGrayscaleWidth[vdb_?fogVolumeQ] :=
|
|
Block[{res},
|
|
res = Quiet[Divide[vdb["getRealMetadata"["cutoff_distance"]], vdb["getRealMetadata"["scaling_factor"]]]];
|
|
If[NumberQ[res],
|
|
res,
|
|
Missing["NotAvailable"]
|
|
]
|
|
]
|
|
|
|
|
|
openVDBGetGrayscaleWidth[___] = Missing["NotApplicable"];
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetGridBoundingBox*)
|
|
|
|
|
|
openVDBGetGridBoundingBox[vdb_] :=
|
|
With[{bbox = vdb["getGridBoundingBox"[]]},
|
|
bbox /; MatrixQ[bbox, IntegerQ] && Dimensions[bbox] === {3, 2}
|
|
]
|
|
|
|
|
|
openVDBGetGridBoundingBox[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetGridClass*)
|
|
|
|
|
|
openVDBGetGridClass[vdb_ /; !OpenVDBScalarGridQ[vdb]] = Missing["NotApplicable"];
|
|
|
|
|
|
openVDBGetGridClass[vdb_] :=
|
|
With[{gc = vdb["getGridClass"[]]},
|
|
gridClassName[gc] /; IntegerQ[gc]
|
|
]
|
|
|
|
|
|
openVDBGetGridClass[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetGridDimensions*)
|
|
|
|
|
|
openVDBGetGridDimensions[vdb_] :=
|
|
With[{bbox = vdb["getGridDimensions"[]]},
|
|
bbox /; VectorQ[bbox, IntegerQ] && Length[bbox] === 3
|
|
]
|
|
|
|
|
|
openVDBGetGridDimensions[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetGridType*)
|
|
|
|
|
|
openVDBGetGridType[vdb_] :=
|
|
With[{type = vdb["getGridType"[]]},
|
|
If[StringQ[type],
|
|
type,
|
|
Missing["NotAvailable"]
|
|
]
|
|
]
|
|
|
|
|
|
openVDBGetGridType[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetHalfwidth*)
|
|
|
|
|
|
openVDBGetHalfwidth[vdb_?levelSetQ] :=
|
|
With[{hw = halfWidth[vdb]},
|
|
If[TrueQ[Positive[hw]],
|
|
hw,
|
|
Missing["NotAvailable"]
|
|
]
|
|
]
|
|
|
|
|
|
openVDBGetHalfwidth[___] = Missing["NotApplicable"];
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetLastModifiedDate*)
|
|
|
|
|
|
openVDBGetLastModifiedDate[vdb_] :=
|
|
Block[{res},
|
|
res = Quiet @ vdb["getIntegerMetadata"["last_modified_date"]];
|
|
If[IntegerQ[res],
|
|
FromUnixTime[res],
|
|
Missing["NotAvailable"]
|
|
]
|
|
]
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetMaxValue*)
|
|
|
|
|
|
openVDBGetMaxValue[vdb_?nonMaskGridQ] :=
|
|
With[{minmax = openVDBGetMinMaxValues[vdb]},
|
|
minmax[[2]] /; ListQ[minmax]
|
|
]
|
|
|
|
|
|
openVDBGetMaxValue[_?OpenVDBMaskGridQ] = Missing["NotApplicable"];
|
|
|
|
|
|
openVDBGetMaxValue[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetMemoryUsage*)
|
|
|
|
|
|
openVDBGetMemoryUsage[vdb_] :=
|
|
With[{cnt = vdb["getMemoryUsage"[]]},
|
|
cnt /; IntegerQ[cnt] && NonNegative[cnt]
|
|
]
|
|
|
|
|
|
openVDBGetMemoryUsage[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetMinValue*)
|
|
|
|
|
|
openVDBGetMinValue[vdb_?nonMaskGridQ] :=
|
|
With[{minmax = openVDBGetMinMaxValues[vdb]},
|
|
minmax[[1]] /; ListQ[minmax]
|
|
]
|
|
|
|
|
|
openVDBGetMinValue[_?OpenVDBMaskGridQ] = Missing["NotApplicable"];
|
|
|
|
|
|
openVDBGetMinValue[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetMinMaxValues*)
|
|
|
|
|
|
openVDBGetMinMaxValues[vdb_?nonMaskGridQ] :=
|
|
With[{minmax = vdb["getMinMaxValues"[]]},
|
|
minmax /; ArrayQ[minmax, _, NumericQ] && Length[minmax] === 2
|
|
]
|
|
|
|
|
|
openVDBGetMinMaxValues[_?OpenVDBMaskGridQ] = Missing["NotApplicable"];
|
|
|
|
|
|
openVDBGetMinMaxValues[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetName*)
|
|
|
|
|
|
openVDBGetName[vdb_] :=
|
|
With[{name = vdb["getName"[]]},
|
|
If[StringQ[name] && StringLength[name] > 0,
|
|
name,
|
|
Missing["NotAvailable"]
|
|
]
|
|
]
|
|
|
|
|
|
openVDBGetName[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetProperties*)
|
|
|
|
|
|
openVDBGetProperties[_] := Keys[$getterPropertyAssoc]
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetPropertyValueGrid*)
|
|
|
|
|
|
openVDBGetPropertyValueGrid[vdb_] :=
|
|
Grid[
|
|
DeleteCases[List @@@ OpenVDBProperty[vdb, All, "RuleList"], {_, Missing["NotApplicable"]}],
|
|
Alignment -> {{Right, Left}},
|
|
Frame -> All,
|
|
Spacings -> {1, 0.75}
|
|
]
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetUniformVoxels*)
|
|
|
|
|
|
openVDBGetUniformVoxels[vdb_] :=
|
|
With[{uniform = vdb["getHasUniformVoxels"[]]},
|
|
uniform /; BooleanQ[uniform]
|
|
]
|
|
|
|
|
|
openVDBGetUniformVoxels[___] = $Failed;
|
|
|
|
|
|
(* ::Subsection::Closed:: *)
|
|
(*openVDBGetVoxelSize*)
|
|
|
|
|
|
openVDBGetVoxelSize[vdb_] :=
|
|
With[{vx = voxelSize[vdb]},
|
|
vx /; NumericQ[vx]
|
|
]
|
|
|
|
|
|
openVDBGetVoxelSize[___] = $Failed;
|