void OnDrawGizmos() { if (result != null) { foreach (var i in result.Cast <OcTreeNodeObject>()) { Gizmos.DrawWireCube(i.Position, Vector3.one); } } if (ocTree == null) { return; } if (oldPos == TestObject.transform.position) { return; } result = ocTree.Top.GetNodes(TestObject.transform.position, TestObject.renderer.bounds.size.x / 2); if (result.Count == 0) { ocTree.AddNode(TestObject.transform.position, new OcTreeNodeObject(11, TestObject.transform.position)); } Handles.Label(new Vector3(0, 0, 0), "result.Count :" + result.Count); oldPos = TestObject.transform.position; }
public static void DrawLibGGraphicItem(NodeModel node, object geom, string tag, RenderDescription rd, Octree.OctreeSearch.Octree octree) { var selected = DynamoSelection.Instance.Selection.Contains(node); var g = geom as GraphicItem; if (g is CoordinateSystem) { #region draw coordinate systems var line_strip_vertices = g.line_strip_vertices_threadsafe(); for (int i = 0; i < line_strip_vertices.Count; i += 6) { var p1 = new Point3D( line_strip_vertices[i], line_strip_vertices[i + 1], line_strip_vertices[i + 2]); var p2 = new Point3D( line_strip_vertices[i + 3], line_strip_vertices[i + 4], line_strip_vertices[i + 5]); if (i < 6) { rd.XAxisPoints.Add(p1); rd.XAxisPoints.Add(p2); } else if (i >= 6 && i < 12) { rd.YAxisPoints.Add(p1); rd.YAxisPoints.Add(p2); } else { rd.ZAxisPoints.Add(p1); rd.ZAxisPoints.Add(p2); } } #endregion } else { #region draw points var point_vertices = g.point_vertices_threadsafe(); for (int i = 0; i < point_vertices.Count; i += 3) { var pos = new Point3D(point_vertices[i], point_vertices[i + 1], point_vertices[i + 2]); if (selected) { rd.SelectedPoints.Add(pos); } else { rd.Points.Add(pos); } if (node.DisplayLabels) { rd.Text.Add(new BillboardTextItem { Text = tag, Position = pos }); } } #endregion #region draw lines FloatList line_strip_vertices = g.line_strip_vertices_threadsafe(); for (int i = 0; i < line_strip_vertices.Count-3; i += 3) { var start = new Point3D( line_strip_vertices[i], line_strip_vertices[i + 1], line_strip_vertices[i + 2]); var end = new Point3D( line_strip_vertices[i + 3], line_strip_vertices[i + 4], line_strip_vertices[i + 5]); //draw a label at the start of the curve if (node.DisplayLabels && i == 0) { rd.Text.Add(new BillboardTextItem { Text = tag, Position = start }); } if (selected) { rd.SelectedLines.Add(start); rd.SelectedLines.Add(end); } else { rd.Lines.Add(start); rd.Lines.Add(end); } } #endregion #region draw surface //var sw = new Stopwatch(); //sw.Start(); var builder = new MeshBuilder(); var points = new Point3DCollection(); var tex = new PointCollection(); var norms = new Vector3DCollection(); var tris = new List<int>(); FloatList triangle_vertices = g.triangle_vertices_threadsafe(); FloatList triangle_normals = g.triangle_normals_threadsafe(); for (int i = 0; i < triangle_vertices.Count; i+=3) { var new_point = new Point3D(triangle_vertices[i], triangle_vertices[i + 1], triangle_vertices[i + 2]); var normal = new Vector3D(triangle_normals[i], triangle_normals[i + 1], triangle_normals[i + 2]); //find a matching point //compare the angle between the normals //to discern a 'break' angle for adjacent faces //int foundIndex = -1; //for (int j = 0; j < points.Count; j++) //{ // var testPt = points[j]; // var testNorm = norms[j]; // var ang = Vector3D.AngleBetween(normal, testNorm); // if (new_point.X == testPt.X && // new_point.Y == testPt.Y && // new_point.Z == testPt.Z && // ang > 90.0000) // { // foundIndex = j; // break; // } //} //if (foundIndex != -1) //{ // tris.Add(foundIndex); // continue; //} tris.Add(points.Count); points.Add(new_point); norms.Add(normal); tex.Add(new System.Windows.Point(0,0)); octree.AddNode(new_point.X, new_point.Y, new_point.Z, node.GUID.ToString()); } //builder.AddTriangles(points, norms, tex); builder.Append(points, tris, norms, tex); //sw.Stop(); //Debug.WriteLine(string.Format("{0} elapsed for drawing geometry.", sw.Elapsed)); //don't add empty meshes if (builder.Positions.Count > 0) { if (selected) { rd.SelectedMeshes.Add(builder.ToMesh(true)); } else { rd.Meshes.Add(builder.ToMesh(true)); } } #endregion } }
/// <summary> /// Convert a Revit mesh to a Helix mesh for visualization. /// In order to merge mesh vertices, this method uses a dictionary with a string key formed as x:y:z of the point. /// This assumes that where vertices are the "same" in the Revit mesh, they will have the same coordinates. This /// is NOT a safe strategy to use in other mesh-processing contexts where vertices might have small discrepancies. /// </summary> /// <param name="rmesh"></param> /// <param name="octree"></param> /// <param name="node"></param> /// <returns></returns> private static MeshGeometry3D RevitMeshToHelixMesh(Mesh rmesh, Octree.OctreeSearch.Octree octree, NodeModel node) { var builder = new MeshBuilder(); var points = new Point3DCollection(); var tex = new PointCollection(); var norms = new Vector3DCollection(); var tris = new List<int>(); //A dictionary which will contain a point, a normal, and an index //keyed on the location of the point as a hash var pointDict = new Dictionary<string, PointData>(); for (int i = 0; i < rmesh.NumTriangles; ++i) { var tri = rmesh.get_Triangle(i); //calculate the face normal by //getting the cross product of two edges var a = tri.get_Vertex(0); var b = tri.get_Vertex(1); var c = tri.get_Vertex(2); var e1 = b - a; var e2 = c - a; var normXYZ = e1.CrossProduct(e2).Normalize(); var normal = new Vector3D(normXYZ.X, normXYZ.Y, normXYZ.Z); for (int j = 0; j < 3; j++) { var pt = RevitPointToWindowsPoint(tri.get_Vertex(j)); var key = pt.X + ":" + pt.Y + ":" + pt.Z; if (!pointDict.ContainsKey(key)) { //if the dictionary doesn't contain the key var pd = new PointData(pt.X,pt.Y,pt.Z); pd.Normals.Add(normal); pd.Index = pointDict.Count; pointDict.Add(key, pd); tris.Add(pd.Index); } else { //add an index to our tris array //add a normal to our internal collection //for post processing var data = pointDict[key]; tris.Add(data.Index); data.Normals.Add(normal); } } } var lst = pointDict.ToList(); lst.ForEach(x => points.Add(x.Value.Position)); lst.ForEach(x=>octree.AddNode(x.Value.Position.X, x.Value.Position.Y, x.Value.Position.Z, node.GUID.ToString())); lst.ForEach(x=>tex.Add(x.Value.Tex)); //merge the normals foreach (var pd in lst) { var avg = new Vector3D(); var nList = pd.Value.Normals; foreach (var n in nList) { avg.X += n.X; avg.Y += n.Y; avg.Z += n.Z; } avg.X = avg.X / nList.Count; avg.Y = avg.Y / nList.Count; avg.Z = avg.Z / nList.Count; norms.Add(avg); } builder.Append(points, tris, norms, tex); Debug.WriteLine(string.Format("Mesh had {0} faces coming in and {1} faces going out.", rmesh.NumTriangles, builder.TriangleIndices.Count / 3)); return builder.ToMesh(true); }