Files
UnrealEngine/Engine/Source/ThirdParty/OpenVDB/openvdb-12.0.0/openvdb_wolfram/OpenVDBLink/IO.m
2025-05-18 13:04:45 +08:00

301 lines
6.0 KiB
Mathematica

(* ::Package:: *)
(* ::Title:: *)
(*IO*)
(* ::Subtitle:: *)
(*Import & export vdb.*)
(* ::Text:: *)
(*Copyright Contributors to the OpenVDB Project*)
(*SPDX-License-Identifier: Apache-2.0*)
(* ::Section:: *)
(*Initialization & Usage*)
Package["OpenVDBLink`"]
PackageExport["OpenVDBImport"]
PackageExport["OpenVDBExport"]
OpenVDBImport::usage = "OpenVDBImport[\"file.vdb\"] imports an OpenVDB grid.";
OpenVDBExport::usage = "OpenVDBExport[\"file.vdb\", expr] exports data from an OpenVDB grid into a file.";
(* ::Section:: *)
(*VDB*)
(* ::Subsection::Closed:: *)
(*OpenVDBImport*)
(* ::Subsubsection::Closed:: *)
(*Main*)
OpenVDBImport[args___] /; !CheckArgs[OpenVDBImport[args], {1, 3}] = $Failed;
OpenVDBImport[args___] :=
With[{res = iOpenVDBImport[args]},
res /; res =!= $Failed
]
OpenVDBImport[args___] := mOpenVDBImport[args]
(* ::Subsubsection::Closed:: *)
(*iOpenVDBImport*)
iOpenVDBImport[File[file_String], args___] := iOpenVDBImport[file, args]
iOpenVDBImport[file_String] := iOpenVDBImport[file, Automatic]
iOpenVDBImport[url_?URLStringQ, args___] :=
Block[{extension, tempfile, dl, res},
extension = urlExtension[url];
tempfile = FileNameJoin[{$TemporaryDirectory, "temp." <> extension}];
If[FileExistsQ[tempfile],
Quiet[DeleteFile[tempfile]];
];
dl = Quiet[URLDownload[url, tempfile]];
(
res = iOpenVDBImport[tempfile, args];
Quiet[DeleteFile[tempfile]];
res /; OpenVDBGridQ[res]
) /; FileExistsQ[tempfile]
]
iOpenVDBImport[file_?zipFileQ, args___] :=
Block[{vdbfile, res},
vdbfile = extractVDBZIP[file];
(
res = iOpenVDBImport[vdbfile, args];
Quiet[DeleteFile[vdbfile]];
res /; OpenVDBGridQ[res]
) /; FileExistsQ[vdbfile]
]
iOpenVDBImport[file_String?FileExistsQ, iname_, itype_:Automatic] :=
Block[{name, type, vdb, id, successQ},
name = If[StringQ[iname], iname, ""];
type = If[itype === Automatic, detectVDBType[file, name], itype];
(
vdb = OpenVDBCreateGrid[1.0, type];
(
successQ = vdb["importVDB"[file, name]];
vdb /; successQ
) /; OpenVDBGridQ[vdb]
) /; type =!= $Failed
]
iOpenVDBImport[___] = $Failed;
(* ::Subsubsection::Closed:: *)
(*Argument conform & completion*)
SyntaxInformation[OpenVDBImport] = {"ArgumentsPattern" -> {_, _., _.}};
addCodeCompletion[OpenVDBImport][None, None, $gridTypeList];
(* ::Subsubsection::Closed:: *)
(*Utilities*)
detectVDBType[file_, name_] :=
Block[{vdb, type, wltype},
(* create a grid of any type since it has the base methods *)
vdb = OpenVDBCreateGrid[1.0, "Scalar"];
type = vdb["importVDBType"[file, name]];
(
wltype = fromInternalType[type];
wltype /; StringQ[wltype]
) /; StringQ[type]
]
detectVDBType[___] = $Failed;
URLStringQ[url_String?StringQ] := StringMatchQ[url, "http://*" | "ftp://*" | "https://*"]
URLStringQ[___] = False;
urlExtension[url_] := Replace[StringCases[StringDelete[url, Longest["?" ~~ ___ ~~ EndOfString]], Shortest["." ~~ __ ~~ EndOfString]], {} -> {"vdb"}, 0][[1]]
urlExtension[___] = "vdb";
zipFileQ[file_String?StringQ] := ToLowerCase[FileExtension[file]] === "zip"
zipFileQ[___] = False;
vdbFileQ[file_String?StringQ] := ToLowerCase[FileExtension[file]] === "vdb"
vdbFileQ[___] = False;
extractVDBZIP[file_] :=
Block[{files, vdbfiles},
files = Quiet[Import[file, "FileNames"]];
(
vdbfiles = Quiet[ExtractArchive[file, $TemporaryDirectory]];
vdbfiles[[1]] /; MatchQ[vdbfiles, {_?StringQ}] && FileExistsQ[vdbfiles[[1]]]
) /; MatchQ[files, {_?vdbFileQ}]
]
extractVDBZIP[___] = $Failed;
(* ::Subsubsection::Closed:: *)
(*Messages*)
mOpenVDBImport[expr_, ___] /; !FileExistsQ[expr] :=
(
Message[OpenVDBImport::nffil, expr, Import];
$Failed
)
mOpenVDBImport[expr_, _, type_, ___] /; type =!= Automatic && !MemberQ[$gridTypeList, type] :=
(
Message[OpenVDBImport::type, type];
$Failed
)
mOpenVDBImport[___] = $Failed;
OpenVDBImport::nffil = "File `1` not found during `2`.";
OpenVDBImport::type = "`1` is not a supported grid type. Evaluate OpenVDBGridTypes[] to see the list of supported types."
(* ::Subsection::Closed:: *)
(*OpenVDBExport*)
(* ::Subsubsection::Closed:: *)
(*Main*)
Options[OpenVDBExport] = {OverwriteTarget -> False};
OpenVDBExport[args___] /; !CheckArgs[OpenVDBExport[args], {1, 2}] = $Failed;
OpenVDBExport[args___] :=
With[{res = iOpenVDBExport[args]},
res /; res =!= $Failed
]
OpenVDBExport[args___] := mOpenVDBExport[args]
(* ::Subsubsection::Closed:: *)
(*iOpenVDBExport*)
Options[iOpenVDBExport] = Options[OpenVDBExport];
iOpenVDBExport[File[file_String], args___] := iOpenVDBExport[file, args]
iOpenVDBExport[file_String, vdb_?OpenVDBGridQ, OptionsPattern[]] :=
If[fileExportQ[file, OptionValue[OverwriteTarget]],
vdb["exportVDB"[file]];
file,
$Failed
]
iOpenVDBExport[___] = $Failed;
(* ::Subsubsection::Closed:: *)
(*Argument conform & completion*)
registerForLevelSet[iOpenVDBExport, 2];
SyntaxInformation[OpenVDBExport] = {"ArgumentsPattern" -> {_, _, OptionsPattern[]}};
(* ::Subsubsection::Closed:: *)
(*fileExportQ*)
fileExportQ[filename_, overwriteQ_] :=
If[!FileExistsQ[filename],
True,
If[TrueQ[overwriteQ],
True,
Message[OpenVDBExport::filex, filename];
False
]
];
OpenVDBExport::filex = "Cannot overwrite existing file `1`.";
(* ::Subsubsection::Closed:: *)
(*Messages*)
mOpenVDBExport[expr_, ___] /; !MatchQ[expr, File[_String]|_String] :=
(
Message[OpenVDBExport::chtype, expr];
$Failed
)
mOpenVDBExport[_, expr_, ___] /; messageGridQ[expr, OpenVDBExport] = $Failed;
mOpenVDBExport[___] = $Failed;
OpenVDBExport::chtype = "First argument `1` is not a valid file specification.";