diff --git a/TestCommand.cs b/TestCommand.cs new file mode 100644 index 0000000..9725e9c --- /dev/null +++ b/TestCommand.cs @@ -0,0 +1,271 @@ +using System; +using System.Linq; +using System.Text; +using System.Linq.Expressions; +using System.Collections; +using System.Collections.Generic; +using Autodesk.Revit.Attributes; +using Autodesk.Revit.ApplicationServices; +using Autodesk.Revit.Creation; +using Autodesk.Revit.DB; +using Autodesk.Revit.DB.Architecture; +using Autodesk.Revit.DB.Plumbing; +using Autodesk.Revit.UI; +using Autodesk.Revit.UI.Selection; +using Document = Autodesk.Revit.DB.Document; +using Newtonsoft.Json; +using System.IO; +using Autodesk.Revit.DB.DirectContext3D; +using System.Runtime.CompilerServices; + +namespace GeoTest +{ + [TransactionAttribute(TransactionMode.Manual)] + [RegenerationAttribute(RegenerationOption.Manual)] + + public class TestCommand : IExternalCommand + { + public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) + { + var applicationApp = commandData.Application.Application; + var app = commandData.Application; + var uidoc = app.ActiveUIDocument; + var doc = uidoc.Document; + var inf=GetData(doc, applicationApp); + OutPut(inf); + return Result.Succeeded; + } + + private Information GetData(Document doc, Autodesk.Revit.ApplicationServices.Application app) + { + var instances = new List(); + var materials = new List(); + var meshes = new List(); + int instanceID = 0; + + var option = GetGeometryOption(app); + // Find all Wall instances in the document by using category filter + ElementCategoryFilter filter = new ElementCategoryFilter(BuiltInCategory.OST_StructuralColumns); + + // Apply the filter to the elements in the active document, + // Use shortcut WhereElementIsNotElementType() to find wall instances only + FilteredElementCollector collector = new FilteredElementCollector(doc); + IList walls = collector.WherePasses(filter).WhereElementIsNotElementType().ToElements(); + foreach (var element in walls) + { + + var materialIds = element.GetMaterialIds(false).ToList(); + var thisMaterials = materialIds.Select(x => doc.GetElement(x) as Autodesk.Revit.DB.Material).ToList(); + var transformList = new List(); + foreach (var mat in thisMaterials) + { + var color = mat.Color; + var newMat = new Material(new List() { color.Red,color.Green,color.Blue}, mat.Transparency); + materials.Add(newMat); + } + if (element is FamilyInstance) + { + var transform = (element as FamilyInstance).GetTotalTransform(); + transformList.Add(transform.BasisX); + transformList.Add(transform.BasisY); + transformList.Add(transform.BasisZ); + } + else + { + var transform = Transform.Identity; + transformList.Add(transform.BasisX); + transformList.Add(transform.BasisY); + transformList.Add(transform.BasisZ); + } + var geoElement = element.get_Geometry(option); + + foreach (var geoObject in geoElement) + { + Solid solid = geoObject as Solid; + if (null == solid || 0 == solid.Faces.Size || 0 == solid.Edges.Size) + { + continue; + } + + + var vertices = new List(); + var faceVertices = new List();//按顺序将每个面用3个顶点表示 + var triInfo = new Dictionary, XYZ>(); + var normals = new List(); + + // Get the faces and edges from solid, and transform the formed points + foreach (Face face in solid.Faces) + { + Autodesk.Revit.DB.Mesh mesh = face.Triangulate(); + var count = mesh.NumTriangles; + for(int i=0;i(); + var triangle = mesh.get_Triangle(i); + //normal + //(x3 - x1).CrossProduct(x2 - x1) + var thisNormal = ((triangle.get_Vertex(2) - triangle.get_Vertex(0)).CrossProduct((triangle.get_Vertex(1) - triangle.get_Vertex(0)))).Normalize(); + + for (int j=0;j<3;j++) + { + var vertex = triangle.get_Vertex(j); + var sameIndex=vertices.Where(x => x.DistanceTo(vertex) < 0.00001); + if (!sameIndex.Any()) + { + vertices.Add(vertex); + vertexIndecies.Add(vertices.Count() - 1); + } + else + { + vertexIndecies.Add(vertices.IndexOf(sameIndex.First())); + } + } + triInfo.Add(vertexIndecies, thisNormal); + faceVertices.AddRange(vertexIndecies); + } + + } + + //对每个顶点寻找邻接面 + //如果两面夹角小于90度,用几何均值合并normal + //如果大于90度,使用各自的normal + for (int i = 0; i < vertices.Count; i++) + { + XYZ vertex = vertices[i]; + var adjacentFaces = triInfo.Where(x => x.Key.Contains(i)).ToList(); + var jc = adjacentFaces.Count; + if (!adjacentFaces.Any()) continue; + for (int j = 0; j < jc; j++) + { + for (int k = j + 1; k < jc; k++) + { + if (Math.Cos(adjacentFaces[j].Value.AngleTo(adjacentFaces[k].Value)) > 0)//即, XYZ>(adjacentFaces[k].Key, changedNormal); + adjacentFaces[k] = tempPair; + //回到本层开头重新循环 + adjacentFaces.RemoveAt(j); + jc--; + j--; + break; + } + } + } + + normals.AddRange(adjacentFaces.Select(x => x.Value)); + } + var newMesh = new Mesh(vertices, faceVertices, normals); + meshes.Add(newMesh); + var newInstance = new Instance(instanceID, transformList, solid.Visibility, meshes.Count() - 1); + instances.Add(newInstance); + instanceID++; + } + + + + + } + + var information = new Information(instances, meshes, materials); + return information; + } + + + Options GetGeometryOption(Autodesk.Revit.ApplicationServices.Application app) + { + Autodesk.Revit.DB.Options option = app.Create.NewGeometryOptions(); + option.ComputeReferences = true; //打开计算几何引用 + option.DetailLevel = ViewDetailLevel.Fine; //视图详细程度为最好 + return option; + + } + + private void OutPut(Information information) + { + string fp = System.Windows.Forms.Application.StartupPath + "\\geometryInfo.json"; + var path = @"D:\geometryInfo.json"; + //FileStream fs1 = new FileStream(fp, FileMode.Create, FileAccess.ReadWrite); + var instanceString = JsonConvert.SerializeObject(information); + + File.WriteAllText(path, instanceString); + return; + } + + + + } + + public class Information + { + public List instances { get; set; } + public List meshes { get; set; } + public List materials { get; set; } + public Information(List instances, List meshes, List materials) + { + this.instances = instances; + this.meshes = meshes; + this.materials = materials; + } + } + + + public class Instance + { + public int id { get; set; } + public List> transform { get; set; } + public int visible { get; set; } + public int meshId { get; set; }//meshID + public string info { get; set; } + public Instance(int id, List transform, Visibility visible, int meshId) + { + this.id = id; + this.transform = new List>(); + foreach(var trans in transform) + { + var tempTrans = new List() { trans.X, trans.Y, trans.Z }; + this.transform.Add(tempTrans); + } + this.visible = (int)visible; + this.meshId = meshId; + } + } + + public class Mesh + { + public List> vertices { get; set; } + public List vertexIndices { get; set; } + public List> normals { get; set; }//点法向量 + public Mesh(List vertices, List vertexIndices, List normals) + { + this.vertexIndices = vertexIndices; + this.vertices = new List>(); + foreach(var vertex in vertices) + { + var tempV = new List() { vertex.X, vertex.Y, vertex.Z }; + this.vertices.Add(tempV); + + } + this.normals = new List>(); + foreach (var n in normals) + { + var tempN = new List() { n.X, n.Y, n.Z }; + this.normals.Add(tempN); + + } + } + } + + public class Material + { + public List color { get; set; } + public double transparent { get; set; }//透明度 + public Material(List color, double transparent) + { + this.color = color; + this.transparent = transparent; + } + } + +} \ No newline at end of file diff --git a/geometryInfo.json b/geometryInfo.json new file mode 100644 index 0000000..636285f --- /dev/null +++ b/geometryInfo.json @@ -0,0 +1 @@ +{"instances":[{"id":0,"transform":[[3.2323239063977555E-15,1.0,0.0],[-0.53333333333333333,1.7239060834121366E-15,0.84590516936330129],[0.8459051693633014,-2.7342395014784418E-15,0.53333333333333333]],"visible":0,"meshId":0,"info":null}],"meshes":[{"vertices":[[-7.1471085548400879,1.3119041919708252,0.37867245078086853],[-7.1067194938659668,1.4297416210174561,0.31461244821548462],[-7.0502605438232422,1.5214704275131226,0.22506439685821533],[-6.8344144821166992,0.63527625799179077,-0.11728298664093018],[-7.1681556701660156,1.1775045394897461,0.41205465793609619],[-6.9823055267333984,1.579659104347229,0.11728298664093018],[-7.1681556701660156,1.0374308824539185,0.41205465793609619],[-7.1471085548400879,0.90303117036819458,0.37867245078086853],[-7.1067194938659668,0.785193681716919,0.31461244821548462],[-6.9823055267333984,0.63527625799179077,0.11728298664093018],[-7.0502605438232422,0.693464994430542,0.22506439685821533],[-6.9083600044250488,1.5995936393737793,2.1706411472264707E-15],[-6.8344144821166992,1.579659104347229,-0.11728298664093018],[-6.7664594650268555,1.5214704275131226,-0.22506439685821533],[-6.7100005149841309,1.4297416210174561,-0.31461244821548462],[-6.66961145401001,1.3119041919708252,-0.37867245078086853],[-6.648564338684082,1.1775045394897461,-0.41205465793609619],[-6.66961145401001,0.90303117036819458,-0.37867245078086853],[-6.7664594650268555,0.693464994430542,-0.22506439685821533],[-6.9083600044250488,0.61534172296524048,6.8987842468767771E-16],[-6.7100005149841309,0.785193681716919,-0.31461244821548462],[-6.648564338684082,1.0374308824539185,-0.41205465793609619],[13.832289695739746,1.579659104347229,13.240642547607422],[13.707876205444336,1.4297416210174561,13.437972068786621],[13.764334678649902,1.5214704275131226,13.348423957824707],[13.667487144470215,1.3119041919708252,13.502032279968262],[13.906235694885254,1.5995936393737793,13.123359680175781],[13.646439552307129,1.1775045394897461,13.535414695739746],[13.646439552307129,1.0374308824539185,13.535414695739746],[13.667487144470215,0.90303117036819458,13.502032279968262],[13.764334678649902,0.693464994430542,13.348423957824707],[13.707876205444336,0.785193681716919,13.437972068786621],[13.832289695739746,0.63527625799179077,13.240642547607422],[13.906235694885254,0.61534172296524048,13.123359680175781],[13.980180740356445,0.63527625799179077,13.006076812744141],[14.104595184326172,0.785193681716919,12.808747291564941],[14.048135757446289,0.693464994430542,12.898295402526855],[14.144984245300293,0.90303117036819458,12.7446870803833],[14.166030883789063,1.0374308824539185,12.711304664611816],[14.166030883789063,1.1775045394897461,12.711304664611816],[14.144984245300293,1.3119041919708252,12.7446870803833],[14.048135757446289,1.5214704275131226,12.898295402526855],[14.104595184326172,1.4297416210174561,12.808747291564941],[13.980180740356445,1.579659104347229,13.006076812744141]],"vertexIndices":[0,1,2,3,4,0,5,0,2,3,0,5,6,4,3,6,3,7,8,9,10,3,9,8,8,7,3,5,11,12,13,14,5,5,15,16,5,14,15,5,16,17,3,17,18,19,9,3,18,17,20,5,17,3,21,17,16,13,5,12,22,11,5,2,22,5,23,1,0,2,1,24,25,0,4,2,24,22,22,26,11,24,1,23,0,25,23,4,27,25,4,6,27,28,6,7,8,29,7,30,10,9,8,10,31,32,9,19,7,29,28,8,31,29,30,31,10,9,32,30,19,33,32,6,28,27,33,19,3,18,34,3,35,20,17,18,20,36,37,17,21,3,34,33,18,36,34,35,36,20,17,37,35,21,38,37,21,16,38,39,16,15,14,40,15,41,13,12,14,13,42,43,12,11,15,40,39,14,42,40,41,42,13,12,43,41,11,26,43,16,39,38,37,39,40,26,42,41,40,42,32,32,34,40,37,36,35,37,38,39,37,34,36,40,34,37,34,32,33,41,43,26,29,26,22,24,23,25,24,25,22,27,22,25,32,31,30,31,32,29,22,28,29,29,32,26,27,28,22,26,32,42],"normals":[[0.84590502982515026,2.793434917820152E-07,0.53333355465077736],[0.4680953229677603,-0.47924947863962969,-0.74243296386902924],[0.53100992599490182,-0.70335379973841761,-0.47256945615265772],[0.8459049868186802,5.9368678833129974E-07,0.53333362286184061],[0.25559940815790594,-0.87767904626787252,-0.40539910494677456],[0.051346921516051164,0.95600035196865507,0.28883701405227136],[0.68462969865789158,-0.13400347262834111,-0.71646719746206811],[0.84590521611938208,8.7654485655055836E-07,0.53333325917408636],[0.15025724958767142,-0.95949303769076355,-0.23831884014760377],[0.6881936990416706,0.078682383607808229,-0.72124788742091739],[0.655260825680997,0.35078977557989288,-0.66901403847487873],[0.84590494815733619,-5.8821041276295223E-07,0.533333684181478],[0.42695519375551455,0.59927800971816769,-0.67718175521304669],[0.845905005590586,-4.9910851653669616E-07,0.53333359308836092],[0.18638091388293798,0.93694971436081409,-0.29561357834062668],[0.84590420688196788,-2.551728302108588E-06,0.53333485988905449],[0.319614896147972,0.80054104878149335,-0.50693229072150026],[0.044209946279623907,-0.99227339183300867,0.11592668592765472],[0.84590527182524256,9.1028519158820716E-07,0.53333317082048615],[-0.18638077123989022,-0.93694981581104475,0.29561334672790579],[0.84590517676702248,5.8092113642781785E-07,0.53333332159018043],[-0.31961455674338268,-0.80054153019725971,0.50693174446582134],[-0.24867599536332871,-0.5944761378097001,0.76469495284389055],[0.84590520182138351,5.9856380733266085E-09,0.53333328185246842],[-0.49970655767183303,-0.34946398709625104,0.79257067693837779],[-0.35409322257554243,-0.078682391139188221,0.931894345433369],[-0.29405086575095624,0.46209239929170826,0.83666283703051225],[-0.087612392157428165,0.856155582275262,0.50923637701892432],[0.16368229633266734,0.98038442649213553,0.10979290577697319],[0.84590548827680012,-2.2103035063022421E-07,0.53333282751312006],[-0.37712330555068829,0.70710737396627044,0.598144776866811],[-0.35131621462783919,0.13400266798947,0.9266176138576635],[-0.83841439250573446,-0.04754387889518439,-0.54295569434240232],[0.42695526743329271,-0.5992778283479917,-0.67718186926517787],[-0.84590945089613268,4.0517984967839827E-06,-0.53332654243735711],[-0.65920562591911336,-0.30635342361975909,-0.6867281285873198],[-0.73216644222389038,-0.068175487099819035,-0.67770524849665514],[-0.84488628403459187,-0.049068492537048973,-0.53269076403703552],[0.53197445439265589,-0.071339938090028837,-0.843749840359657],[-0.84590666366052281,1.8924725523627976E-06,-0.53333096325934581],[-0.57949391068420752,0.054461113673595171,-0.81315484046850228],[-0.79595056510834372,0.046974327619249787,-0.60353633730573975],[-0.41740373454137231,0.62061720260848774,-0.6637834061027218],[-0.63719451929151294,0.27060148277216528,-0.72163562973730966],[-0.84445023519590323,0.01199162582843021,-0.53549976768209206],[-0.038047638924027634,0.99745210475802082,0.060346299688557765],[-0.84590502708732862,-2.0234178960724989E-05,-0.5333335586093978],[-0.86010100418368773,0.091827156218482836,-0.50179082891483628],[-0.42695507884439965,0.59927829484285822,0.67718157533944234],[-0.84590027907760068,-7.0001409653805189E-06,-0.53334108955473813],[-0.90382492267878856,0.30635119321949278,-0.29874647371588314],[-0.86940612112307247,0.017147007675700068,-0.49380054341961088],[-0.97430667043022789,0.050444003063912737,0.21950379156190294],[-0.983536535707673,-0.054461086821840622,-0.17230749533996861],[-0.88771348125667027,-0.046974273017733055,-0.45799366029413408],[-0.87932693085344493,-0.33587992352029822,-0.3375926919408348],[-0.903224471587857,-0.13795039069033613,-0.40639296700757543],[-0.67830645761647779,-0.69095074756725139,-0.24997482671669527]]}],"materials":[{"color":[192,192,192],"transparent":0.0}]} \ No newline at end of file