我目前正在研究一些Revit API代码,这些代码运行于 欧特克Forge设计自动化云解决方案. 基本上,我是想 创建一个材质并附加一个纹理 通过以下代码。
private void AddTexturePath(AssetProperty asset, string texturePath) {
Asset connectedAsset = null;
if (asset.NumberOfConnectedProperties == 0)
asset.AddConnectedAsset("UnifiedBitmapSchema");
connectedAsset = (Asset) asset.GetConnectedProperty(0);
AssetPropertyString path = (AssetPropertyString) connectedAsset.FindByName(UnifiedBitmap.UnifiedbitmapBitmap);
if (!path.IsValidValue(texturePath)) {
File.Create("texture.png");
texturePath = Path.GetFullPath("texture.png");
}
path.Value = texturePath;
}
这其实是很好用的,因为纹理路径的值:
path.Value = texturePath;
必须是一个现有文件的引用。我在 Forge 的云端实例上没有这个文件,因为纹理名称的路径是由用户在发送 Workitem 请求时指定的。
问题在于,这将材质的纹理路径设置成了这样。
T:\Aces\Jobs\<workitem_id>\texture.png
基本上就是Workitem实例的工作文件夹。这个路径是没用的,因为像这样的纹理路径的材质需要在Revit中手动重新链接。
对我来说,最完美的结果是,如果我能以某种方式将材质纹理路径映射到一些用户友好的目录,如 "C:\Textures\texture.png",似乎Forge实例有一个 "C:\"驱动器(可能是某种Windows实例),但我的代码在低权限下运行,所以它不能在工作目录之外创建任何类型的目录文件。
有人知道如何解决这个问题吗?任何帮助将是非常感激的
经过一整天的研究,我几乎得出了一个满意的解决方案。为了清楚起见--我将参考以下内容 Autodesk Forge Design Automation API for Revit,只是因为 "锻造".
基本上上面提供的代码是正确的。我没有找到任何可能的方法在 Forge 实例上创建一个文件,其目录与 Workitem 工作目录不同。
T:\Aces\Jobs\<workitem_id>\texture.png
有趣的是,在Forge实例上有一个C:\驱动器,其中包含Windows、Revit和.NET框架的安装(因为Forge实例基本上是某种安装了Revit的Windows实例)。可以列举很多这样的目录,但是我试过的所有目录都不允许创建目录或文件(我试过很多--大部分是最明显的、公开访问的Windows目录,如C:\Users\Public,C:\Program Files等)。这与Forge文档中的 "限制 "区域的内容是一致的。
你的应用程序是以低权限运行的,不能与Windows操作系统自由交互。
- 写入访问通常被限制在作业的工作文件夹中。
- 注册表的访问大多受到限制,应避免对注册表的写入。
- 任何子进程也将以低权限执行。
因此,在尝试将 "虚拟 "纹理文件保存在Forge C:/\驱动器的某个地方后,我找到了另一个解决方案-----------------------------。纹理的纹理路径其实并不重要。这是因为Revit提供了一个替代方案来重新链接你的纹理。如果你启动Revit,你可以进入 "文件"-> "选项"-> "渲染",在 "附加渲染外观路径 "字段中,你可以指定你本地机器上的目录,Revit可以用来寻找丢失的纹理。有了这些,你就可以进行以下操作,以便完全控制在Forge上创建材质。
我希望有人会觉得这很有用
此外,根据Jeremy的要求,我发布了一个代码示例,用于在Revit中使用Revit API(在C#中)创建纹理材料和修改不同的外观属性。
private void SetAppearanceParameters(Document project, Material mat, MaterialData data) {
using(Transaction setParameters = new Transaction(project, "Set material parameters")) {
setParameters.Start();
AppearanceAssetElement genericAsset = new FilteredElementCollector(project)
.OfClass(typeof(AppearanceAssetElement))
.ToElements()
.Cast < AppearanceAssetElement > ().Where(i = >i.Name.Contains("Generic"))
.FirstOrDefault();
AppearanceAssetElement newAsset = genericAsset.Duplicate(data.Name);
mat.AppearanceAssetId = newAsset.Id;
using(AppearanceAssetEditScope editAsset = new AppearanceAssetEditScope(project)) {
Asset editableAsset = editAsset.Start(newAsset.Id);
AssetProperty assetProperty = editableAsset["generic_diffuse"];
SetColor(editableAsset, data.MaterialAppearance.Color);
SetGlossiness(editableAsset, data.MaterialAppearance.Gloss);
SetReflectivity(editableAsset, data.MaterialAppearance.Reflectivity);
SetTransparency(editableAsset, data.MaterialAppearance.Transparency);
if (data.MaterialAppearance.Texture != null && data.MaterialAppearance.Texture.Length != 0)
AddTexturePath(assetProperty, $@"C:\{data.MaterialIdentity.Manufacturer}\textures\{data.MaterialAppearance.Texture}");
editAsset.Commit(true);
}
setParameters.Commit();
}
}
private void SetTransparency(Asset editableAsset, int transparency) {
AssetPropertyDouble genericTransparency = editableAsset["generic_transparency"] as AssetPropertyDouble;
genericTransparency.Value = Convert.ToDouble(transparency);
}
private void SetReflectivity(Asset editableAsset, int reflectivity) {
AssetPropertyDouble genericReflectivityZero = (AssetPropertyDouble) editableAsset["generic_reflectivity_at_0deg"];
genericReflectivityZero.Value = Convert.ToDouble(reflectivity) / 100;
AssetPropertyDouble genericReflectivityAngle = (AssetPropertyDouble) editableAsset["generic_reflectivity_at_90deg"];
genericReflectivityAngle.Value = Convert.ToDouble(reflectivity) / 100;
}
private void SetGlossiness(Asset editableAsset, int gloss) {
AssetPropertyDouble glossProperty = (AssetPropertyDouble) editableAsset["generic_glossiness"];
glossProperty.Value = Convert.ToDouble(gloss) / 100;
}
private void SetColor(Asset editableAsset, int[] color) {
AssetPropertyDoubleArray4d genericDiffuseColor = (AssetPropertyDoubleArray4d) editableAsset["generic_diffuse"];
Color newColor = new Color((byte) color[0], (byte) color[1], (byte) color[2]);
genericDiffuseColor.SetValueAsColor(newColor);
}
private void AddTexturePath(AssetProperty asset, string texturePath) {
Asset connectedAsset = null;
if (asset.NumberOfConnectedProperties == 0) asset.AddConnectedAsset("UnifiedBitmapSchema");
connectedAsset = (Asset) asset.GetConnectedProperty(0);
AssetProperty prop = connectedAsset.FindByName(UnifiedBitmap.UnifiedbitmapBitmap);
AssetPropertyString path = (AssetPropertyString) connectedAsset.FindByName(UnifiedBitmap.UnifiedbitmapBitmap);
string fileName = Path.GetFileName(texturePath);
File.Create(fileName);
texturePath = Path.GetFullPath(fileName);
path.Value = texturePath;
}