(* ::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.";