Stream(ArrayList data, MeshTriangle meshTri) { data.Add(new Snoop.Data.ClassSeparator(typeof(MeshTriangle))); // TBD: not sure what get_index() is all about?? data.Add(new Snoop.Data.Xyz("Vertex [0]", meshTri.get_Vertex(0))); data.Add(new Snoop.Data.Xyz("Vertex [1]", meshTri.get_Vertex(1))); data.Add(new Snoop.Data.Xyz("Vertex [2]", meshTri.get_Vertex(2))); }
/// <summary> /// Return the median point of a triangle by /// taking the average of its three vertices. /// </summary> XYZ MedianPoint(MeshTriangle triangle) { XYZ p = XYZ.Zero; p += triangle.get_Vertex(0); p += triangle.get_Vertex(1); p += triangle.get_Vertex(2); p *= 0.3333333333333333; return(p); }
/// <summary> /// Calculates net volume. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="extrusionCreationData"> /// The IFCExtrusionCreationData. /// </param> /// <param name="element"> /// The element to calculate the value. /// </param> /// <param name="elementType"> /// The element type. /// </param> /// <returns> /// True if the operation succeed, false otherwise. /// </returns> public override bool Calculate(ExporterIFC exporterIFC, IFCExtrusionCreationData extrusionCreationData, Element element, ElementType elementType) { double vol = 0; SolidMeshGeometryInfo geomInfo = GeometryUtil.GetSolidMeshGeometry(element); if (geomInfo.SolidsCount() > 0) { for (int ii = 0; ii < geomInfo.SolidsCount(); ++ii) { vol += geomInfo.GetSolids()[ii].Volume; } } if (geomInfo.MeshesCount() > 0) { for (int jj = 0; jj < geomInfo.MeshesCount(); ++jj) { Mesh geomMesh = geomInfo.GetMeshes()[jj]; XYZ arbitraryOrig = geomMesh.Vertices[0]; for (int i = 0; i < geomMesh.NumTriangles; ++i) { MeshTriangle meshTri = geomMesh.get_Triangle(i); XYZ v1 = meshTri.get_Vertex(0) - arbitraryOrig; XYZ v2 = meshTri.get_Vertex(1) - arbitraryOrig; XYZ v3 = meshTri.get_Vertex(2) - arbitraryOrig; vol += v1.DotProduct(v2.CrossProduct(v3)) / 6.0f; } } } m_Volume = UnitUtil.ScaleVolume(vol); if (m_Volume < MathUtil.Eps() * MathUtil.Eps() || m_Volume < MathUtil.Eps()) { if (ParameterUtil.GetDoubleValueFromElementOrSymbol(element, "IfcQtyNetVolume", out m_Volume) == null) { if (ParameterUtil.GetDoubleValueFromElementOrSymbol(element, "IfcNetVolume", out m_Volume) == null) { ParameterUtil.GetDoubleValueFromElementOrSymbol(element, "NetVolume", out m_Volume); } } m_Volume = UnitUtil.ScaleVolume(m_Volume); if (m_Volume < MathUtil.Eps()) { return(false); } else { return(true); } } else { return(true); } }
private XYZ NormVect(MeshTriangle triangle) { XYZ vertex0 = triangle.get_Vertex(0); XYZ vertex1 = triangle.get_Vertex(1); XYZ vertex2 = triangle.get_Vertex(2); XYZ VecPoi1 = vertex1 - vertex0; XYZ VecPoi2 = vertex2 - vertex0; XYZ CP = VecPoi1.CrossProduct(VecPoi2); XYZ Nor = CP.Normalize(); return(Nor); }
void DrawMesh( Mesh mesh ) { int n = mesh.NumTriangles; for( int i = 0; i < n; ++i ) { MeshTriangle t = mesh.get_Triangle( i ); XYZ p = t.get_Vertex( 0 ); XYZ q = t.get_Vertex( 1 ); XYZ r = t.get_Vertex( 2 ); DrawInstanceTriangle( p, q, r ); DrawSymbolTriangle( p, q, r ); } }
/// <summary> /// Return the area of a triangle as half of /// its height multiplied with its base length. /// </summary> double TriangleArea(MeshTriangle triangle) { XYZ a = triangle.get_Vertex(0); XYZ b = triangle.get_Vertex(1); XYZ c = triangle.get_Vertex(2); Line l = Line.CreateBound(a, b); double h = l.Project(c).Distance; double area = 0.5 * l.Length * h; return(area); }
private void MeshData(GeometryObject obj) { Mesh mesh = obj as Mesh; if (null == mesh) { return; } StringBuilder str = new StringBuilder(); for (int i = 0; i < mesh.NumTriangles; i++) { MeshTriangle triangular = mesh.get_Triangle(i); List <XYZ> points = new List <XYZ>(); for (int n = 0; n < 3; n++) { XYZ point = triangular.get_Vertex(n); points.Add(point); str.Append(point.ToString() + "\n"); } XYZ iniPoint = points[0]; points.Add(iniPoint); } TaskDialog td = new TaskDialog("vertex"); td.MainContent = str.ToString(); td.Show(); }
/// <summary> /// 将给定三角形的顶点添加到顶点查找字典并发出三角形。 /// Add the vertices of the given triangle to our /// vertex lookup dictionary and emit a triangle. /// </summary> void StoreTriangle(MeshTriangle triangle, ObjModel objModel) { var vFace = new VFace(); for (int i = 0; i < 3; ++i) { XYZ p = triangle.get_Vertex(i); if (i == 0) { vFace.Point1 = _vertices.AddVertex(new PointInt(p)) + 1; } else if (i == 1) { vFace.Point2 = _vertices.AddVertex(new PointInt(p)) + 1; } else if (i == 2) { vFace.Point3 = _vertices.AddVertex(new PointInt(p)) + 1; } } // 添加面数据 objModel.Faces.Add(vFace); }
/// <summary> /// Return an arbitrary point on a planar face, /// namely the midpoint of the first mesh triangle. /// </summary> XYZ PointOnFace(PlanarFace face) { XYZ p = new XYZ(0, 0, 0); Mesh mesh = face.Triangulate(); for (int i = 0; i < mesh.NumTriangles;) { MeshTriangle triangle = mesh.get_Triangle(i); p += triangle.get_Vertex(0); p += triangle.get_Vertex(1); p += triangle.get_Vertex(2); p *= 0.3333333333333333; break; } return(p); }
/// <summary> /// generate data of a Mesh. /// </summary> /// <param name="obj">a geometry object of element.</param> private void AddMesh(GeometryObject obj) { Mesh mesh = obj as Mesh; List <XYZ> points = new List <XYZ>(); // get all triangles of the mesh. for (int i = 0; i < mesh.NumTriangles; i++) { MeshTriangle trigangle = mesh.get_Triangle(i); for (int j = 0; j < 3; j++) { // A vertex of the triangle. Autodesk.Revit.DB.XYZ point = trigangle.get_Vertex(j); double x = point.X; double y = point.Y; double z = point.Z; points.Add(point); } Autodesk.Revit.DB.XYZ iniPoint = points[0]; points.Add(iniPoint); m_curve3Ds.Add(points); } }
/// <summary> /// generate data of a Mesh /// </summary> /// <param name="obj"></param> /// <param name="transform"></param> private void AddMesh(GeometryObject obj, Transform transform) { Mesh mesh = obj as Mesh; if (null == mesh) { return; } //a face has a mesh, all meshes are made of triangles for (int i = 0; i < mesh.NumTriangles; i++) { MeshTriangle triangular = mesh.get_Triangle(i); List <XYZ> points = new List <XYZ>(); try { for (int n = 0; n < 3; n++) { Autodesk.Revit.DB.XYZ point = triangular.get_Vertex(n); Autodesk.Revit.DB.XYZ newPoint = MathUtil.GetBasis(point, transform); points.Add(newPoint); } Autodesk.Revit.DB.XYZ iniPoint = points[0]; points.Add(iniPoint); m_curve3Ds.Add(points); } catch { } } }
public List <PlanarFace> GetMeshedFaces() { Mesh mesh = GetMesh(); TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); builder.OpenConnectedFaceSet(false); List <XYZ> args = new List <XYZ>(3); XYZ[] triangleCorners = new XYZ[3]; for (int i = 0; i < mesh.NumTriangles; ++i) { MeshTriangle triangle = mesh.get_Triangle(i); triangleCorners[0] = triangle.get_Vertex(0); triangleCorners[1] = triangle.get_Vertex(1); triangleCorners[2] = triangle.get_Vertex(2); TessellatedFace tesseFace = new TessellatedFace(triangleCorners, ElementId.InvalidElementId); if (builder.DoesFaceHaveEnoughLoopsAndVertices( tesseFace)) { builder.AddFace(tesseFace); } } builder.CloseConnectedFaceSet(); TessellatedShapeBuilderResult result = builder.Build( TessellatedShapeBuilderTarget.AnyGeometry, TessellatedShapeBuilderFallback.Mesh, ElementId.InvalidElementId); var geo = result.GetGeometricalObjects(); var solids = GeoHelper.GetSolidsInModel(geo, GeoHelper.SolidVolumnConstraint.Any); var faces = GeoHelper.GetSurfaces(solids.Keys); return(faces.OfType <PlanarFace>().ToList()); }
public void DrawFaceTriangleNormals(Face f) { Mesh mesh = f.Triangulate(); int n = mesh.NumTriangles; string s = "{0} face triangulation returns " + "mesh triangle{1} and normal vector{1}:"; Debug.Print( s, n, Util.PluralSuffix(n)); for (int i = 0; i < n; ++i) { MeshTriangle t = mesh.get_Triangle(i); XYZ p = (t.get_Vertex(0) + t.get_Vertex(1) + t.get_Vertex(2)) / 3; XYZ v = t.get_Vertex(1) - t.get_Vertex(0); XYZ w = t.get_Vertex(2) - t.get_Vertex(0); XYZ normal = v.CrossProduct(w).Normalize(); Debug.Print( "{0} {1} --> {2}", i, Util.PointString(p), Util.PointString(normal)); CreateModelLine(_doc, p, p + normal); } }
/// <summary> /// Add the vertices of the given triangle to our /// vertex lookup dictionary and emit a triangle. /// </summary> void StoreTriangle(MeshTriangle triangle) { for (int i = 0; i < 3; ++i) { XYZ p = triangle.get_Vertex(i); PointInt q = new PointInt(p); _triangles.Add(_vertices.AddVertex(q)); } }
private void MeshProcess(Mesh geomMesh) { try { uint iStartId = (uint)Lid_Vertices.Count; uint iNextId = iStartId / 3; fr_Progress.SetProBarData(geomMesh.NumTriangles); for (int i = 0; i < geomMesh.NumTriangles; i++) { fr_Progress.AddValueProBarData(i + 1); MeshTriangle triangle = geomMesh.get_Triangle(i); XYZ vertex = triangle.get_Vertex(0); Liu_Indices.Add(3); AddVertex(iStartId, vertex, iNextId++); vertex = triangle.get_Vertex(1); AddVertex(iStartId, vertex, iNextId++); vertex = triangle.get_Vertex(2); AddVertex(iStartId, vertex, iNextId++); XYZ normal = NormVect(triangle); for (int inorms = 0; inorms < 3; inorms++) { Lid_Normals.Add(normal.X); Lid_Normals.Add(normal.Y); Lid_Normals.Add(normal.Z); //Lid_TextureCoords.Add(normal.X); //Lid_TextureCoords.Add(normal.Y); //Lid_TextureCoords.Add(normal.Z); } } Liu_FeatureIndex.Add((uint)geomMesh.NumTriangles * 3); } catch (Exception e) { string message; // Exception rised, report it by revit error reporting mechanism. message = "MeshProcess fails for Reason:" + Environment.NewLine; File.AppendAllText(@"C:\CadFaster\Revit\ExeWriter_log.txt", message); message = e.ToString(); //File.AppendAllText(@"C:\CadFaster\Revit\ExeWriter_log.txt", message); //return Autodesk.Revit.UI.Result.Failed; } //End of MeshProcess }
// must return an array to make mesh double sided public static Mesh3D[] RevitMeshToHelixMesh(Mesh rmesh) { var indicesFront = new List <int>(); var indicesBack = new List <int>(); var vertices = new List <Point3D>(); for (int i = 0; i < rmesh.NumTriangles; ++i) { MeshTriangle tri = rmesh.get_Triangle(i); for (int k = 0; k < 3; ++k) { Point3D newPoint = RevitPointToWindowsPoint(tri.get_Vertex(k)); bool newPointExists = false; for (int l = 0; l < vertices.Count; ++l) { Point3D p = vertices[l]; if ((p.X == newPoint.X) && (p.Y == newPoint.Y) && (p.Z == newPoint.Z)) { indicesFront.Add(l); newPointExists = true; break; } } if (newPointExists) { continue; } indicesFront.Add(vertices.Count); vertices.Add(newPoint); } int a = indicesFront[indicesFront.Count - 3]; int b = indicesFront[indicesFront.Count - 2]; int c = indicesFront[indicesFront.Count - 1]; indicesBack.Add(c); indicesBack.Add(b); indicesBack.Add(a); } var meshes = new List <Mesh3D> { new Mesh3D(vertices, indicesFront), new Mesh3D(vertices, indicesBack) }; return(meshes.ToArray()); }
void GetMesh( Mesh mesh, out JtFace fInstance, out JtFace fSymbol) { int n = mesh.NumTriangles; fInstance = new JtFace(n); fSymbol = InSymbol ? new JtFace(n) : null; for (int i = 0; i < n; ++i) { MeshTriangle t = mesh.get_Triangle(i); XYZ p = t.get_Vertex(0); XYZ q = t.get_Vertex(1); XYZ r = t.get_Vertex(2); fInstance.Add(GetInstanceTriangle(p, q, r)); if (InSymbol) { fSymbol.Add(GetSymbolTriangle(p, q, r)); } } }
/// <summary> /// Calculates net surface area. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="extrusionCreationData"> /// The IFCExtrusionCreationData. /// </param> /// <param name="element"> /// The element to calculate the value. /// </param> /// <param name="elementType"> /// The element type. /// </param> /// <returns> /// True if the operation succeed, false otherwise. /// </returns> public override bool Calculate(ExporterIFC exporterIFC, IFCExtrusionCreationData extrusionCreationData, Element element, ElementType elementType) { double areaSum = 0; SolidMeshGeometryInfo geomInfo = GeometryUtil.GetSolidMeshGeometry(element); if (geomInfo.SolidsCount() > 0) { for (int ii = 0; ii < geomInfo.SolidsCount(); ++ii) { foreach (Face f in geomInfo.GetSolids()[ii].Faces) { areaSum += f.Area; } } } if (geomInfo.MeshesCount() > 0) { for (int jj = 0; jj < geomInfo.MeshesCount(); ++jj) { Mesh geomMesh = geomInfo.GetMeshes()[jj]; XYZ arbitraryOrig = geomMesh.Vertices[0]; for (int ii = 0; ii < geomMesh.NumTriangles; ++ii) { MeshTriangle meshTri = geomMesh.get_Triangle(ii); double a = meshTri.get_Vertex(1).DistanceTo(meshTri.get_Vertex(0)); double b = meshTri.get_Vertex(2).DistanceTo(meshTri.get_Vertex(1)); double c = meshTri.get_Vertex(0).DistanceTo(meshTri.get_Vertex(2)); areaSum += (a + b + c) / 2.0; } } } m_Area = UnitUtil.ScaleArea(areaSum); if (m_Area < MathUtil.Eps() * MathUtil.Eps() || m_Area < MathUtil.Eps()) { if (ParameterUtil.GetDoubleValueFromElementOrSymbol(element, "IfcQtyNetSurfaceArea", out m_Area) == null) { if (ParameterUtil.GetDoubleValueFromElementOrSymbol(element, "IfcNetSurfaceArea", out m_Area) == null) { ParameterUtil.GetDoubleValueFromElementOrSymbol(element, "NetSurfaceArea", out m_Area); } } m_Area = UnitUtil.ScaleArea(m_Area); if (m_Area < MathUtil.Eps() * MathUtil.Eps() || m_Area < MathUtil.Eps()) { return(false); } else { return(true); } } else { return(true); } }
/// <summary> /// Add the 2D projection of the given mesh triangles /// to the current element outline union /// </summary> static public bool AddToUnion( Polygons union, VertexLookup vl, Clipper c, Mesh m) { int n = m.NumTriangles; Polygons triangles = new Polygons(n); Polygon triangle = new Polygon(3); for (int i = 0; i < n; ++i) { MeshTriangle mt = m.get_Triangle(i); triangle.Clear(); triangle.Add(vl.GetOrAdd(mt.get_Vertex(0))); triangle.Add(vl.GetOrAdd(mt.get_Vertex(1))); triangle.Add(vl.GetOrAdd(mt.get_Vertex(2))); triangles.Add(triangle); } return(c.AddPaths(triangles, PolyType.ptSubject, true)); }
Stream(Mesh mesh) { for (int i = 0; i < mesh.NumTriangles; i++) { MeshTriangle mt = mesh.get_Triangle(i); Stream(mt.get_Vertex(0), mt.get_Vertex(1)); Stream(mt.get_Vertex(1), mt.get_Vertex(2)); Stream(mt.get_Vertex(2), mt.get_Vertex(0)); } }
public static Triangle3D ToSAM(this MeshTriangle meshTriangle) { return(new Triangle3D(meshTriangle.get_Vertex(0).ToSAM(), meshTriangle.get_Vertex(1).ToSAM(), meshTriangle.get_Vertex(2).ToSAM())); }
/// <summary> /// Get triangles in a solid with transform. /// </summary> /// <param name="solid">The solid contains triangulars</param> /// <param name="transform">The transformation.</param> private void GetTriangular(Document document, Solid solid, Transform transform) { // a solid has many faces FaceArray faces = solid.Faces; bool hasTransform = (null != transform); if (0 == faces.Size) { return; } foreach (Face face in faces) { if (face.Visibility != Visibility.Visible) { continue; } Mesh mesh; if (null != m_Settings.Detail) { mesh = face.Triangulate((double)m_Settings.Detail); } else { mesh = face.Triangulate(); } if (null == mesh) { continue; } m_TriangularNumber += mesh.NumTriangles; PlanarFace planarFace = face as PlanarFace; // write face to stl file // a face has a mesh, all meshes are made of triangles for (int ii = 0; ii < mesh.NumTriangles; ii++) { MeshTriangle triangular = mesh.get_Triangle(ii); double[] xyz = new double[9]; Autodesk.Revit.DB.XYZ normal = new Autodesk.Revit.DB.XYZ(); try { Autodesk.Revit.DB.XYZ[] triPnts = new Autodesk.Revit.DB.XYZ[3]; for (int n = 0; n < 3; ++n) { double x, y, z; Autodesk.Revit.DB.XYZ point = triangular.get_Vertex(n); if (hasTransform) { point = transform.OfPoint(point); } if (m_Settings.ExportSharedCoordinates) { ProjectPosition ps = document.ActiveProjectLocation.GetProjectPosition(point); x = ps.EastWest; y = ps.NorthSouth; z = ps.Elevation; } else { x = point.X; y = point.Y; z = point.Z; } if (m_Settings.Units != DisplayUnitType.DUT_UNDEFINED) { xyz[3 * n] = UnitUtils.ConvertFromInternalUnits(x, m_Settings.Units); xyz[3 * n + 1] = UnitUtils.ConvertFromInternalUnits(y, m_Settings.Units); xyz[3 * n + 2] = UnitUtils.ConvertFromInternalUnits(z, m_Settings.Units); } else { xyz[3 * n] = x; xyz[3 * n + 1] = y; xyz[3 * n + 2] = z; } var mypoint = new XYZ(xyz[3 * n], xyz[3 * n + 1], xyz[3 * n + 2]); triPnts[n] = mypoint; } Autodesk.Revit.DB.XYZ pnt1 = triPnts[1] - triPnts[0]; normal = pnt1.CrossProduct(triPnts[2] - triPnts[1]); } catch (Exception ex) { m_TriangularNumber--; STLDialogManager.ShowDebug(ex.Message); continue; } if (m_Writer is SaveDataAsBinary && m_Settings.ExportColor) { Material material = document.GetElement(face.MaterialElementId) as Material; if (material != null) { ((SaveDataAsBinary)m_Writer).Color = material.Color; } } m_Writer.WriteSection(normal, xyz); } } }
public static void Execute1( ExternalCommandData commandData) { Transaction trans = null; UIDocument uidoc = commandData.Application .ActiveUIDocument; Document doc = uidoc.Document; try { Selection choices = uidoc.Selection; Reference reference = choices.PickObject( ObjectType.Face); Element el = doc.GetElement( reference.ElementId); trans = new Transaction(doc, "Create elements"); trans.Start(); TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); builder.OpenConnectedFaceSet(false); Face face = el.GetGeometryObjectFromReference( reference) as Face; Mesh mesh = face.Triangulate(); List <XYZ> args = new List <XYZ>(3); XYZ offset = new XYZ(); if (el.Location is LocationPoint) { LocationPoint locationPoint = el.Location as LocationPoint; offset = locationPoint.Point; } for (int i = 0; i < mesh.NumTriangles; i++) { MeshTriangle triangle = mesh.get_Triangle( i); XYZ p1 = triangle.get_Vertex(0); XYZ p2 = triangle.get_Vertex(1); XYZ p3 = triangle.get_Vertex(2); p1 = p1.Add(offset); p2 = p2.Add(offset); p3 = p3.Add(offset); args.Clear(); args.Add(p1); args.Add(p2); args.Add(p3); TessellatedFace tesseFace = new TessellatedFace(args, ElementId.InvalidElementId); if (builder.DoesFaceHaveEnoughLoopsAndVertices( tesseFace)) { builder.AddFace(tesseFace); } } builder.CloseConnectedFaceSet(); //TessellatedShapeBuilderResult result // = builder.Build( // TessellatedShapeBuilderTarget.AnyGeometry, // TessellatedShapeBuilderFallback.Mesh, // ElementId.InvalidElementId ); // 2016 builder.Target = TessellatedShapeBuilderTarget.AnyGeometry; // 2018 builder.Fallback = TessellatedShapeBuilderFallback.Mesh; // 2018 builder.Build(); // 2018 TessellatedShapeBuilderResult result = builder.GetBuildResult(); // 2018 ElementId categoryId = new ElementId( BuiltInCategory.OST_GenericModel); //DirectShape ds = DirectShape.CreateElement( // doc, categoryId, // Assembly.GetExecutingAssembly().GetType() // .GUID.ToString(), Guid.NewGuid().ToString() ); // 2016 DirectShape ds = DirectShape.CreateElement( doc, categoryId); // 2018 ds.ApplicationId = Assembly.GetExecutingAssembly() .GetType().GUID.ToString(); // 2018 ds.ApplicationDataId = Guid.NewGuid().ToString(); // 2018 ds.SetShape(result.GetGeometricalObjects()); ds.Name = "MyShape"; trans.Commit(); } catch (Exception ex) { if (trans != null) { trans.RollBack(); } Debug.Print(ex.Message); } }
private void DataProcess(Solid geomSolid, GeometryInstance instance) { try { uint ufaces = 0; uint uVertices = 0; uint uPoints = 0; uint iStartId = (uint)d_VerticesList.Count; foreach (Face geomFace in geomSolid.Faces) { iStartId = (uint)d_VerticesList.Count; bool bNewFace = true; ufaces++; Mesh mesh = geomFace.Triangulate(); foreach (XYZ ii in mesh.Vertices) { uVertices++; XYZ point = ii; if (null != instance) { Transform instTransform = instance.Transform; XYZ transformedPoint = instTransform.OfPoint(point); } } uint iNextId = 0; for (int i = 0; i < mesh.NumTriangles; i++) { MeshTriangle triangle = mesh.get_Triangle(i); XYZ vertex = triangle.get_Vertex(0); if (bNewFace) { iNextId = iStartId / 3; bNewFace = false; } u_IndicesList.Add(3); AddVertex(iStartId, vertex, iNextId++); vertex = triangle.get_Vertex(1); AddVertex(iStartId, vertex, iNextId++); vertex = triangle.get_Vertex(2); AddVertex(iStartId, vertex, iNextId++); } XYZ origin = new XYZ(0, 0, 0); XYZ normal = new XYZ(0, 0, 0); XYZ vector = new XYZ(0, 0, 0); PlanarFace planarFace = geomFace as PlanarFace; if (null != planarFace) { origin = planarFace.Origin; normal = planarFace.Normal; vector = planarFace.get_Vector(0); } ConicalFace ConFace = geomFace as ConicalFace; if (null != ConFace) { origin = ConFace.Origin; normal = ConFace.Axis; vector = ConFace.get_Radius(0); } HermiteFace HermiteFace = geomFace as HermiteFace; if (null != HermiteFace) { origin = new XYZ(0, 0, 0); //HermiteFace.Points; normal = new XYZ(0, 0, 0); //HermiteFace.TaAxis; vector = new XYZ(0, 0, 0); //HermiteFace.get_Tangents(0); } RevolvedFace RevolFace = geomFace as RevolvedFace; if (null != RevolFace) { origin = RevolFace.Origin; normal = RevolFace.Axis; vector = RevolFace.get_Radius(0); } RuledFace RulFace = geomFace as RuledFace; if (null != RulFace) { origin = new XYZ(0, 0, 0); // RulFace.get_Point; normal = new XYZ(0, 0, 0); ///RulFace.Axis; vector = RulFace.get_Point(0); } CylindricalFace CylinFace = geomFace as CylindricalFace; if (null != CylinFace) { origin = CylinFace.Origin; normal = CylinFace.Axis; vector = CylinFace.get_Radius(0); } uint featuresCount = 0; for (int s = d_NormalsList.Count; s < d_VerticesList.Count; s += 3) { d_NormalsList.Add(normal.X); d_NormalsList.Add(normal.Y); d_NormalsList.Add(normal.Z); d_TextureCoordsList.Add(normal.X); d_TextureCoordsList.Add(normal.Y); d_TextureCoordsList.Add(normal.Z); featuresCount++; } u_FeaturesIndList.Add(featuresCount); } foreach (Edge edge in geomSolid.Edges) { foreach (XYZ ii in edge.Tessellate()) { uPoints++; XYZ point = ii; if (null != instance) { Transform instTransform = instance.Transform; XYZ transformedPoint = instTransform.OfPoint(point); } } }//foreach (Face geomFace in geomSolid.Faces) //string Osa = element.Name.ToString() + element.Id.ToString(); } catch (Exception e) { string message; // Exception rised, report it by revit error reporting mechanism. message = e.ToString(); File.AppendAllText(@"C:\CadFaster\Revit\ExeWriter_log.txt", message); //return Autodesk.Revit.UI.Result.Failed; } //End of DataProcess }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; double scale = 304.8; #region TEST ////cut line endpoints //XYZ v1 = new XYZ(0, 2000, 0)/scale; //XYZ v2 = new XYZ(6018, 2000, 0) / scale; ////rhino cut line endpoints // rg.Point3d rv0 = new rg.Point3d(0, 2000, 0); // rg.Point3d rv1 = new rg.Point3d(6018, 2000, 0); //rg.Point3d rv2 = new rg.Point3d(0, 2000, 1); ////rhino cut plane //rg.Plane cutPlane = new rg.Plane(rv0, rv1, rv2); ////wip points //rg.Point3d rv3 = new rg.Point3d(857, 203, 4597); //rg.Point3d rv4 = new rg.Point3d(857, 6221, 4597); //rg.Point3d rv5 = new rg.Point3d(9818, 6221, 4597); // //wip plane // rg.Plane rhinoPlane = new rg.Plane(rv3, rv4, rv5); // rg.Line intLine; // var result = rg.Intersect.Intersection.PlanePlane(cutPlane, rhinoPlane, out intLine); // using (Transaction t = new Transaction(doc, "Project Line")) // { // t.Start(); // SketchPlane sp = SketchPlane.Create(doc, RhinoToRevitPlane(cutPlane)); // doc.Create.NewModelCurve(RhinoToRevitLine(intLine), sp); // t.Commit(); // } // TaskDialog.Show("r", "Done"); #endregion #region Revit // SELECT THE LINE TO PROJECT AND CONSTRUCT THE PLANE TO INTERSECT THE MESH Reference lineToProject = uidoc.Selection.PickObject(ObjectType.Element, "Select cut Line"); Element lineElement = doc.GetElement(lineToProject); CurveElement curveLine = lineElement as CurveElement; LocationCurve lineLocation = lineElement.Location as LocationCurve; Line line = lineLocation.Curve as Line; rg.Line rhinoCutLine = new rg.Line(RevitToRhinoPoint(line.GetEndPoint(0)), RevitToRhinoPoint(line.GetEndPoint(1))); XYZ perpDir = line.Direction.CrossProduct(XYZ.BasisZ).Normalize(); Plane cutPlane = Plane.CreateByNormalAndOrigin(perpDir, line.GetEndPoint(0)); // GET THE MESH GEOMETRY Reference meshRef = uidoc.Selection.PickObject(ObjectType.Element, "Select Mesh"); Element e = doc.GetElement(meshRef); Options opt = new Options(); opt.ComputeReferences = true; opt.IncludeNonVisibleObjects = false; opt.View = doc.ActiveView; GeometryElement geomElem = e.get_Geometry(opt); Mesh geomMesh = null; foreach (GeometryObject geomObj in geomElem) { GeometryInstance gi = geomObj as GeometryInstance; if (gi != null) { foreach (GeometryObject element in gi.GetInstanceGeometry()) { geomMesh = element as Mesh; } } else { geomMesh = geomObj as Mesh; } } int counter = 0; using (Transaction t = new Transaction(doc, "Project Line")) { t.Start(); SketchPlane sp = SketchPlane.Create(doc, cutPlane); XYZ spOrigin = sp.GetPlane().Origin; Debug.Write($"Sketch plane origin: {spOrigin}\n"); XYZ spNormal = sp.GetPlane().Normal; Debug.Write($"Sketch plane normal: {spNormal}\n"); Line spX = Line.CreateBound(spOrigin, spOrigin + XYZ.BasisZ * 100); Debug.Write($"line start: {spX.GetEndParameter(0)}\n"); Debug.Write($"line end: {spX.GetEndParameter(1)}\n"); ModelCurve mc = doc.Create.NewModelCurve(spX, sp); Debug.Write($"mc: {mc.Id}\n"); List <XYZ> intersectionPoints = new List <XYZ>(); for (int i = 0; i < geomMesh.NumTriangles; i++) { MeshTriangle triangle = geomMesh.get_Triangle(i); XYZ vertex1 = triangle.get_Vertex(0); XYZ vertex2 = triangle.get_Vertex(1); XYZ vertex3 = triangle.get_Vertex(2); rg.Point3d rhinoVertex1 = RevitToRhinoPoint(vertex1); rg.Point3d rhinoVertex2 = RevitToRhinoPoint(vertex2); rg.Point3d rhinoVertex3 = RevitToRhinoPoint(vertex3); List <rg.Line> rhinoEdges = new List <rg.Line> { new rg.Line(rhinoVertex1, rhinoVertex2), new rg.Line(rhinoVertex1, rhinoVertex2), new rg.Line(rhinoVertex1, rhinoVertex2) }; XYZ[] pts = new XYZ[2]; int ptscount = 0; foreach (rg.Line edge in rhinoEdges) { double a = 0; double b = 0; bool result = rg.Intersect.Intersection.LineLine(edge, rhinoCutLine, out a, out b); if (result) { intersectionPoints.Add(RhinoToRevitPoint(edge.PointAt(a))); pts[ptscount] = RhinoToRevitPoint(edge.PointAt(a)); ptscount = 1; counter++; } } if (pts[0] != null) { try { Line temp = Line.CreateBound(pts[0], pts[0] + XYZ.BasisZ * 100); //Line li = Line.CreateBound(pts[0], new XYZ(pts[0].X, pts[0].Y, pts[0].Z +100)); doc.Create.NewModelCurve(temp, sp); } catch { } } } t.Commit(); } TaskDialog.Show("Intersections found", counter.ToString()); #endregion return(Result.Succeeded); }
void SubDivideSoffits_CreateFireRatedLayers(Document doc) { try { #region Get Soffits List <Element> Soffits = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).ToElements().Where(m => !(m is ElementType)).ToList(); #endregion //Subdivide foreach (Element Soffit in Soffits.Where(m => m.Name.ToLower().Contains("eave"))) { #region Get Soffit Geometry Options ops = new Options(); ops.DetailLevel = ViewDetailLevel.Fine; ops.IncludeNonVisibleObjects = true; GeometryElement Geo = Soffit.get_Geometry(ops); #endregion foreach (var item in Geo) { if (item is Solid) { #region Get one of the Main Faces, it doesn't really matter if it is top or bottom Solid GSol = item as Solid; List <Face> Fs = new List <Face>(); foreach (Face f in GSol.Faces) { Fs.Add(f); } Face F = Fs.Where(m => m.Area == Fs.Max(a => a.Area)).First(); #endregion #region Triangulate the Face with max detail Mesh M = F.Triangulate(1); #endregion #region Create Variables for: the curves that will define the new Soffits, List of Custom Triangle Class, List of Custom Pair of Triangle Class List <List <Curve> > LLC = new List <List <Curve> >(); List <Triangle> Triangles = new List <Triangle>(); List <TrianglePair> TPairs = new List <TrianglePair>(); #endregion #region Loop Through Triangles & Add Them to the list of My Triangle Class for (int i = 0; i < M.NumTriangles; i++) { List <Curve> LC = new List <Curve>(); #region Make List of Curves From Triangle MeshTriangle MT = M.get_Triangle(i); List <Curve> Curves = new List <Curve>(); Curve C = Line.CreateBound(MT.get_Vertex(0), MT.get_Vertex(1)) as Curve; Curves.Add(C); C = Line.CreateBound(MT.get_Vertex(1), MT.get_Vertex(2)) as Curve; Curves.Add(C); C = Line.CreateBound(MT.get_Vertex(2), MT.get_Vertex(0)) as Curve; Curves.Add(C); #endregion Triangle T = new Triangle(); T.Sides = new List <Curve>(); T.Sides = Curves; T.Vertices = new List <XYZ>(); T.Vertices.Add(MT.get_Vertex(0)); T.Vertices.Add(MT.get_Vertex(1)); T.Vertices.Add(MT.get_Vertex(2)); Triangles.Add(T); } #endregion #region Loop Through Triangles And Create Trapezoid Pairs To Catch The Segments, Getting Rid of The Shared sides bool GO = true; do { Triangle TKeeper1 = new Triangle(); Triangle TKeeper2 = new Triangle(); foreach (Triangle T in Triangles) { TKeeper1 = new Triangle(); foreach (Triangle T2 in Triangles) { TKeeper2 = new Triangle(); if (T != T2) { if (FindCurvesFacing(T, T2) != null) { if (FindCurvesFacing(T, T2)[0].Length == T.Sides.Min(c => c.Length) || FindCurvesFacing(T, T2)[1].Length == T2.Sides.Min(c => c.Length)) { continue; } Curve[] Cs = FindCurvesFacing(T, T2); T.Sides.Remove(Cs[0]); T2.Sides.Remove(Cs[1]); if (T.Sides.Count() == 2 && T2.Sides.Count() == 2) { TKeeper1 = T; TKeeper2 = T2; goto ADDANDGOROUND; } } } } } GO = false; ADDANDGOROUND: if (GO) { Triangles.Remove(TKeeper1); Triangles.Remove(TKeeper2); TrianglePair TP = new TrianglePair(); TP.T1 = TKeeper1; TP.T2 = TKeeper2; TPairs.Add(TP); } } while(GO); #endregion #region Create Curve Loops From Triangle Pairs foreach (TrianglePair TPair in TPairs) { List <Curve> Cs = new List <Curve>(); Cs.AddRange(TPair.T1.Sides); Cs.AddRange(TPair.T2.Sides); LLC.Add(Cs); } #endregion double Offset = Convert.ToDouble(Soffit.LookupParameter("Height Offset From Level").AsValueString()); FloorType FT = (Soffit as Floor).FloorType; Level Lvl = doc.GetElement((Soffit as Floor).LevelId) as Level; #region Delete Old Soffit If All Went Well using (Transaction T = new Transaction(doc, "Delete Soffit")) { T.Start(); doc.Delete(Soffit.Id); T.Commit(); } #endregion #region Sort The Lists of Curves and Create The New Segments foreach (List <Curve> LC in LLC) { List <Curve> LCSorted = new List <Curve>(); try { LCSorted = SortCurvesContiguous(LC, false); } #region Exception Details if Curves Could not be sorted catch (Exception EXC) { string exmsge = EXC.Message; } #endregion CurveArray CA = new CurveArray(); foreach (Curve C in LCSorted) { CA.Append(C); } using (Transaction T = new Transaction(doc, "Make Segment")) { T.Start(); Floor newFloor = doc.Create.NewFloor(CA, FT, Lvl, false); newFloor.LookupParameter("Height Offset From Level").SetValueString(Offset.ToString()); T.Commit(); } } #endregion } } } //refresh collection Soffits = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).ToElements().Where(m => !(m is ElementType)).ToList(); //test soffits for needing fire rating foreach (Element Soffit in Soffits.Where(m => m.Name.ToLower().Contains("eave"))) { #region Get Soffit Geometry Options ops = new Options(); ops.DetailLevel = ViewDetailLevel.Fine; ops.IncludeNonVisibleObjects = true; GeometryElement Geo = Soffit.get_Geometry(ops); #endregion foreach (var item in Geo) { if (item is Solid) { #region Find boundary Void Element List <Element> MaybeBoundary = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).ToElements().Where(m => !(m is ElementType)).ToList(); Element BoundryElement = MaybeBoundary.Where(m => !(m is FloorType) && m.Name == "Boundary").First(); #endregion #region Get Intersection of Boundary and eave PolygonAnalyser com = new PolygonAnalyser(); List <CurveArray> CArray = com.Execute(BoundryElement as Floor, Soffit as Floor); Level L = doc.GetElement(Soffit.LevelId) as Level; #endregion foreach (CurveArray CA in CArray) { #region Sort The Curves IList <Curve> CAL = new List <Curve>(); foreach (Curve C in CA) { CAL.Add(C); } List <Curve> Curves = SortCurvesContiguous(CAL, false); List <XYZ> NewCurveEnds = new List <XYZ>(); #endregion #region Close the loop if nesesary CurveLoop CL = new CurveLoop(); foreach (Curve curv in Curves) { CL.Append(curv); } if (CL.IsOpen()) { Curves.Add(Line.CreateBound(CL.First().GetEndPoint(0), CL.Last().GetEndPoint(1)) as Curve); } #endregion #region Recreate a Curve Array Curves = SortCurvesContiguous(Curves, false); CurveArray CA2 = new CurveArray(); int i = 0; foreach (Curve c in Curves) { CA2.Insert(c, i); i += 1; } #endregion #region Create The New Fire Rated Layer element FloorType ft = new FilteredElementCollector(doc).WhereElementIsElementType().OfCategory(BuiltInCategory.OST_Floors).ToElements().Where(m => m.Name == "Fire Rated Layer").First() as FloorType; Transaction T = new Transaction(doc, "Fire Rated Layer Creation"); try { T.Start(); Floor F = doc.Create.NewFloor(CA2, ft, L, false); string s = Soffit.LookupParameter("Height Offset From Level").AsValueString(); double si = Convert.ToDouble(s); si = si + (Convert.ToDouble(Soffit.LookupParameter("Thickness").AsValueString())); F.LookupParameter("Height Offset From Level").SetValueString(si.ToString()); T.Commit(); } catch (Exception EX) { T.RollBack(); string EXmsg = EX.Message; } #endregion } } } } } catch (Exception ex) { string mesg = ex.Message; } }
public static void Execute( ExternalCommandData commandData) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Document doc = uidoc.Document; Selection choices = uidoc.Selection; try { Reference reference = choices.PickObject( ObjectType.Face); Element el = doc.GetElement( reference.ElementId); Face face = el.GetGeometryObjectFromReference( reference) as Face; Mesh mesh = face.Triangulate(); var familyInstance = el as FamilyInstance; if (null != familyInstance) { var t = familyInstance .GetTotalTransform(); mesh = mesh.get_Transformed(t); } using (Transaction trans = new Transaction(doc)) { trans.Start("Create DirectShape from Face"); TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); builder.OpenConnectedFaceSet(false); List <XYZ> args = new List <XYZ>(3); XYZ[] triangleCorners = new XYZ[3]; for (int i = 0; i < mesh.NumTriangles; ++i) { MeshTriangle triangle = mesh.get_Triangle(i); triangleCorners[0] = triangle.get_Vertex(0); triangleCorners[1] = triangle.get_Vertex(1); triangleCorners[2] = triangle.get_Vertex(2); TessellatedFace tesseFace = new TessellatedFace(triangleCorners, ElementId.InvalidElementId); if (builder.DoesFaceHaveEnoughLoopsAndVertices( tesseFace)) { builder.AddFace(tesseFace); } } builder.CloseConnectedFaceSet(); //TessellatedShapeBuilderResult result // = builder.Build( // TessellatedShapeBuilderTarget.AnyGeometry, // TessellatedShapeBuilderFallback.Mesh, // ElementId.InvalidElementId ); // 2016 builder.Target = TessellatedShapeBuilderTarget.AnyGeometry; // 2018 builder.Fallback = TessellatedShapeBuilderFallback.Mesh; // 2018 builder.Build(); // 2018 TessellatedShapeBuilderResult result = builder.GetBuildResult(); // 2018 ElementId categoryId = new ElementId( BuiltInCategory.OST_GenericModel); //DirectShape ds = DirectShape.CreateElement( // doc, categoryId, // Assembly.GetExecutingAssembly().GetType() // .GUID.ToString(), Guid.NewGuid().ToString() ); // 2016 DirectShape ds = DirectShape.CreateElement( doc, categoryId); // 2018 ds.ApplicationId = Assembly.GetExecutingAssembly() .GetType().GUID.ToString(); // 2018 ds.ApplicationDataId = Guid.NewGuid().ToString(); // 2018 ds.SetShape(result.GetGeometricalObjects()); ds.Name = "MyShape"; trans.Commit(); } } catch (Exception ex) { Debug.Print(ex.Message); } }
/// <summary> /// Builds the geometry based on the selected element. /// </summary> private void FillGeometryOfSelectedElement() { List <Triangle> triangles = new List <Triangle>(); Options opt = ThisMainExtension.Revit.ActiveDocument.Application.Create.NewGeometryOptions(); opt.DetailLevel = ViewDetailLevel.Fine; GeometryElement gel = ThisMainExtension.Data.SelectedElement.get_Geometry(opt); foreach (GeometryObject geoObject in gel) { Solid s = geoObject as Solid; if (null != s) { foreach (Face f in s.Faces) { Mesh m = f.Triangulate(); for (int i = 0; i < m.NumTriangles; i++) { MeshTriangle mt = m.get_Triangle(i); XYZ pt1 = mt.get_Vertex(0); XYZ pt2 = mt.get_Vertex(1); XYZ pt3 = mt.get_Vertex(2); triangles.Add(new Triangle(new REX.Common.Geometry.REXxyz(pt1.X, pt1.Y, pt1.Z), new REX.Common.Geometry.REXxyz(pt2.X, pt2.Y, pt2.Z), new REX.Common.Geometry.REXxyz(pt3.X, pt3.Y, pt3.Z))); } } continue; } GeometryInstance inst = geoObject as GeometryInstance; if (null != inst) { foreach (GeometryObject o in inst.SymbolGeometry) { s = o as Solid; if (s != null) { foreach (Face f in s.Faces) { Mesh m = f.Triangulate(); m = m.get_Transformed(inst.Transform); for (int i = 0; i < m.NumTriangles; i++) { MeshTriangle mt = m.get_Triangle(i); XYZ pt1 = mt.get_Vertex(0); XYZ pt2 = mt.get_Vertex(1); XYZ pt3 = mt.get_Vertex(2); triangles.Add(new Triangle(new REX.Common.Geometry.REXxyz(pt1.X, pt1.Y, pt1.Z), new REX.Common.Geometry.REXxyz(pt2.X, pt2.Y, pt2.Z), new REX.Common.Geometry.REXxyz(pt3.X, pt3.Y, pt3.Z))); } } } } } } ThisMainExtension.Data.SelectedElementGeometry = triangles; }
private void Stream(ArrayList data, MeshTriangle meshTri) { data.Add(new Snoop.Data.ClassSeparator(typeof(MeshTriangle))); // TBD: not sure what get_index() is all about?? data.Add(new Snoop.Data.Xyz("Vertex [0]", meshTri.get_Vertex(0))); data.Add(new Snoop.Data.Xyz("Vertex [1]", meshTri.get_Vertex(1))); data.Add(new Snoop.Data.Xyz("Vertex [2]", meshTri.get_Vertex(2))); }
/// <summary> /// Create a new list of geometry objects from the /// given input. As input, we supply the result of /// Room.GetClosedShell. The output is the exact /// same solid lacking whatever flaws are present /// in the input solid. /// </summary> static IList <GeometryObject> CopyGeometry( GeometryElement geo, ElementId materialId, List <IntPoint3d> coords, List <TriangleIndices> indices) { TessellatedShapeBuilderResult result = null; TessellatedShapeBuilder builder = new TessellatedShapeBuilder(); // Need to include the key in the value, otherwise // no way to access it later, cf. // https://stackoverflow.com/questions/1619090/getting-a-keyvaluepair-directly-from-a-dictionary Dictionary <XYZ, KeyValuePair <XYZ, int> > pts = new Dictionary <XYZ, KeyValuePair <XYZ, int> >( new XyzEqualityComparer()); int nSolids = 0; //int nFaces = 0; int nTriangles = 0; //int nVertices = 0; List <XYZ> vertices = new List <XYZ>(3); foreach (GeometryObject obj in geo) { Solid solid = obj as Solid; if (null != solid) { if (0 < solid.Volume) { ++nSolids; builder.OpenConnectedFaceSet(false); #region Create a new solid based on tessellation of the invalid room closed shell solid #if CREATE_NEW_SOLID_USING_TESSELATION Debug.Assert( SolidUtils.IsValidForTessellation(solid), "expected a valid solid for room closed shell"); SolidOrShellTessellationControls controls = new SolidOrShellTessellationControls() { // // Summary: // A positive real number specifying how accurately a triangulation should approximate // a solid or shell. // // Exceptions: // T:Autodesk.Revit.Exceptions.ArgumentOutOfRangeException: // When setting this property: The given value for accuracy must be greater than // 0 and no more than 30000 feet. // This statement is not true. I set Accuracy = 0.003 and an exception was thrown. // Setting it to 0.006 was acceptable. 0.03 is a bit over 9 mm. // // Remarks: // The maximum distance from a point on the triangulation to the nearest point on // the solid or shell should be no greater than the specified accuracy. This constraint // may be approximately enforced. Accuracy = 0.03, // // Summary: // An number between 0 and 1 (inclusive) specifying the level of detail for the // triangulation of a solid or shell. // // Exceptions: // T:Autodesk.Revit.Exceptions.ArgumentOutOfRangeException: // When setting this property: The given value for levelOfDetail must lie between // 0 and 1 (inclusive). // // Remarks: // Smaller values yield coarser triangulations (fewer triangles), while larger values // yield finer triangulations (more triangles). LevelOfDetail = 0.1, // // Summary: // A non-negative real number specifying the minimum allowed angle for any triangle // in the triangulation, in radians. // // Exceptions: // T:Autodesk.Revit.Exceptions.ArgumentOutOfRangeException: // When setting this property: The given value for minAngleInTriangle must be at // least 0 and less than 60 degrees, expressed in radians. The value 0 means to // ignore the minimum angle constraint. // // Remarks: // A small value can be useful when triangulating long, thin objects, in order to // keep the number of triangles small, but it can result in long, thin triangles, // which are not acceptable for all applications. If the value is too large, this // constraint may not be satisfiable, causing the triangulation to fail. This constraint // may be approximately enforced. A value of 0 means to ignore the minimum angle // constraint. MinAngleInTriangle = 3 * Math.PI / 180.0, // // Summary: // A positive real number specifying the minimum allowed value for the external // angle between two adjacent triangles, in radians. // // Exceptions: // T:Autodesk.Revit.Exceptions.ArgumentOutOfRangeException: // When setting this property: The given value for minExternalAngleBetweenTriangles // must be greater than 0 and no more than 30000 feet. // // Remarks: // A small value yields more smoothly curved triangulated surfaces, usually at the // expense of an increase in the number of triangles. Note that this setting has // no effect for planar surfaces. This constraint may be approximately enforced. MinExternalAngleBetweenTriangles = 0.2 * Math.PI }; TriangulatedSolidOrShell shell = SolidUtils.TessellateSolidOrShell(solid, controls); int n = shell.ShellComponentCount; Debug.Assert(1 == n, "expected just one shell component in room closed shell"); TriangulatedShellComponent component = shell.GetShellComponent(0); int coordsBase = coords.Count; int indicesBase = indices.Count; n = component.VertexCount; for (int i = 0; i < n; ++i) { XYZ v = component.GetVertex(i); coords.Add(new IntPoint3d(v)); } n = component.TriangleCount; for (int i = 0; i < n; ++i) { TriangleInShellComponent t = component.GetTriangle(i); vertices.Clear(); vertices.Add(component.GetVertex(t.VertexIndex0)); vertices.Add(component.GetVertex(t.VertexIndex1)); vertices.Add(component.GetVertex(t.VertexIndex2)); indices.Add(new TriangleIndices( coordsBase + t.VertexIndex0, coordsBase + t.VertexIndex1, coordsBase + t.VertexIndex2)); TessellatedFace tf = new TessellatedFace( vertices, materialId); if (builder.DoesFaceHaveEnoughLoopsAndVertices(tf)) { builder.AddFace(tf); ++nTriangles; } } #else // Iterate over the individual solid faces foreach (Face f in solid.Faces) { vertices.Clear(); #region Use face triangulation #if USE_FACE_TRIANGULATION Mesh mesh = f.Triangulate(); int n = mesh.NumTriangles; for (int i = 0; i < n; ++i) { MeshTriangle triangle = mesh.get_Triangle(i); XYZ p1 = triangle.get_Vertex(0); XYZ p2 = triangle.get_Vertex(1); XYZ p3 = triangle.get_Vertex(2); vertices.Clear(); vertices.Add(p1); vertices.Add(p2); vertices.Add(p3); TessellatedFace tf = new TessellatedFace( vertices, materialId); if (builder.DoesFaceHaveEnoughLoopsAndVertices(tf)) { builder.AddFace(tf); ++nTriangles; } } #endif // USE_FACE_TRIANGULATION #endregion // Use face triangulation #region Use original solid and its EdgeLoops #if USE_EDGELOOPS // This returns arbitrarily ordered and // oriented edges, so no solid can be // generated. foreach (EdgeArray loop in f.EdgeLoops) { foreach (Edge e in loop) { XYZ p = e.AsCurve().GetEndPoint(0); XYZ q = p; if (pts.ContainsKey(p)) { KeyValuePair <XYZ, int> kv = pts[p]; q = kv.Key; int n = kv.Value; pts[p] = new KeyValuePair <XYZ, int>( q, ++n); Debug.Print("Ignoring vertex at {0} " + "with distance {1} to existing " + "vertex {2}", p, p.DistanceTo(q), q); } else { pts[p] = new KeyValuePair <XYZ, int>( p, 1); } vertices.Add(q); ++nVertices; } } #endif // USE_EDGELOOPS #endregion // Use original solid and its EdgeLoops #region Use original solid and GetEdgesAsCurveLoops #if USE_AS_CURVE_LOOPS // The solids generated by this have some weird // normals, so they do not render correctly in // the Forge viewer. Revert to triangles again. IList <CurveLoop> loops = f.GetEdgesAsCurveLoops(); foreach (CurveLoop loop in loops) { foreach (Curve c in loop) { XYZ p = c.GetEndPoint(0); XYZ q = p; if (pts.ContainsKey(p)) { KeyValuePair <XYZ, int> kv = pts[p]; q = kv.Key; int n = kv.Value; pts[p] = new KeyValuePair <XYZ, int>( q, ++n); Debug.Print("Ignoring vertex at {0} " + "with distance {1} to existing " + "vertex {2}", p, p.DistanceTo(q), q); } else { pts[p] = new KeyValuePair <XYZ, int>( p, 1); } vertices.Add(q); ++nVertices; } } #endif // USE_AS_CURVE_LOOPS #endregion // Use original solid and GetEdgesAsCurveLoops builder.AddFace(new TessellatedFace( vertices, materialId)); ++nFaces; } #endif // CREATE_NEW_SOLID_USING_TESSELATION #endregion // Create a new solid based on tessellation of the invalid room closed shell solid builder.CloseConnectedFaceSet(); builder.Target = TessellatedShapeBuilderTarget.AnyGeometry; // Solid failed builder.Fallback = TessellatedShapeBuilderFallback.Mesh; // use Abort if target is Solid builder.Build(); result = builder.GetBuildResult(); // Debug printout log of current solid's glTF facet data n = coords.Count - coordsBase; Debug.Print("{0} glTF vertex coordinates " + "in millimetres:", n); Debug.Print(string.Join(" ", coords .TakeWhile <IntPoint3d>((p, i) => coordsBase <= i) .Select <IntPoint3d, string>(p => p.ToString()))); n = indices.Count - indicesBase; Debug.Print("{0} glTF triangles:", n); Debug.Print(string.Join(" ", indices .TakeWhile <TriangleIndices>((ti, i) => indicesBase <= i) .Select <TriangleIndices, string>(ti => ti.ToString()))); } } } return(result.GetGeometricalObjects()); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; Document doc = uidoc.Document; //WALLS FACES List <PlanarFace> wallFaces = new List <PlanarFace>(); //WALLS Reference wallRef = uidoc.Selection.PickObject(ObjectType.Element, "Select a Wall"); Element wall = doc.GetElement(wallRef); LocationCurve lc = wall.Location as LocationCurve; Line wallLine = lc.Curve as Line; XYZ perpDir = wallLine.Direction.CrossProduct(XYZ.BasisZ); Options opt = new Options(); opt.ComputeReferences = true; opt.IncludeNonVisibleObjects = false; opt.View = doc.ActiveView; GeometryElement geomElem = doc.GetElement(wallRef).get_Geometry(opt); foreach (GeometryObject geomObj in geomElem) { Solid geomSolid = geomObj as Solid; foreach (Face geomFace in geomSolid.Faces) { XYZ faceNormal = geomFace.ComputeNormal(new UV(0.5, 0.5)); //select only the vertical faces if (faceNormal.CrossProduct(perpDir).IsAlmostEqualTo(XYZ.Zero)) { PlanarFace pf = geomFace as PlanarFace; wallFaces.Add(pf); } } } //GET MESH Reference meshRef = uidoc.Selection.PickObject(ObjectType.Element, "Select Mesh"); Element e = doc.GetElement(meshRef); GeometryElement geomElemSurvey = e.get_Geometry(opt); Mesh geomMesh = null; foreach (GeometryObject geomObj in geomElemSurvey) { try { GeometryInstance gi = geomObj as GeometryInstance; foreach (GeometryObject element in gi.GetInstanceGeometry()) { geomMesh = element as Mesh; } } catch { geomMesh = geomObj as Mesh; } } using (Transaction t = new Transaction(doc, "Find intersection")) { t.Start(); List <XYZ> intPts = new List <XYZ>(); for (int i = 0; i < geomMesh.NumTriangles; i++) { MeshTriangle triangle = geomMesh.get_Triangle(i); XYZ vertex1 = triangle.get_Vertex(0); XYZ vertex2 = triangle.get_Vertex(1); XYZ vertex3 = triangle.get_Vertex(2); Line[] edgeList = new Line[3]; try { Line[] edges = new Line[] { Line.CreateBound(vertex1, vertex2), Line.CreateBound(vertex1, vertex3), Line.CreateBound(vertex2, vertex3) }; for (int k = 0; k < edgeList.Length; k++) { edgeList[k] = edges[k]; } } catch { } // Plane facePlane = Plane.CreateByThreePoints(vertex1, vertex2, vertex3); // SketchPlane sp = SketchPlane.Create(doc, facePlane); // doc.Create.NewModelCurve(edge12, sp); // doc.Create.NewModelCurve(edge13, sp); // doc.Create.NewModelCurve(edge23, sp); foreach (PlanarFace pf in wallFaces) { XYZ[] pts = new XYZ[2]; int count = 0; if (edgeList[0] != null) { foreach (Line edge in edgeList) { IntersectionResultArray intersections = null; SetComparisonResult scr = pf.Intersect(edge, out intersections); if (scr == SetComparisonResult.Overlap && intersections.Size == 1) { for (int j = 0; j < intersections.Size; j++) { //TaskDialog.Show("r", intersections.get_Item(i)); } //TaskDialog.Show("r", intersections.Size.ToString()); IntersectionResult iResult = intersections.get_Item(0); intPts.Add(iResult.XYZPoint); pts[count] = iResult.XYZPoint; count = 1; if (pts.Length == 2 && pts[1] != null) { // TaskDialog.Show("r", String.Format("{0}\n{1}",pts[0], pts[1])); try { Plane wallPlane = Plane.CreateByNormalAndOrigin(pf.FaceNormal, pf.Origin); SketchPlane spWall = SketchPlane.Create(doc, wallPlane); doc.Create.NewModelCurve(Line.CreateBound(pts[0], pts[1]), spWall); } catch { } } } } } } } t.Commit(); } return(Result.Succeeded); }