初步完成导出,待优化顶点

This commit is contained in:
zhangXQ 2021-02-21 23:36:45 +08:00
parent 06a8c36d6b
commit e5e28afc3f
22 changed files with 2314 additions and 0 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30320.27
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NwGeoExporter", "NwGeoExporter\NwGeoExporter.csproj", "{7EC625E4-E75B-40C5-83A4-407D427B74CE}"
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Installer", "Installer\Installer.vdproj", "{9BAC4FE1-B316-41B9-B908-5981C2477A3F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7EC625E4-E75B-40C5-83A4-407D427B74CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EC625E4-E75B-40C5-83A4-407D427B74CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EC625E4-E75B-40C5-83A4-407D427B74CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EC625E4-E75B-40C5-83A4-407D427B74CE}.Release|Any CPU.Build.0 = Release|Any CPU
{9BAC4FE1-B316-41B9-B908-5981C2477A3F}.Debug|Any CPU.ActiveCfg = Debug
{9BAC4FE1-B316-41B9-B908-5981C2477A3F}.Release|Any CPU.ActiveCfg = Release
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AFF13710-5A2E-4029-8150-67359B2AF996}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Navisworks.Api.Interop.ComApi;
using NwGeoExporter.Models;
using NwGeoExporter.NwUtils;
namespace NwGeoExporter
{
public class CustomExporter : InwSimplePrimitivesCB
{
private TransformM transform3D;
public CustomExporter()
{
Triangles = new List<Triangle>();
}
public CustomExporter(TransformM transform3D):this()
{
this.transform3D = transform3D;
}
public List<Triangle> Triangles { get; set; }
public void Triangle(InwSimpleVertex v1, InwSimpleVertex v2, InwSimpleVertex v3)
{
var vertices = new PointM[]
{
transform3D.OfPoint(new PointM(v1)),
transform3D.OfPoint(new PointM(v2)),
transform3D.OfPoint(new PointM(v3)),
};
var normals = new VectorM[]
{
new VectorM(v1),
new VectorM(v2),
new VectorM(v3),
};
//Triangles.Add(new Triangle(v1,v2,v3));
Triangles.Add(new Triangle(normals,vertices));
}
public void Line(InwSimpleVertex v1, InwSimpleVertex v2)
{
}
public void Point(InwSimpleVertex v1)
{
}
public void SnapPoint(InwSimpleVertex v1)
{
}
}
}

View File

@ -0,0 +1,72 @@
using Autodesk.Navisworks.Api;
using Newtonsoft.Json;
using NwGeoExporter.NwEx;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NwGeoExporter.Models
{
public class Instance
{
/// <summary>
/// 构件ID
/// </summary>
public string id { get; set; }
/// <summary>
/// 转换
/// </summary>
[JsonIgnore]
public TransformM Transform { get; set; }
///// <summary>
///// 转换-序列化(列主序)
///// </summary>
//public double[] transform
//{
// get
// {
// return new double[]
// {
// Transform.BasicX.X,Transform.BasicX.Y,Transform.BasicX.Z,0
// ,Transform.BasicY.X,Transform.BasicY.Y,Transform.BasicY.Z,0
// ,Transform.BasicZ.X,Transform.BasicZ.Y,Transform.BasicZ.Z,0
// ,Transform.Origin.X,Transform.Origin.Y,Transform.Origin.Z,1
// };
// }
//}
/// <summary>
/// 转换-序列化(行主序)
/// </summary>
public double[] transform
{
get
{
return new double[]
{
Transform.BasicX.X,Transform.BasicX.Y,Transform.BasicX.Z,0
,Transform.BasicY.X,Transform.BasicY.Y,Transform.BasicY.Z,0
,Transform.BasicZ.X,Transform.BasicZ.Y,Transform.BasicZ.Z,0
,Transform.Origin.X,Transform.Origin.Y,Transform.Origin.Z,1
};
}
}
/// <summary>
/// 是否可见
/// </summary>
public double visible { get; set; }
/// <summary>
/// 三角面片索引
/// </summary>
public int mesh { get; set; }
/// <summary>
/// 构件信息
/// </summary>
public Dictionary<string, string> info { get; set; }
}
}

View File

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NwGeoExporter.Models
{
public class Material
{
/// <summary>
/// 十六进制颜色
/// </summary>
public string color { get; set; }
/// <summary>
/// 透明度
/// </summary>
public double transparment { get; set; }
public Material()
{
}
public Material(string color, double transparment)
{
this.color = color;
this.transparment = transparment;
}
public override bool Equals(object obj)
{
if (obj is Material mat)
{
return mat.color == color && mat.transparment == transparment;
}
return true;
}
public override int GetHashCode()
{
return 0;
}
}
}

View File

@ -0,0 +1,114 @@
using Autodesk.Navisworks.Api.Interop.ComApi;
using Newtonsoft.Json;
using NwGeoExporter.NwEx;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NwGeoExporter.Models
{
public class Mesh
{
/// <summary>
/// 顶点数组-序列化数据
/// </summary>
public double[] vertices { get => VerticeList.SelectMany(x => new List<double> { x.X.Feet2Mm(), x.Y.Feet2Mm(), x.Z.Feet2Mm() }).ToArray(); }
//public double[] vertices { get => VerticeList.SelectMany(x => new List<double> { x.X, x.Y, x.Z }).ToArray(); }
/// <summary>
/// 顶点索引-序列化数据
/// </summary>
public int[] indices { get => IndiceList.ToArray(); }
/// <summary>
/// 顶点法向-序列化数据
/// </summary>
public double[] normals { get => NormalList.SelectMany(x => new List<double> { x.X, x.Y, x.Z }).ToArray(); }
/// <summary>
/// 顶点集合
/// </summary>
[JsonIgnore]
public List<PointM> VerticeList { get; set; }
/// <summary>
/// 顶点法线
/// </summary>
[JsonIgnore]
public List<VectorM> NormalList { get; set; }
/// <summary>
/// 顶点索引
/// </summary>
[JsonIgnore]
public List<int> IndiceList { get; set; }
/// <summary>
/// 材质索引
/// </summary>
public int material { get; set; }
public Mesh(int materialIndex)
{
VerticeList = new List<PointM>();
NormalList = new List<VectorM>();
IndiceList = new List<int>();
material = materialIndex;
}
public Mesh(IEnumerable<Triangle> triangles, int materialIndex) : this(materialIndex)
{
this.AddTriangles(triangles);
}
public Mesh(Triangle triangle, int materialIndex) : this(materialIndex)
{
this.AddTriangle(triangle);
}
public void AddTriangle(Triangle triangle)
{
for (int i = 0; i < triangle.Vertices.Length; i++)
{
// bool isHandle = false;
// for (int j = 0; j < VerticeList.Count; j++)
// {
// if (VerticeList[j] == triangle.vertices[i])
// {
// //拿到索引集合中与当前顶点值一样的索引
// List<int> indexList = IndiceList.FindIndexs(x => x == j);
// //TODO考虑多个的情况
// //第几个需要跟当前顶点法向进行平均
// int index = indexList.FindIndex(x => NormalList[x]
// .AngelTo(triangle.normals[i]).ToAngle() - 90 > 0.1);
// //有遇到顶点法线平均
// if (index != -1)
// {
// NormalList[j] = (triangle.normals[i] + NormalList[j]).Normalize();
// isHandle = true;
// break;
// }
// }
// }
// if (!isHandle)
// {
//添加顶点以及顶点法向以及对应的索引
VerticeList.Add(triangle.Vertices[i]);
NormalList.Add(triangle.Normals[i]);
IndiceList.Add(VerticeList.Count - 1);
}
//}
}
public void AddTriangles(IEnumerable<Triangle> triangles)
{
foreach (var triangle in triangles)
{
this.AddTriangle(triangle);
}
}
}
}

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NwGeoExporter.Models
{
public class NwModel
{
public Instance[] instances { get; set; }
public Mesh[] meshes { get; set; }
public Material[] materials { get; set; }
public NwModel()
{
}
public NwModel(List<Instance> instanceList, List<Mesh> meshList, List<Material> materailList)
{
instances = instanceList.ToArray();
meshes = meshList.ToArray();
materials = materailList.ToArray();
}
}
}

View File

@ -0,0 +1,65 @@
using Autodesk.Navisworks.Api.Interop.ComApi;
using NwGeoExporter.NwEx;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NwGeoExporter.Models
{
public class PointM
{
public double X { get; private set; }
public double Y { get; private set; }
public double Z { get; private set; }
public PointM()
{
X = 0;
Y = 0;
Z = 0;
}
public PointM(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
}
public PointM(InwSimpleVertex v)
{
Array array_v = (Array)(object)v.coord;
X = (float)array_v.GetValue(1);
Y = (float)array_v.GetValue(2);
Z = (float)array_v.GetValue(3);
}
public override bool Equals(object obj)
{
if (obj is PointM pm)
{
if (pm.X.Round(6) == X.Round(6) && pm.Y.Round(6) == Y.Round(6) && pm.Z.Round(6) == Z.Round(6))
return true;
}
return false;
}
public override int GetHashCode()
{
return 0;
}
public static bool operator ==(PointM pm1, PointM pm2)
{
return pm1.Equals(pm2);
}
public static bool operator !=(PointM pm1, PointM pm2)
{
return !pm1.Equals(pm2);
}
}
}

View File

@ -0,0 +1,74 @@
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Interop.ComApi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NwGeoExporter.NwEx;
namespace NwGeoExporter.Models
{
public class TransformM
{
public VectorM BasicX { get; set; }
public VectorM BasicY { get; set; }
public VectorM BasicZ { get; set; }
public PointM Origin { get; set; }
public static TransformM Identify
{
get =>
new TransformM
{
BasicX = VectorM.BasicX,
BasicY = VectorM.BasicY,
BasicZ = VectorM.BasicZ,
Origin = new PointM(),
};
}
private InwLTransform3f3 inwTransform;
private TransformM()
{
}
/// <summary>
/// 将NW的列主序转换变成自定义的转换
/// </summary>
/// <param name="inwTransform"></param>
public TransformM(InwLTransform3f3 inwTransform)
{
double[] matrixElements = ((Array)(object)inwTransform.Matrix).ToArray<double>();
BasicX = new VectorM(matrixElements[0], matrixElements[1], matrixElements[2]);
BasicY = new VectorM(matrixElements[4], matrixElements[5], matrixElements[6]);
BasicZ = new VectorM(matrixElements[8], matrixElements[9], matrixElements[10]);
Origin = new PointM(matrixElements[12], matrixElements[13], matrixElements[14]);
this.inwTransform = inwTransform;
}
public PointM OfPoint(PointM point)
{
double[] matrixElements = ((Array)(object)inwTransform.Matrix).ToArray<double>();
double x = point.X;
double y = point.Y;
double z = point.Z;
double w = matrixElements[3] * x + matrixElements[7] * y + matrixElements[11] * z + matrixElements[15];
return new PointM(
(matrixElements[0] * x + matrixElements[4] * y + matrixElements[8] * z + matrixElements[12]) / w,
(matrixElements[1] * x + matrixElements[5] * y + matrixElements[9] * z + matrixElements[13]) / w,
(matrixElements[2] * x + matrixElements[6] * y + matrixElements[10] * z + matrixElements[14]) / w);
}
//public PointM OfPoint(PointM point)
//{
// double x = point.X;
// double y = point.Y;
// double z = point.Z;
// return
// new PointM(
// BasicX.X * x + BasicY.X * y + BasicZ.X * z + Origin.X,
// BasicX.Y * x + BasicY.Y * y + BasicZ.Y * z + Origin.Y,
// BasicX.Z * x + BasicY.Z * y + BasicZ.Z * z + Origin.Z
// );
//}
}
}

View File

@ -0,0 +1,39 @@
using Autodesk.Navisworks.Api.Interop.ComApi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NwGeoExporter.Models
{
public class Triangle
{
public Triangle()
{
Vertices = new PointM[3];
Normals = new VectorM[3];
}
public Triangle(VectorM[] normals,PointM[] vertices)
{
Vertices = vertices;
Normals = normals;
}
public Triangle(InwSimpleVertex v1, InwSimpleVertex v2, InwSimpleVertex v3):this()
{
//点
Vertices[0] = new PointM(v1);
Vertices[1] = new PointM(v2);
Vertices[2] = new PointM(v3);
//法向
Normals[0] = new VectorM(v1);
Normals[1] = new VectorM(v2);
Normals[2] = new VectorM(v3);
}
public PointM[] Vertices { get; private set; }
public VectorM[] Normals { get; private set; }
}
}

View File

@ -0,0 +1,91 @@
using Autodesk.Navisworks.Api.Interop.ComApi;
using Newtonsoft.Json;
using NwGeoExporter.NwEx;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NwGeoExporter.Models
{
public class VectorM
{
public double X { get; private set; }
public double Y { get; private set; }
public double Z { get; private set; }
private double _length;
public VectorM()
{
}
public VectorM(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
_length = Math.Sqrt(X * X + Y * Y + Z * Z);
}
public VectorM(InwSimpleVertex v)
{
Array array = (Array)(object)v.normal;
X = (float)array.GetValue(1);
Y = (float)array.GetValue(2);
Z = (float)array.GetValue(3);
}
/// <summary>
/// 点积
/// </summary>
/// <param name="vetor"></param>
/// <returns></returns>
public double DotProduct(VectorM vetor)
{
return X * X + Y * Y + Z * Z;
}
/// <summary>
/// 0→PI夹角计算
/// </summary>
/// <param name="vetor"></param>
/// <returns></returns>
public double AngelTo(VectorM vetor)
{
return Math.Acos(DotProduct(vetor) / (_length * vetor._length));
}
/// <summary>
/// 向量单位化
/// </summary>
/// <returns></returns>
public VectorM Normalize()
{
return new VectorM(X / _length, Y / _length, Z / _length);
}
public static VectorM BasicX { get => new VectorM(1, 0, 0); }
public static VectorM BasicY { get => new VectorM(0, 1, 0); }
public static VectorM BasicZ { get => new VectorM(0, 0, 1); }
public static VectorM operator +(VectorM vetor1, VectorM vetor2)
{
return new VectorM(vetor1.X + vetor2.X, vetor1.Y + vetor2.Y, vetor1.Z + vetor2.Z);
}
public override bool Equals(object obj)
{
if (obj is VectorM pm)
{
if (pm.X.Round(6) == X.Round(6) && pm.Y.Round(6) == Y.Round(6) && pm.Z.Round(6) == Z.Round(6))
return true;
}
return false;
}
public override int GetHashCode()
{
return 0;
}
}
}

View File

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NwGeoExporter.NwEx
{
public static class IEnumerableEx
{
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="arr"></param>
/// <returns></returns>
public static T[] ToArray<T>(this Array arr)
{
T[] result = new T[arr.Length];
Array.Copy(arr, result, result.Length);
return result;
}
/// <summary>
/// 找到第一个索引
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="array"></param>
/// <param name="func"></param>
/// <returns></returns>
public static int FindIndex<T>(this IEnumerable<T> array, Func<T, bool> func)
{
if (func == null) return -1;
for (int i = 0; i < array.Count(); i++)
{
var t = array.ElementAt(i);
if (func(t))
{
return i;
}
}
return -1;
}
/// <summary>
/// 找到所有的索引
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="array"></param>
/// <param name="func"></param>
/// <returns></returns>
public static List<int> FindIndexs<T>(this IEnumerable<T> array, Func<T, bool> func)
{
List<int> indexList = new List<int>();
if (func == null) return null;
for (int i = 0; i < array.Count(); i++)
{
var t = array.ElementAt(i);
if (func(t))
{
indexList.Add(i);
}
}
return indexList.Count == 0 ? null : indexList;
}
}
}

View File

@ -0,0 +1,28 @@
using Autodesk.Navisworks.Api;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NwGeoExporter.NwEx
{
public static class MathEx
{
public static double Round(this double d,int count)
{
return Math.Round(d, count);
}
public static double ToAngle(this double rad)
{
return rad / Math.PI * 180;
}
public static double Feet2Mm(this double feet)
{
return UnitConversion.ScaleFactor(Units.Feet,Units.Millimeters)*feet;
}
}
}

View File

@ -0,0 +1,22 @@
using Autodesk.Navisworks.Api;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NwGeoExporter.NwEx
{
public static class Vector3DEx
{
public static Vector3D SetZ(this Vector3D vector, double z = 0)
{
return new Vector3D(vector.X, vector.Y, z);
}
public static Vector3D AddZ(this Vector3D vector, double z)
{
return new Vector3D(vector.X, vector.Y, vector.Z + z);
}
}
}

View File

@ -0,0 +1,170 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Plugins;
using ComBridge = Autodesk.Navisworks.Api.ComApi.ComApiBridge;
using COMApi = Autodesk.Navisworks.Api.Interop.ComApi;
using NwGeoExporter.NwUtils;
using Autodesk.Navisworks.Api.Interop.ComApi;
using NwGeoExporter.Models;
using System.Windows.Forms;
using System.IO;
using Application = Autodesk.Navisworks.Api.Application;
using System.Diagnostics;
using static NwGeoExporter.NwUtils.PropertyUtils;
using NwGeoExporter.NwEx;
namespace NwGeoExporter
{
#region NW Plugin
[Plugin("Nw导出", "uBIM")]
[AddInPlugin(AddInLocation.AddIn)]
public class NwExporterPlugin : AddInPlugin
{
public override int Execute(params string[] parameters)
{
//实例集合
List<Instance> instanceList = new List<Instance>();
//网格集合
List<Mesh> meshList = new List<Mesh>();
//材质集合
List<Material> materialList = new List<Material>();
//拿到所有的构件
Document doc = Application.ActiveDocument;
//获取项目树中的子项
var modelItemColl = ModelItemUtils.GetModelItems(doc);
//转换成选择集
COMApi.InwOpSelection selItemColl =
ComBridge.ToInwOpSelection(modelItemColl);
//当前索引
int index = 0;
foreach (COMApi.InwOaPath3 path in selItemColl.Paths())
{
//是否是可载入族
bool isInstance = ModelItemUtils.IsRevitInstance(modelItemColl[index].Parent.Parent);
#region Mesh材质
//材质属性
var material = GetMaterial(modelItemColl[index].Parent);
//查找材质索引
int matIndex = materialList.FindIndex(x => x.Equals(material));
if (matIndex == -1)
{
materialList.Add(material);
matIndex = materialList.Count - 1;
}
#endregion
#region Revit元素属性
Dictionary<string, string> elemPropertyDict = new Dictionary<string, string>();
DataPropertyCollection elemPropertyColl = null;
if (isInstance)
{
elemPropertyColl = GetDataPropertys(modelItemColl[index].Parent.Parent, PropertyCategoryName.LcRevitData_Element);
}
else
{
elemPropertyColl = GetDataPropertys(modelItemColl[index].Parent, PropertyCategoryName.LcRevitData_Element);
}
//二级是系统族获取元素属性的方法
foreach (var elemProperty in elemPropertyColl)
{
if (!elemPropertyDict.ContainsKey(elemProperty.CombinedName.ToString()))
elemPropertyDict.Add(elemProperty.CombinedName.ToString(), GetValueString(elemProperty));
}
#endregion
#region ID
string elemID = "";
DataPropertyCollection projectPropertyColl = null;
if (isInstance)
{
projectPropertyColl = GetDataPropertys(modelItemColl[index].Parent.Parent, PropertyCategoryName.LcOaNode);
}
else
{
projectPropertyColl = GetDataPropertys(modelItemColl[index].Parent, PropertyCategoryName.LcOaNode);
}
foreach (var projectProperty in projectPropertyColl)
{
if (projectProperty.Name == "LcOaNodeGuid")
{
elemID = GetValueString(projectProperty);
}
}
#endregion
#region Mesh
Mesh mesh = new Mesh(matIndex);
TransformM transform3D = null;
foreach (COMApi.InwOaFragment3 frag in path.Fragments())
{
//if (transform3D == null)
//{
InwLTransform3f3 localToWorld = (InwLTransform3f3)frag.GetLocalToWorldMatrix();
transform3D = new TransformM(localToWorld);
//}
CustomExporter customExporter = new CustomExporter(transform3D);
// generate the primitives
frag.GenerateSimplePrimitives(COMApi.nwEVertexProperty.eNORMAL, customExporter);
mesh.AddTriangles(customExporter.Triangles);
}
meshList.Add(mesh);
#endregion
#region Instance对象
Instance currentInstance = new Instance()
{
id = elemID,
mesh = meshList.Count - 1,
Transform = TransformM.Identify,
visible = 1.0,
info = elemPropertyDict,
};
instanceList.Add(currentInstance);
index++;
#endregion
}
NwModel model = new NwModel(instanceList, meshList, materialList);
string json = JsonUtils.ObjectToJson(model);
while (true)
{
SaveFileDialog sfd = new SaveFileDialog();
try
{
sfd.Filter = "nw导出数据(*.json)|*.json";
sfd.FileName = "Test";
sfd.AddExtension = true;
sfd.RestoreDirectory = true;
DialogResult result = sfd.ShowDialog();
//点了保存按钮进入
if (result == DialogResult.OK)
{
//获得文件路径
string path = sfd.FileName;
File.WriteAllText(path, json);
}
}
catch
{
MessageBox.Show($"{sfd.FileName}被占用,请重新选择!", "提示", MessageBoxButtons.OK);
continue;
}
break;
}
MessageBox.Show("导出成功。");
return 0;
}
}
#endregion
}

View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7EC625E4-E75B-40C5-83A4-407D427B74CE}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NwGeoExporter</RootNamespace>
<AssemblyName>NwGeoExporter</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autodesk.Navisworks.Api, Version=13.0.1240.52, Culture=neutral, PublicKeyToken=d85e58fa5af9b484, processorArchitecture=AMD64">
<SpecificVersion>False</SpecificVersion>
<HintPath>D:\Program Files\Autodesk\Navisworks Manage 2016\Autodesk.Navisworks.Api.dll</HintPath>
</Reference>
<Reference Include="Autodesk.Navisworks.ComApi, Version=13.0.1240.52, Culture=neutral, PublicKeyToken=d85e58fa5af9b484, processorArchitecture=AMD64">
<SpecificVersion>False</SpecificVersion>
<HintPath>D:\Program Files\Autodesk\Navisworks Manage 2016\Autodesk.Navisworks.ComApi.dll</HintPath>
</Reference>
<Reference Include="Autodesk.Navisworks.Interop.ComApi, Version=13.0.1240.52, Culture=neutral, PublicKeyToken=d85e58fa5af9b484, processorArchitecture=AMD64">
<SpecificVersion>False</SpecificVersion>
<EmbedInteropTypes>True</EmbedInteropTypes>
<HintPath>D:\Program Files\Autodesk\Navisworks Manage 2016\Autodesk.Navisworks.Interop.ComApi.dll</HintPath>
</Reference>
<Reference Include="NewtonSoft.Json">
<HintPath>D:\Program Files\Autodesk\Navisworks Manage 2016\Loaders\Rx\NewtonSoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CustomExporter.cs" />
<Compile Include="Models\Instance.cs" />
<Compile Include="Models\Material.cs" />
<Compile Include="Models\Mesh.cs" />
<Compile Include="Models\NwModel.cs" />
<Compile Include="Models\PointM.cs" />
<Compile Include="Models\TransformM.cs" />
<Compile Include="NwEx\Vector3DEx.cs" />
<Compile Include="Models\Triangle.cs" />
<Compile Include="Models\VectorM.cs" />
<Compile Include="NwExporterPlugin.cs" />
<Compile Include="NwEx\IEnumerableEx.cs" />
<Compile Include="NwEx\MathEx.cs" />
<Compile Include="NwUtils\JsonUtils.cs" />
<Compile Include="NwUtils\ModelUtils.cs" />
<Compile Include="NwUtils\PropertyUtils.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="PackageContents.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace NwGeoExporter.NwUtils
{
public static class JsonUtils
{
public static string ObjectToJson<T>(T t)
{
return JsonConvert.SerializeObject(t);
}
}
}

View File

@ -0,0 +1,43 @@
using Autodesk.Navisworks.Api;
using Autodesk.Navisworks.Api.Interop.ComApi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ComBridge = Autodesk.Navisworks.Api.ComApi.ComApiBridge;
namespace NwGeoExporter.NwUtils
{
public static class ModelItemUtils
{
public static ModelItemCollection GetModelItems(Document doc)
{
var modelItemList = doc.Models.SelectMany(x => GetMostBasicModelItem(x.RootItem)).Where(x => x.HasGeometry).ToList();
ModelItemCollection modelItemCollection = new ModelItemCollection();
modelItemCollection.AddRange(modelItemList);
return modelItemCollection;
}
/// <summary>
/// 获取最底层的树节点
/// </summary>
/// <param name="modelItem"></param>
/// <returns></returns>
public static List<ModelItem> GetMostBasicModelItem(ModelItem modelItem)
{
if (modelItem.Children.Count() == 0)
{
return new List<ModelItem> { modelItem };
}
else
{
return modelItem.Children.SelectMany(x => GetMostBasicModelItem(x)).ToList();
}
}
public static bool IsRevitInstance(ModelItem item)
{
return item.ClassName == "LcRevitInstance";
}
}
}

View File

@ -0,0 +1,157 @@
using Autodesk.Navisworks.Api;
using NwGeoExporter.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NwGeoExporter.NwUtils
{
public static class PropertyUtils
{
public enum PropertyCategoryName
{
/// <summary>
/// 项目
/// </summary>
LcOaNode,
/// <summary>
/// 变换
/// </summary>
LcOaExTrans,
/// <summary>
/// 材质
/// </summary>
LcOaExMaterial,
/// <summary>
/// Revit材质
/// </summary>
LcRevitMaterialProperties,
/// <summary>
/// AutoDesk材质
/// </summary>
LcOaProteinMaterialAttribute,
/// <summary>
/// 元素ID
/// </summary>
LcRevitId,
/// <summary>
/// 元素
/// </summary>
LcRevitData_Element,
//LcRevitData_Parameter(钢筋保护层 - 其他面)
//LcRevitData_Parameter(顶部标高)
//LcRevitData_Parameter(底部标高)
//LcRevitData_Parameter(创建的阶段)
//LcRevitData_Type(Revit 类型)
//LcOdpTimeLinerProperty(TimeLiner)
}
public static Material GetMaterial(ModelItem modelItem)
{
//材质属性
var propertyColl = GetDataPropertys(modelItem, PropertyCategoryName.LcRevitMaterialProperties);
string color = "#FF0000";
double transparency = 0;
foreach (var property in propertyColl)
{
if (property.Name == "revit_Color")
{
string colorString = GetValueString(property);
//分割
var byteArray = colorString.Split(new char[] { ',' }).Select(x => int.Parse(x)).ToList();
color = $"#{byteArray[0]:x0}{byteArray[1]:x0}{byteArray[2]:x0}";
}
else if (property.Name == "revit_Transparency")
{
transparency = property.Value.ToInt32() / 100.0;
}
Debug.WriteLine(property.CombinedName);
}
return new Material(color, transparency);
}
/// <summary>
/// 根据栏目名称获取对应的属性集合
/// </summary>
/// <param name="modelItem"></param>
/// <param name="pCatName"></param>
/// <returns></returns>
public static DataPropertyCollection GetDataPropertys(ModelItem modelItem, PropertyCategoryName pCatName)
{
PropertyCategoryCollection propertyCatCollection = modelItem.PropertyCategories;
string catName = Enum.GetName(pCatName.GetType(), (int)pCatName);
foreach (var propertyCat in propertyCatCollection)
{
if (propertyCat.Name == catName)
return propertyCat.Properties;
}
return new DataPropertyCollection();
}
/// <summary>
/// 识别属性值的类型并将其转成string类型
/// </summary>
/// <param name="dataProperty"></param>
/// <returns></returns>
public static string GetValueString(DataProperty dataProperty)
{
string valueString = "";
switch (dataProperty.Value.DataType)
{
case VariantDataType.Boolean:
valueString = dataProperty.Value.ToBoolean().ToString();
break;
case VariantDataType.None:
break;
case VariantDataType.Double:
valueString = dataProperty.Value.ToDouble().ToString();
break;
case VariantDataType.Int32:
valueString = dataProperty.Value.ToInt32().ToString();
break;
case VariantDataType.DisplayString:
valueString = dataProperty.Value.ToDisplayString();
break;
case VariantDataType.DateTime:
valueString = dataProperty.Value.ToDateTime().ToString();
break;
case VariantDataType.DoubleLength:
valueString = dataProperty.Value.ToDoubleLength().ToString();
break;
case VariantDataType.DoubleAngle:
valueString = dataProperty.Value.ToDoubleAngle().ToString();
break;
case VariantDataType.NamedConstant:
valueString = dataProperty.Value.ToNamedConstant().ToString();
break;
case VariantDataType.IdentifierString:
valueString = dataProperty.Value.ToIdentifierString();
break;
case VariantDataType.DoubleArea:
valueString = dataProperty.Value.ToDoubleArea().ToString();
break;
case VariantDataType.DoubleVolume:
valueString = dataProperty.Value.ToDoubleVolume().ToString();
break;
case VariantDataType.Point3D:
valueString = dataProperty.Value.ToPoint3D().ToString();
break;
case VariantDataType.Point2D:
valueString = dataProperty.Value.ToPoint2D().ToString();
break;
}
return valueString;
}
}
}

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<ApplicationPackage>
<Components>
<RuntimeRequirements OS="Win64" Platform="NAVMAN" SeriesMin="Nw13" SeriesMax="Nw13" />
<ComponentEntry AppType="ManagedPlugin" ModuleName="./Contents/NwGeoExporter.dll">
</ComponentEntry>
</Components>
</ApplicationPackage>

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("NwGeoExporter")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NwGeoExporter")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("7ec625e4-e75b-40c5-83a4-407d427b74ce")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]