/// <summary> /// Given an array of edges, weeds out any edges /// not present on the desired plane /// </summary> /// <param name="xyzArray">the array of edges </param> /// <param name="normal">normal to the desired plane</param> /// <returns>edges on the desired plane</returns> public static EdgeArray GetEdgesOnPlane(EdgeArray edgeArray, XYZ normal) { EdgeArray edgesOnPlane = new EdgeArray(); for (int i = 0; i < edgeArray.Size; i++) { IList<XYZ> xyzArray = edgeArray.get_Item(i).Tessellate(); if (normal.Equals(GeomUtils.kXAxis)) { if (xyzArray[0].X == xyzArray[1].X) { edgesOnPlane.Append(edgeArray.get_Item(i)); } } if (normal.Equals(GeomUtils.kYAxis)) { if (xyzArray[0].Y == xyzArray[1].Y) { edgesOnPlane.Append(edgeArray.get_Item(i)); } } if (normal.Equals(GeomUtils.kZAxis)) { if (xyzArray[0].Z == xyzArray[1].Z) { edgesOnPlane.Append(edgeArray.get_Item(i)); } } } return edgesOnPlane; }
ToCurveArray(EdgeArray edgeArray, CurveArray curveArray) { EdgeArrayIterator edgeArrayIter = edgeArray.ForwardIterator(); while (edgeArrayIter.MoveNext()) { Edge edge = edgeArrayIter.Current as Edge; XYZ startPt = edge.Tessellate()[0]; XYZ endPt = edge.Tessellate()[1]; Line curve = Line.CreateBound(startPt, endPt); curveArray.Append(curve); } return(curveArray); }
private CurveArray GetCurveArrayFromEdgeArary(EdgeArray edgeArray) { CurveArray curveArray = new CurveArray(); foreach (Edge edge in edgeArray) { var edgeCurve = edge.AsCurve(); curveArray.Append(edgeCurve); } return(curveArray); }
/***************************************************/ public static List <oM.Geometry.ICurve> FromRevit(this EdgeArray edgeArray) { if (edgeArray == null) { return(null); } List <oM.Geometry.ICurve> result = new List <oM.Geometry.ICurve>(); foreach (Edge edge in edgeArray) { result.Add(edge.FromRevit()); } return(result); }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = uiapp.ActiveUIDocument; Application app = uiapp.Application; doc = uidoc.Document; Selection sel = uidoc.Selection; Reference rf = sel.PickObject(ObjectType.Element); ElementtransformToCopy kl = new ElementtransformToCopy(); Element ele = doc.GetElement(rf); FamilyInstance familyInstance = ele as FamilyInstance; FamilyInstance flat = kl.GetFlat(doc, familyInstance); var t1 = flat.GetReferences(FamilyInstanceReferenceType.StrongReference).First(); var t2 = flat.GetReferences(FamilyInstanceReferenceType.StrongReference).First(); Transform transform = flat.GetTransform(); EdgeArray edgeArray = kl.FlEdgeArray(flat); List <Edge> list = new List <Edge>(); foreach (Edge i in edgeArray) { list.Add(i); } list.OrderBy(i => i.ApproximateLength).ToList(); Edge max = list.Last(); Curve cure = max.AsCurve(); Line lop = cure as Line; ReferenceArray referenceArray = new ReferenceArray(); XYZ startpoint = lop.GetEndPoint(0); XYZ endpoint = lop.GetEndPoint(1); using (Transaction tr = new Transaction(doc, "cre")) { tr.Start(); Line line = Line.CreateBound(transform.OfPoint(startpoint), transform.OfPoint(endpoint)); DetailLine detailLine = doc.Create.NewDetailCurve(doc.ActiveView, line) as DetailLine; referenceArray.Append(t1); referenceArray.Append(t2); var t = doc.Create.NewDimension(doc.ActiveView, line, referenceArray); tr.Commit(); } return(Result.Succeeded); }
/// <summary> /// Finds candidate path edges from a side face with two edges on the profile face. /// </summary> /// <param name="face">The side face.</param> /// <param name="edge0">The edge on the profile face and the side face.</param> /// <param name="edge1">The edge on the profile face and the side face.</param> /// <returns>The potential path edges. Should at least have two path on one face</returns> private static List <Edge> FindCandidatePathEdge(Face face, Edge edge0, Edge edge1) { double vertexEps = ExporterCacheManager.Document.Application.VertexTolerance; Curve curve0 = edge0.AsCurveFollowingFace(face); Curve curve1 = edge1.AsCurveFollowingFace(face); XYZ[,] endPoints = new XYZ[2, 2] { { curve0.GetEndPoint(0), curve1.GetEndPoint(1) }, { curve0.GetEndPoint(1), curve1.GetEndPoint(0) } }; List <Edge> candidatePathEdges = new List <Edge>(); EdgeArray outerEdgeLoop = face.EdgeLoops.get_Item(0); foreach (Edge edge in outerEdgeLoop) { XYZ endPoint0 = edge.Evaluate(0); XYZ endPoint1 = edge.Evaluate(1); for (int ii = 0; ii < 2; ii++) { bool found = false; for (int jj = 0; jj < 2; jj++) { if (endPoint0.IsAlmostEqualTo(endPoints[ii, jj], vertexEps)) { int kk = 1 - jj; if (endPoint1.IsAlmostEqualTo(endPoints[ii, kk], vertexEps)) { candidatePathEdges.Add(edge); found = true; break; } } } if (found) { break; } } } return(candidatePathEdges); }
/// <summary> /// Calculate geometry info for Slab /// </summary> public void GetSlabProfileInfo() { // get all the edges of the Slab m_edges = GetFloorEdges(); // Get a matrix which can transform points to 2D m_to2DMatrix = GetTo2DMatrix(); // get the boundary of all the points m_boundPoints = GetBoundsPoints(); // get a matrix which can keep all the points in the center of the canvas m_moveToCenterMatrix = GetMoveToCenterMatrix(); // get a matrix for scaling all the points and lines within the canvas m_scaleMatrix = GetScaleMatrix(); // get a matrix for moving all point in the middle of PictureBox m_MoveToPictureBoxCenter = GetMoveToCenterOfPictureBox(); // transform 3D points to 2D m_transformMatrix = Get3DTo2DMatrix(); // transform from 2D to 3D m_restoreMatrix = Get2DTo3DMatrix(); }
private static CurveLoop GetFaceBoundary(Face face, EdgeArray faceBoundary, XYZ baseLoopOffset, bool polygonalOnly, out FaceBoundaryType faceBoundaryType) { faceBoundaryType = FaceBoundaryType.Polygonal; CurveLoop currLoop = new CurveLoop(); foreach (Edge faceBoundaryEdge in faceBoundary) { Curve edgeCurve = faceBoundaryEdge.AsCurveFollowingFace(face); Curve offsetCurve = (baseLoopOffset != null) ? MoveCurve(edgeCurve, baseLoopOffset) : edgeCurve; if (!(offsetCurve is Line)) { if (polygonalOnly) { IList <XYZ> tessPts = offsetCurve.Tessellate(); int numTessPts = tessPts.Count; for (int ii = 0; ii < numTessPts - 1; ii++) { Line line = Line.get_Bound(tessPts[ii], tessPts[ii + 1]); currLoop.Append(line); } } else { currLoop.Append(offsetCurve); } if (offsetCurve is Arc) { faceBoundaryType = FaceBoundaryType.LinesAndArcs; } else { faceBoundaryType = FaceBoundaryType.Complex; } } else { currLoop.Append(offsetCurve); } } return(currLoop); }
public EdgeGrid(int x, int y, int z) { Debug.Log("Creating the EdgeGrid: " + Time.realtimeSinceStartup.ToString()); _grid = new EdgeArray[x, y, z]; for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { for (int k = 0; k < z; k++) { _grid[i, j, k] = new EdgeArray(); } } } Debug.Log("EdgeGrid created: " + Time.realtimeSinceStartup.ToString()); } // End of constructor
/// <summary> /// Finds candidate path edges from a side face with two edges on the profile face. /// </summary> /// <param name="face">The side face.</param> /// <param name="edge0">The edge on the profile face and the side face.</param> /// <param name="edge1">The edge on the profile face and the side face.</param> /// <returns>The potential path edges. Should at least have two path on one face</returns> private static List <Edge> FindCandidatePathEdge(Face face, Edge edge0, Edge edge1) { Curve curve0 = edge0.AsCurveFollowingFace(face); Curve curve1 = edge1.AsCurveFollowingFace(face); XYZ[,] endPoints = new XYZ[2, 2] { { curve0.GetEndPoint(0), curve1.GetEndPoint(1) }, { curve0.GetEndPoint(1), curve1.GetEndPoint(0) } }; List <Edge> candidatePathEdges = new List <Edge>(); EdgeArray outerEdgeLoop = face.EdgeLoops.get_Item(0); foreach (Edge edge in outerEdgeLoop) { XYZ endPoint0 = edge.Evaluate(0); XYZ endPoint1 = edge.Evaluate(1); for (int i = 0; i < 2; i++) { bool found = false; for (int j = 0; j < 2; j++) { if (endPoint0.IsAlmostEqualTo(endPoints[i, j], MathUtil.VertexEps)) { int k = 1 - j; if (endPoint1.IsAlmostEqualTo(endPoints[i, k], MathUtil.VertexEps)) { candidatePathEdges.Add(edge); found = true; break; } } } if (found) { break; } } } return(candidatePathEdges); }
/// <summary> /// Change the swept profile edges from EdgeArray type to line list /// </summary> /// <param name="edges">The swept profile edges</param> /// <returns>The line list which stores the swept profile edges</returns> private List <Line> ChangeEdgeToLine(EdgeArray edges) { // create the line list instance. List <Line> edgeLines = new List <Line>(); // get each edge from swept profile, // and change the geometry information in line list foreach (Edge edge in edges) { //get the two points of each edge List <XYZ> points = edge.Tessellate() as List <XYZ>; Autodesk.Revit.DB.XYZ first = Transform(points[0]); Autodesk.Revit.DB.XYZ second = Transform(points[1]); // create new line and add them into line list edgeLines.Add(Line.CreateBound(first, second)); } return(edgeLines); }
/// <summary> /// Get an edge from the form by its endpoints /// </summary> /// <param name="form">The form contains the edge</param> /// <param name="startPoint">Start point of the edge</param> /// <param name="endPoint">End point of the edge</param> /// <returns>The edge found</returns> private Edge GetEdgeByEndPoints(Form form, Autodesk.Revit.DB.XYZ startPoint, Autodesk.Revit.DB.XYZ endPoint) { Edge edge = null; // Get all edges of the form EdgeArray edges = null; Options geoOptions = m_revitApp.Create.NewGeometryOptions(); geoOptions.ComputeReferences = true; Autodesk.Revit.DB.GeometryElement geoElement = form.get_Geometry(geoOptions); //foreach (GeometryObject geoObject in geoElement.Objects) IEnumerator <GeometryObject> Objects = geoElement.GetEnumerator(); while (Objects.MoveNext()) { GeometryObject geoObject = Objects.Current; Solid solid = geoObject as Solid; if (null == solid) { continue; } edges = solid.Edges; } // Traverse the edges and look for the edge with the right endpoints foreach (Edge ed in edges) { Autodesk.Revit.DB.XYZ rpPos1 = ed.Evaluate(0); Autodesk.Revit.DB.XYZ rpPos2 = ed.Evaluate(1); if ((startPoint.IsAlmostEqualTo(rpPos1) && endPoint.IsAlmostEqualTo(rpPos2)) || (startPoint.IsAlmostEqualTo(rpPos2) && endPoint.IsAlmostEqualTo(rpPos1))) { edge = ed; break; } } return(edge); }
/// <summary> /// 获取边的所有点 /// </summary> /// <param name="edgeArray"></param> /// <returns></returns> public static List <XYZ> GetPoints(EdgeArray edgeArray, BeamAlignToFloorModel model) { List <XYZ> points = new List <XYZ>(); foreach (Edge edge in edgeArray) { var tPoints = edge.Tessellate(); //链接顺序 1S-1E,2E-1S,3E-2S,4E-3S for (int i = tPoints.Count() - 1; i >= 0; i--) { var point = tPoints[i]; if (points.FirstOrDefault(c => c.IsAlmostEqualTo(point, ConstraintsOfBeamAlignToFloor.XYZTolerance)) == null) { points.Insert(0, point + model.Offset); } } //if (tPoints.Count == 2) //{ // var point = tPoints[0]; // if (points.FirstOrDefault(c => c.IsAlmostEqualTo(point, ConstraintsOfBeamAlignToFloor.XYZTolerance)) == null) // { // points.Add(point + model.Offset); // } // else // { // point = tPoints[1]; // if (points.FirstOrDefault(c => c.IsAlmostEqualTo(point, ConstraintsOfBeamAlignToFloor.XYZTolerance)) == null) // points.Add(point + model.Offset); // } //} //else //{ // foreach (var point in tPoints) // if (points.FirstOrDefault(c => c.IsAlmostEqualTo(point, ConstraintsOfBeamAlignToFloor.XYZTolerance)) == null) // points.Add(point + model.Offset); //} } return(points); }
public static EdgeArray PlanarFaceOuterLoop(Face F) { PlanarFace face = F as PlanarFace; if (face == null) { return(null); } Transform T = Transform.Identity; T.BasisZ = face.FaceNormal; T.BasisX = face.XVector; T.BasisY = face.YVector; T.Origin = face.Origin; Transform Tinv = T.Inverse; EdgeArray eaMin = null; EdgeArrayArray loops = F.EdgeLoops; double uMin = double.MaxValue; foreach (EdgeArray a in loops) { double uMin2 = double.MaxValue; foreach (Edge e in a) { double min = MinX(e.AsCurve(), Tinv); if (min < uMin2) { uMin2 = min; } } if (uMin2 < uMin) { uMin = uMin2; eaMin = a; } } return(eaMin); }
/// <summary> /// Implement this method as an external command for Revit. /// </summary> /// <param name="commandData">An object that is passed to the external application /// which contains data related to the command, /// such as the application object and active view.</param> /// <param name="message">A message that can be set by the external application /// which will be displayed if a failure or cancellation is returned by /// the external command.</param> /// <param name="elements">A set of elements to which the external application /// can add elements that are to be highlighted in case of failure or cancellation.</param> /// <returns>Return the status of the external command. /// A result of Succeeded means that the API external method functioned as expected. /// Cancelled can be used to signify that the user cancelled the external operation /// at some point. Failure should be returned if the application is unable to proceed with /// the operation.</returns> public Autodesk.Revit.UI.Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements) { m_app = commandData.Application.Application; m_doc = commandData.Application.ActiveUIDocument.Document; // step 1: get all the divided surfaces in the Revit document List <DividedSurface> dsList = GetElements <DividedSurface>(); foreach (DividedSurface ds in dsList) { // step 2: get the panel instances from the divided surface List <FamilyInstance> fiList = GetFamilyInstances(ds); foreach (FamilyInstance inst in fiList) { // step 3: compute the length and angle and set them to the parameters InstParameters instParams = GetParams(inst); EdgeArray edges = GetEdges(inst); SetParams(edges, instParams); } } return(Autodesk.Revit.UI.Result.Succeeded); }
/// <summary> /// Get edges of element's profile /// </summary> /// <param name="elem">Selected element</param> public List <List <Edge> > GetFaces(Autodesk.Revit.DB.Element elem) { List <List <Edge> > faceEdges = new List <List <Edge> >(); Options options = m_appCreator.NewGeometryOptions(); options.DetailLevel = ViewDetailLevel.Medium; options.ComputeReferences = true; Autodesk.Revit.DB.GeometryElement geoElem = elem.get_Geometry(options); //GeometryObjectArray gObjects = geoElem.Objects; IEnumerator <GeometryObject> Objects = geoElem.GetEnumerator(); //foreach (GeometryObject geo in gObjects) while (Objects.MoveNext()) { GeometryObject geo = Objects.Current; Solid solid = geo as Solid; if (solid != null) { EdgeArray edges = solid.Edges; FaceArray faces = solid.Faces; foreach (Face face in faces) { EdgeArrayArray edgeArrarr = face.EdgeLoops; foreach (EdgeArray edgeArr in edgeArrarr) { List <Edge> edgesList = new List <Edge>(); foreach (Edge edge in edgeArr) { edgesList.Add(edge); } faceEdges.Add(edgesList); } } } } return(faceEdges); }
/// <summary> /// Return the vertices from a face edge loop /// </summary> static List <XYZ> GetEdgeLoopVertices( EdgeArray loop) { if (1 > loop.Size) { throw new ArgumentException( "empty top face loop"); } List <XYZ> vertices = new List <XYZ>(); XYZ p, q = XYZ.Zero; bool first = true; int i, n; foreach (Edge e in loop) { IList <XYZ> points = e.Tessellate(); p = points[0]; if (!first) { Debug.Assert(p.IsAlmostEqualTo(q), "expected subsequent start point" + " to equal previous end point"); } n = points.Count; q = points[n - 1]; for (i = 0; i < n - 1; ++i) { vertices.Add(points[i]); } } Debug.Assert(q.IsAlmostEqualTo(vertices[0]), "expected last end point to equal" + " first start point"); return(vertices); }
/// <summary> /// Get all points of the Slab /// </summary> /// <returns>points array stores all the points on slab</returns> public EdgeArray GetFloorEdges() { EdgeArray edges = new EdgeArray(); Options options = m_commandData.Application.Application.Create.NewGeometryOptions(); options.DetailLevel = ViewDetailLevel.Medium; //make sure references to geometric objects are computed. options.ComputeReferences = true; Autodesk.Revit.DB.GeometryElement geoElem = m_floor.get_Geometry(options); //GeometryObjectArray gObjects = geoElem.Objects; IEnumerator <GeometryObject> Objects = geoElem.GetEnumerator(); //get all the edges in the Geometry object //foreach (GeometryObject geo in gObjects) while (Objects.MoveNext()) { GeometryObject geo = Objects.Current; Solid solid = geo as Solid; if (solid != null) { FaceArray faces = solid.Faces; foreach (Face face in faces) { EdgeArrayArray edgeArrarr = face.EdgeLoops; foreach (EdgeArray edgeArr in edgeArrarr) { foreach (Edge edge in edgeArr) { edges.Append(edge); } } } } } return(edges); }
/// <summary> /// Given an array of edges, weeds out any edges /// not present at the given offset /// </summary> /// <param name="edgeArray">the array of edges </param> /// <param name="normal">normal to the desired plane</param> /// <param name="offset">offset from the plane</param> /// <returns>edges on a plane at given offset</returns> public static EdgeArray GetEdgesOnPlaneAtOffset(EdgeArray edgeArray, XYZ normal, double offset) { EdgeArray edgesAtOffset = new EdgeArray(); edgeArray = GetEdgesOnPlane(edgeArray, normal); for (int i = 0; i < edgeArray.Size; i++) { IList<XYZ> xyzArray = edgeArray.get_Item(i).Tessellate(); if (normal.Equals(GeomUtils.kXAxis)) { if ((xyzArray[0].X == offset)) { edgesAtOffset.Append(edgeArray.get_Item(i)); } } if (normal.Equals(GeomUtils.kYAxis)) { if (xyzArray[0].Y == offset) { edgesAtOffset.Append(edgeArray.get_Item(i)); } } if (normal.Equals(GeomUtils.kZAxis)) { if (xyzArray[0].Z == offset) { edgesAtOffset.Append(edgeArray.get_Item(i)); } } } return edgesAtOffset; }
public static List <XYZ> GetPolygon(this EdgeArray ea) { int n = ea.Size; List <XYZ> polygon = new List <XYZ>(n); foreach (Edge e in ea) { IList <XYZ> pts = e.Tessellate(); n = polygon.Count; if (0 < n) { /* * Debug.Assert(pts[0] * .IsAlmostEqualTo(polygon[n - 1]), * "expected last edge end point to " + "equal next edge start point"); */ polygon.RemoveAt(n - 1); } polygon.AddRange(pts); } n = polygon.Count; /* * Debug.Assert(polygon[0] * .IsAlmostEqualTo(polygon[n - 1]), * "expected first edge start point to " + "equal last edge end point"); */ polygon.RemoveAt(n - 1); return(polygon); }
public BoruvkaSpanningTree(AdjancenceVector <T> graph) { this.graph = graph; data = null; }
/// <summary> /// Gets existing nodes. /// </summary> /// <returns></returns> public IEnumerable <Edge <U> > GetEdges() { return(EdgeArray.Where(edge => edge != null)); }
/// <summary> /// Group the extra faces in the extrusion by element id, representing clippings, recesses, and openings. /// </summary> /// <param name="elem">The element generating the base extrusion.</param> /// <param name="analyzer">The extrusion analyzer.</param> /// <returns>A list of connected faces for each element id that cuts the extrusion</returns> public static IDictionary <ElementId, ICollection <ICollection <Face> > > GetCuttingElementFaces(Element elem, ExtrusionAnalyzer analyzer) { IDictionary <ElementId, HashSet <Face> > cuttingElementFaces = new Dictionary <ElementId, HashSet <Face> >(); IDictionary <Face, ExtrusionAnalyzerFaceAlignment> allFaces = analyzer.CalculateFaceAlignment(); foreach (KeyValuePair <Face, ExtrusionAnalyzerFaceAlignment> currFace in allFaces) { if (currFace.Value == ExtrusionAnalyzerFaceAlignment.FullyAligned) { continue; } EdgeArrayArray faceEdges = currFace.Key.EdgeLoops; int numBoundaries = faceEdges.Size; if (numBoundaries == 0) { continue; } if (numBoundaries > 1) { throw new Exception("Can't handle faces with interior boundaries."); } ICollection <ElementId> generatingElementIds = elem.GetGeneratingElementIds(currFace.Key); foreach (ElementId generatingElementId in generatingElementIds) { HashSet <Face> elementFaces; if (cuttingElementFaces.ContainsKey(generatingElementId)) { elementFaces = cuttingElementFaces[generatingElementId]; } else { elementFaces = new HashSet <Face>(); cuttingElementFaces[generatingElementId] = elementFaces; } elementFaces.Add(currFace.Key); } } IDictionary <ElementId, ICollection <ICollection <Face> > > cuttingElementFaceCollections = new Dictionary <ElementId, ICollection <ICollection <Face> > >(); foreach (KeyValuePair <ElementId, HashSet <Face> > cuttingElementFaceCollection in cuttingElementFaces) { ICollection <ICollection <Face> > faceCollections = new List <ICollection <Face> >(); // Split into separate collections based on connectivity. while (cuttingElementFaceCollection.Value.Count > 0) { IList <Face> currCollection = new List <Face>(); IEnumerator <Face> cuttingElementFaceCollectionEnumerator = cuttingElementFaceCollection.Value.GetEnumerator(); cuttingElementFaceCollectionEnumerator.MoveNext(); Face currFace = cuttingElementFaceCollectionEnumerator.Current; currCollection.Add(currFace); cuttingElementFaceCollection.Value.Remove(currFace); IList <Face> facesToProcess = new List <Face>(); facesToProcess.Add(currFace); if (cuttingElementFaceCollection.Value.Count > 0) { while (facesToProcess.Count > 0) { EdgeArray faceOuterBoundary = facesToProcess[0].EdgeLoops.get_Item(0); foreach (Edge edge in faceOuterBoundary) { Face adjoiningFace = edge.get_Face(1); if (adjoiningFace.Equals(currFace)) { adjoiningFace = edge.get_Face(0); } if (cuttingElementFaceCollection.Value.Contains(adjoiningFace)) { currCollection.Add(adjoiningFace); cuttingElementFaceCollection.Value.Remove(adjoiningFace); facesToProcess.Add(adjoiningFace); } } facesToProcess.Remove(facesToProcess[0]); } } faceCollections.Add(currCollection); } cuttingElementFaceCollections[cuttingElementFaceCollection.Key] = faceCollections; } return(cuttingElementFaceCollections); }
Transform.CreateTranslation(_offset); // 2014 #endif // CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES 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; Options opt = app.Create.NewGeometryOptions(); XyzEqualityComparer comparer = new XyzEqualityComparer(1e-6); #if CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES Creator creator = new Creator(doc); Transaction t = new Transaction(doc); t.Start("Create model curve copies of top face edges"); #endif // CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES IList <Face> topFaces = new List <Face>(); int n; int nWalls = 0; //foreach( Element e in uidoc.Selection.Elements ) // 2014 foreach (ElementId id in uidoc.Selection.GetElementIds()) // 2015 { Element e = doc.GetElement(id); Wall wall = e as Wall; if (null == wall) { Debug.Print("Skipped " + Util.ElementDescription(e)); continue; } // Get the side faces IList <Reference> sideFaces = HostObjectUtils.GetSideFaces(wall, ShellLayerType.Exterior); // Access the first side face Element e2 = doc.GetElement(sideFaces[0]); Debug.Assert(e2.Id.Equals(e.Id), "expected side face element to be the wall itself"); Face face = e2.GetGeometryObjectFromReference( sideFaces[0]) as Face; if (null == face) { Debug.Print("No side face found for " + Util.ElementDescription(e)); continue; } // When there are opening such as doors or // windows in the wall, we need to find the // outer loop. // For one possible approach to extract the // outermost loop, please refer to // http://thebuildingcoder.typepad.com/blog/2008/12/2d-polygon-areas-and-outer-loop.html // Determine the outer loop of the side face // by finding the polygon with the largest area XYZ normal; double area, dist, maxArea = 0; EdgeArray outerLoop = null; foreach (EdgeArray ea in face.EdgeLoops) { if (CmdWallProfileArea.GetPolygonPlane( ea.GetPolygon(), out normal, out dist, out area) && Math.Abs(area) > Math.Abs(maxArea)) { maxArea = area; outerLoop = ea; } } n = 0; #if GET_FACES_FROM_OUTER_LOOP // With the outermost loop, calculate the top faces foreach (Edge edge in outerLoop) { // For each edge, get the neighbouring // face and check its normal for (int i = 0; i < 2; ++i) { PlanarFace pf = edge.get_Face(i) as PlanarFace; if (null == pf) { Debug.Print("Skipped non-planar face on " + Util.ElementDescription(e)); continue; } if (Util.PointsUpwards(pf.Normal, 0.9)) { if (topFaces.Contains(pf)) { Debug.Print("Duplicate face on " + Util.ElementDescription(e)); } else { topFaces.Add(pf); ++n; } } } } #endif // GET_FACES_FROM_OUTER_LOOP List <XYZ> sideVertices = outerLoop.GetPolygon(); // Go over all the faces of the wall and // determine which ones fulfill the following // two criteria: (i) planar face pointing // upwards, and (ii) neighbour of the side // face outer loop. Solid solid = wall.get_Geometry(opt) .OfType <Solid>() .First <Solid>(sol => null != sol); foreach (Face f in solid.Faces) { if (IsTopFace(f)) { IList <XYZ> faceVertices = f.Triangulate().Vertices; //if( sideVertices.Exists( v // => faceVertices.Contains<XYZ>( v, comparer ) ) ) //{ // topFaces.Add( f ); // ++n; //} foreach (XYZ v in faceVertices) { if (sideVertices.Contains <XYZ>( v, comparer)) { topFaces.Add(f); ++n; #if CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES // Display face for debugging purposes foreach (EdgeArray ea in f.EdgeLoops) { IEnumerable <Curve> curves = ea.Cast <Edge>() .Select <Edge, Curve>( x => x.AsCurve()); foreach (Curve curve in curves) { //creator.CreateModelCurve( curve.get_Transformed( _t ) ); // 2013 creator.CreateModelCurve(curve.CreateTransformed(_t)); // 2014 } } #endif // CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES break; } } } } Debug.Print(string.Format( "{0} top face{1} found on {2} ({3})", n, Util.PluralSuffix(n), Util.ElementDescription(e)), nWalls++); } #if CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES t.Commit(); #endif // CREATE_MODEL_CURVES_FOR_TOP_FACE_EDGES string s = string.Format( "{0} wall{1} successfully processed", nWalls, Util.PluralSuffix(nWalls)); n = topFaces.Count; TaskDialog.Show("Wall Top Faces", string.Format( "{0} with {1} top face{2}.", s, n, Util.PluralSuffix(n))); return(Result.Succeeded); }
/// <summary> /// check whether the faces of the mass are one-one parallel /// </summary> /// <param name="faces"> /// the 6 faces of the mass /// </param> /// <returns> /// if the 6 faces are one-one parallel, return true; otherwise false /// </returns> private bool IsFacesParallel(FaceArray faces) { // step1: get the normals of the 6 faces List <Utility.Vector4> normals = new List <Utility.Vector4>(); foreach (Face face in faces) { EdgeArrayArray edgeArrayArray = face.EdgeLoops; EdgeArray edges = edgeArrayArray.get_Item(0); if (null == edges || 2 > edges.Size) { return(false); } // we use the cross product of 2 non-parallel vectors as the normal for (int i = 0; i < edges.Size - 1; i++) { Edge edgeA = edges.get_Item(i); Edge edgeB = edges.get_Item(i + 1); // if edgeA & edgeB are parallel, can't compute the cross product bool isLinesParallel = IsLinesParallel(edgeA, edgeB); if (true == isLinesParallel) { continue; } Utility.Vector4 vec4 = ComputeCrossProduct(edgeA, edgeB); normals.Add(vec4); break; } } // step 2: the 6 normals should be one-one parallel pairs if (null == normals || 6 != normals.Count) { return(false); } bool[] matchedList = new bool[6]; for (int i = 0; i < matchedList.Length; i++) { matchedList[i] = false; } // check whether the normal has another matched parallel normal for (int i = 0; i < matchedList.Length; i++) { if (true == matchedList[i]) { continue; } Utility.Vector4 vec4A = normals[i]; for (int j = 0; j < matchedList.Length; j++) { if (j == i || true == matchedList[j]) { continue; } Utility.Vector4 vec4B = normals[j]; if (true == IsLinesParallel(vec4A, vec4B)) { matchedList[i] = true; matchedList[j] = true; break; } } } // step 3: check each of the 6 normals has matched parallel normal for (int i = 0; i < matchedList.Length; i++) { if (false == matchedList[i]) { return(false); } } // all the normals have matched parallel normals return(true); }
private CurveArray GetCurveArrayFromEdgeArary(EdgeArray edgeArray) { CurveArray curveArray = new CurveArray(); foreach (Edge edge in edgeArray) { var edgeCurve = edge.AsCurve(); curveArray.Append(edgeCurve); } return curveArray; }
/// <summary> /// This method parses geometry information of given Corbel to construct the CorbelFrame. /// </summary> /// <param name="corbel">Given corbel family instance to parse</param> /// <returns>CorbelFrame object</returns> public static CorbelFrame ParseCorbelGeometry(FamilyInstance corbel) { // Get Corbel Host information. Element corbelHost = corbel.Host; Reference corbelHostFace = corbel.HostFace; PlanarFace hostPlane = corbelHost.GetGeometryObjectFromReference(corbelHostFace) as PlanarFace; XYZ hostNormal = GetNormalOutside(hostPlane); // Extract the faces in Corbel parallel with Corbel host face. Solid corbelSolid = GetElementSolid(corbel); PlanarFace corbelTopFace = null; PlanarFace corbelBottomFace = null; foreach (Face face in corbelSolid.Faces) { PlanarFace planarFace = face as PlanarFace; XYZ normal = GetNormalOutside(planarFace); if (normal.IsAlmostEqualTo(hostNormal)) { corbelTopFace = planarFace; } else if (normal.IsAlmostEqualTo(-hostNormal)) { corbelBottomFace = planarFace; } } // Extract the faces in Corbel Host parallel with Corbel host face. Solid hostSolid = GetElementSolid(corbelHost); PlanarFace hostTopFace = null; PlanarFace hostBottomFace = hostPlane; foreach (Face face in hostSolid.Faces) { PlanarFace planarFace = face as PlanarFace; XYZ normal = GetNormalOutside(planarFace); if (normal.IsAlmostEqualTo(-hostNormal)) { hostTopFace = planarFace; } } // Parse the side faces to find out the Trapezoid face. Edge topEdge = null; Edge leftEdge = null; Edge bottomEdge = null; Edge rightEdge = null; PlanarFace trapezoidFace = null; int foundEdgeIndex = -1; bool foundTrapezoid = false; EdgeArray bottomEdges = corbelBottomFace.EdgeLoops.get_Item(0); foreach (Edge edge in bottomEdges) { bottomEdge = edge; foundEdgeIndex++; foundTrapezoid = IsTrapezoid(hostNormal, corbelBottomFace, bottomEdge, out trapezoidFace, out topEdge, out leftEdge, out rightEdge); if (foundTrapezoid) { break; } } // Check to see if the Trapezoid faces was found. if (!foundTrapezoid) { // Throw if no any trapezoid face in corbel. throw new Exception("Didn't find the trapezoid face in corbel [Id:" + corbel.Id + "]."); } Edge depthEdge = bottomEdges.get_Item((foundEdgeIndex + 1) % bottomEdges.Size); double hostDepth = GetDistance(hostTopFace, hostBottomFace); // Compute the host face cover distance. RebarHostData corbelHostData = RebarHostData.GetRebarHostData(corbelHost); // Get CoverType of the given host face RebarCoverType coverType = corbelHostData.GetCoverType(hostTopFace.Reference); // if the host face don't have a CoverType, then try to get the common CoverType. if (coverType == null) { coverType = corbelHostData.GetCommonCoverType(); } // Get the Cover Distance double coverDistance = coverType.CoverDistance; // Construct the CorbelFrame from the given parsed trapezoid information. return(ConstructCorbelFrame( corbel, depthEdge, leftEdge, bottomEdge, rightEdge, topEdge, corbel.Document, trapezoidFace, hostDepth, coverDistance)); }
/// <summary> /// Get all points of the Slab /// </summary> /// <returns>points array stores all the points on slab</returns> public EdgeArray GetFloorEdges() { EdgeArray edges = new EdgeArray(); Options options = m_commandData.Application.Application.Create.NewGeometryOptions(); options.DetailLevel = DetailLevels.Medium; //make sure references to geometric objects are computed. options.ComputeReferences = true; Autodesk.Revit.DB.GeometryElement geoElem = m_floor.get_Geometry(options); GeometryObjectArray gObjects = geoElem.Objects; //get all the edges in the Geometry object foreach (GeometryObject geo in gObjects) { Solid solid = geo as Solid; if (solid != null) { FaceArray faces = solid.Faces; foreach (Face face in faces) { EdgeArrayArray edgeArrarr = face.EdgeLoops; foreach (EdgeArray edgeArr in edgeArrarr) { foreach (Edge edge in edgeArr) { edges.Append(edge); } } } } } return edges; }
private void Stream(ArrayList data, EdgeArray edgeArray) { data.Add(new Snoop.Data.ClassSeparator(typeof(EdgeArray))); IEnumerator iter = edgeArray.GetEnumerator(); int i = 0; while (iter.MoveNext()) { data.Add(new Snoop.Data.Object(string.Format("Edge {0:d}", i++), iter.Current)); } }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; UIDocument uidoc = app.ActiveUIDocument; Document doc = uidoc.Document; // Retrieve selected floors, or all floors, if nothing is selected: List <Element> floors = new List <Element>(); if (!Util.GetSelectedElementsOrAll( floors, uidoc, typeof(Floor))) { Selection sel = uidoc.Selection; message = (0 < sel.GetElementIds().Count) ? "Please select some floor elements." : "No floor elements found."; return(Result.Failed); } // Determine top face of each selected floor: int nNullFaces = 0; List <Face> topFaces = new List <Face>(); Options opt = app.Application.Create.NewGeometryOptions(); foreach (Floor floor in floors) { GeometryElement geo = floor.get_Geometry(opt); //GeometryObjectArray objects = geo.Objects; // 2012 foreach (GeometryObject obj in geo) { Solid solid = obj as Solid; if (solid != null) { PlanarFace f = GetTopFace(solid); if (null == f) { Debug.WriteLine( Util.ElementDescription(floor) + " has no top face."); ++nNullFaces; } topFaces.Add(f); } } } using (Transaction t = new Transaction(doc)) { t.Start("Create Model Lines and Floor"); // Create new floors from the top faces found. // Before creating the new floor, we would obviously // apply whatever modifications are required to the // new floor profile: Autodesk.Revit.Creation.Application creApp = app.Application.Create; Autodesk.Revit.Creation.Document creDoc = doc.Create; int i = 0; int n = topFaces.Count - nNullFaces; Debug.Print( "{0} top face{1} found.", n, Util.PluralSuffix(n)); foreach (Face f in topFaces) { Floor floor = floors[i++] as Floor; if (null != f) { EdgeArrayArray eaa = f.EdgeLoops; CurveArray profile; #region Attempt to include inner loops #if ATTEMPT_TO_INCLUDE_INNER_LOOPS bool use_original_loops = true; if (use_original_loops) { profile = Convert(eaa); } else #endif // ATTEMPT_TO_INCLUDE_INNER_LOOPS #endregion // Attempt to include inner loops { profile = new CurveArray(); // Only use first edge array, // the outer boundary loop, // skip the further items // representing holes: EdgeArray ea = eaa.get_Item(0); foreach (Edge e in ea) { IList <XYZ> pts = e.Tessellate(); int m = pts.Count; XYZ p = pts[0]; XYZ q = pts[m - 1]; Line line = Line.CreateBound(p, q); profile.Append(line); } } //Level level = floor.Level; // 2013 Level level = doc.GetElement(floor.LevelId) as Level; // 2014 // In this case we have a valid floor type given. // In general, not that NewFloor will only accept // floor types whose IsFoundationSlab predicate // is false. floor = creDoc.NewFloor(profile, floor.FloorType, level, true); XYZ v = new XYZ(5, 5, 0); //doc.Move( floor, v ); // 2011 ElementTransformUtils.MoveElement(doc, floor.Id, v); // 2012 } } t.Commit(); } return(Result.Succeeded); }
/// <summary> /// get a list of points representing an edge array /// found on the building coder: /// http://thebuildingcoder.typepad.com/blog/2011/07/ /// </summary> /// <param name="ea"></param> /// <returns></returns> private static List<Autodesk.DesignScript.Geometry.Point> GetPolygon(EdgeArray ea) { int n = ea.Size; List<XYZ> polygon = new List<XYZ>(n); foreach (Autodesk.Revit.DB.Edge e in ea) { IList<XYZ> pts = e.Tessellate(); n = polygon.Count; if (0 < n) { polygon.RemoveAt(n - 1); } polygon.AddRange(pts); } n = polygon.Count; polygon.RemoveAt(n - 1); //return polygon; //convert polygon to designscript points and return List<Autodesk.DesignScript.Geometry.Point> outPoitns = new List<Autodesk.DesignScript.Geometry.Point>(); foreach (var p in polygon) { outPoitns.Add(Autodesk.DesignScript.Geometry.Point.ByCoordinates(p.X, p.Y, p.Z)); } return outPoitns; }
/// <summary> /// Given an edge Array converts it to a curveArray /// </summary> /// <param name="edgeArray">edgeArray to convert</param> /// <param name="curveArray">curveArray to fill</param> /// <returns>a curveArray</returns> public static CurveArray ToCurveArray(EdgeArray edgeArray, CurveArray curveArray) { EdgeArrayIterator edgeArrayIter = edgeArray.ForwardIterator(); while (edgeArrayIter.MoveNext()) { Edge edge = edgeArrayIter.Current as Edge; XYZ startPt = edge.Tessellate()[0]; XYZ endPt = edge.Tessellate()[1]; Line curve = Line.CreateBound(startPt, endPt); curveArray.Append(curve); } return curveArray; }
public OutLine(EdgeArray edgeArray, BeamAlignToFloorModel model) { Init(edgeArray, model); }
Stream(EdgeArray edgeArray) { foreach (Edge edge in edgeArray) { Stream(edge); } }
CollectEvent(object sender, CollectorEventArgs e) { // cast the sender object to the SnoopCollector we are expecting Collector snoopCollector = sender as Collector; if (snoopCollector == null) { Debug.Assert(false); // why did someone else send us the message? return; } // see if it is a type we are responsible for Location loc = e.ObjToSnoop as Location; if (loc != null) { Stream(snoopCollector.Data(), loc); return; } GeometryObject geomObj = e.ObjToSnoop as GeometryObject; if (geomObj != null) { Stream(snoopCollector.Data(), geomObj); return; } Options opts = e.ObjToSnoop as Options; if (opts != null) { Stream(snoopCollector.Data(), opts); return; } Transform trf = e.ObjToSnoop as Transform; if (trf != null) { Stream(snoopCollector.Data(), trf); return; } BoundingBoxXYZ bndBoxXyz = e.ObjToSnoop as BoundingBoxXYZ; if (bndBoxXyz != null) { Stream(snoopCollector.Data(), bndBoxXyz); return; } MeshTriangle meshTri = e.ObjToSnoop as MeshTriangle; if (meshTri != null) { Stream(snoopCollector.Data(), meshTri); return; } Reference reference = e.ObjToSnoop as Reference; if (reference != null) { Stream(snoopCollector.Data(), reference); return; } EdgeArray edgeArray = e.ObjToSnoop as EdgeArray; // NOTE: this is needed because EdgeArrayArray will display enumerable Snoop items if (edgeArray != null) { Stream(snoopCollector.Data(), edgeArray); return; } CurveArray curveArray = e.ObjToSnoop as CurveArray; // NOTE: this is needed because CurveArrayArray will display enumerable Snoop items if (curveArray != null) { Stream(snoopCollector.Data(), curveArray); return; } Plane plane = e.ObjToSnoop as Plane; if (plane != null) { Stream(snoopCollector.Data(), plane); return; } IntersectionResult intrResult = e.ObjToSnoop as IntersectionResult; if (intrResult != null) { Stream(snoopCollector.Data(), intrResult); return; } BoundingBoxUV bboxUV = e.ObjToSnoop as BoundingBoxUV; if (bboxUV != null) { Stream(snoopCollector.Data(), bboxUV); return; } SweepProfile sweepProf = e.ObjToSnoop as SweepProfile; if (sweepProf != null) { Stream(snoopCollector.Data(), sweepProf); return; } DimensionSegment dimSeg = e.ObjToSnoop as DimensionSegment; if (dimSeg != null) { Stream(snoopCollector.Data(), dimSeg); return; } UV uv = e.ObjToSnoop as UV; if (uv != null) { Stream(snoopCollector.Data(), uv); return; } }
private static CurveLoop GetFaceBoundary(Face face, EdgeArray faceBoundary, XYZ baseLoopOffset, bool polygonalOnly, out FaceBoundaryType faceBoundaryType) { faceBoundaryType = FaceBoundaryType.Polygonal; CurveLoop currLoop = new CurveLoop(); foreach (Edge faceBoundaryEdge in faceBoundary) { Curve edgeCurve = faceBoundaryEdge.AsCurveFollowingFace(face); Curve offsetCurve = (baseLoopOffset != null) ? MoveCurve(edgeCurve, baseLoopOffset) : edgeCurve; if (!(offsetCurve is Line)) { if (polygonalOnly) { IList<XYZ> tessPts = offsetCurve.Tessellate(); int numTessPts = tessPts.Count; for (int ii = 0; ii < numTessPts - 1; ii++) { Line line = Line.get_Bound(tessPts[ii], tessPts[ii + 1]); currLoop.Append(line); } } else { currLoop.Append(offsetCurve); } if (offsetCurve is Arc) faceBoundaryType = FaceBoundaryType.LinesAndArcs; else faceBoundaryType = FaceBoundaryType.Complex; } else currLoop.Append(offsetCurve); } return currLoop; }
public static PlanarFace GetTopFace(IList <PlanarFace> faces, XYZ direction, Transform transform) { PlanarFace result = null; double num = double.MinValue; XYZ point = new XYZ(); double num2 = double.MinValue; foreach (PlanarFace planarFace in faces) { foreach (object obj in planarFace.EdgeLoops) { EdgeArray edgeArray = (EdgeArray)obj; foreach (object obj2 in edgeArray) { Edge edge = (Edge)obj2; Curve curve = edge.AsCurve(); bool flag = curve == null; if (!flag) { XYZ xyz = transform.OfPoint(curve.GetEndPoint(0)); XYZ xyz2 = transform.OfPoint(curve.GetEndPoint(1)); double num3 = xyz.DotProduct(direction); double num4 = xyz2.DotProduct(direction); bool flag2 = num3 > num2; if (flag2) { point = xyz; num2 = num3; } bool flag3 = num4 > num2; if (flag3) { point = xyz2; num2 = num4; } } } } } List <PlanarFace> list = new List <PlanarFace>(); foreach (PlanarFace planarFace2 in faces) { double num5 = Facelibry.PointToFace(point, planarFace2, transform); bool flag4 = num5 < 0.001; if (flag4) { list.Add(planarFace2); } } foreach (PlanarFace planarFace3 in list) { XYZ xyz3 = transform.OfVector(planarFace3.FaceNormal); double num6 = xyz3.DotProduct(direction); bool flag5 = num6 > num; if (flag5) { result = planarFace3; num = num6; } } return(result); }
private static bool IsCounterClocwize(Face face, EdgeArray edgeArray) { var curveLoop = CurveLoop.Create(edgeArray.Cast <Edge>().Select(x => x.AsCurve()).ToList()); return(curveLoop.IsCounterclockwise(face.ComputeNormal(new UV()))); }
private static void ComputerGeometryLoops(EdgeArray ea, out List<XYZ> loop, out XYZ loopNormal, out double loopArea) { // Create a list of points of the loop loop = new List<XYZ>(); foreach (Edge e in ea) { IList<XYZ> edgePoints = e.Tessellate(); // Avoid duplicated points (generic approach) foreach (XYZ edgePoint in edgePoints) if (!ListContains(loop, edgePoint)) loop.Add(edgePoint); } // Calculate the area and length of the loop // // More information at // http://thebuildingcoder.typepad.com/ // blog/2008/12/3d-polygon-areas.html double loopLength; GetPolygonPlane(loop, out loopNormal, out loopLength, out loopArea); }
/// <summary> /// Attempts to create a clipping, recess, or opening from a collection of faces. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="cuttingElement">The cutting element. This will help determine whether to use a clipping or opening in boundary cases.</param> /// <param name="extrusionBasePlane">The plane of the extrusion base.</param> /// <param name="extrusionDirection">The extrusion direction.</param> /// <param name="faces">The collection of faces.</param> /// <param name="range">The valid range of the extrusion.</param> /// <param name="origBodyRepHnd">The original body representation.</param> /// <returns>The new body representation. If the clipping completely clips the extrusion, this will be null. Otherwise, this /// will be the clipped representation if a clipping was done, or the original representation if not.</returns> public static IFCAnyHandle ProcessFaceCollection(ExporterIFC exporterIFC, Element cuttingElement, Plane extrusionBasePlane, XYZ extrusionDirection, ICollection <Face> faces, IFCRange range, IFCAnyHandle origBodyRepHnd) { if (IFCAnyHandleUtil.IsNullOrHasNoValue(origBodyRepHnd)) { return(null); } bool polygonalOnly = ExporterCacheManager.ExportOptionsCache.ExportAs2x2; IList <CurveLoop> outerCurveLoops = new List <CurveLoop>(); IList <Plane> outerCurveLoopPlanes = new List <Plane>(); IList <bool> boundaryIsPolygonal = new List <bool>(); bool allPlanes = true; UV faceOriginUV = new UV(0, 0); foreach (Face face in faces) { FaceBoundaryType faceBoundaryType; CurveLoop curveLoop = GetOuterFaceBoundary(face, null, polygonalOnly, out faceBoundaryType); outerCurveLoops.Add(curveLoop); boundaryIsPolygonal.Add(faceBoundaryType == FaceBoundaryType.Polygonal); if (face is PlanarFace) { PlanarFace planarFace = face as PlanarFace; XYZ faceOrigin = planarFace.Origin; XYZ faceNormal = planarFace.ComputeNormal(faceOriginUV); Plane plane = new Plane(faceNormal, faceOrigin); outerCurveLoopPlanes.Add(plane); if (!curveLoop.IsCounterclockwise(faceNormal)) { curveLoop.Flip(); } } else { outerCurveLoopPlanes.Add(null); allPlanes = false; } } if (allPlanes) { int numFaces = faces.Count; // Special case: one face is a clip plane. if (numFaces == 1) { return(ProcessClippingFace(exporterIFC, outerCurveLoops[0], outerCurveLoopPlanes[0], extrusionBasePlane, extrusionDirection, range, false, origBodyRepHnd)); } KeyValuePair <bool, bool> clipsExtrusionEnds = CollectionClipsExtrusionEnds(outerCurveLoops, extrusionDirection, range); if (clipsExtrusionEnds.Key == true || clipsExtrusionEnds.Value == true) { // Don't clip for a door, window or opening. if (CreateOpeningForCategory(cuttingElement)) { throw new Exception("Unhandled opening."); } ICollection <int> facesToSkip = new HashSet <int>(); bool clipStart = (clipsExtrusionEnds.Key == true); bool clipBoth = (clipsExtrusionEnds.Key == true && clipsExtrusionEnds.Value == true); if (!clipBoth) { for (int ii = 0; ii < numFaces; ii++) { double slant = outerCurveLoopPlanes[ii].Normal.DotProduct(extrusionDirection); if (!MathUtil.IsAlmostZero(slant)) { if (clipStart && (slant > 0.0)) { throw new Exception("Unhandled clip plane direction."); } if (!clipStart && (slant < 0.0)) { throw new Exception("Unhandled clip plane direction."); } } else { facesToSkip.Add(ii); } } } else { // If we are clipping both the start and end of the extrusion, we have to make sure all of the clipping // planes have the same a non-negative dot product relative to one another. int clipOrientation = 0; for (int ii = 0; ii < numFaces; ii++) { double slant = outerCurveLoopPlanes[ii].Normal.DotProduct(extrusionDirection); if (!MathUtil.IsAlmostZero(slant)) { if (slant > 0.0) { if (clipOrientation < 0) { throw new Exception("Unhandled clipping orientations."); } clipOrientation = 1; } else { if (clipOrientation > 0) { throw new Exception("Unhandled clipping orientations."); } clipOrientation = -1; } } else { facesToSkip.Add(ii); } } } IFCAnyHandle newBodyRepHnd = origBodyRepHnd; for (int ii = 0; ii < numFaces; ii++) { if (facesToSkip.Contains(ii)) { continue; } newBodyRepHnd = ProcessClippingFace(exporterIFC, outerCurveLoops[ii], outerCurveLoopPlanes[ii], extrusionBasePlane, extrusionDirection, range, true, newBodyRepHnd); if (newBodyRepHnd == null) { return(null); } } return(newBodyRepHnd); } } bool unhandledCases = true; if (unhandledCases) { throw new Exception("Unhandled opening or clipping."); } // We will attempt to "sew" the faces, and see what we have left over. Depending on what we have, we have an opening, recess, or clipping. IList <Edge> boundaryEdges = new List <Edge>(); foreach (Face face in faces) { EdgeArrayArray faceBoundaries = face.EdgeLoops; // We only know how to deal with the outer loop; we'll throw if we have multiple boundaries. if (faceBoundaries.Size != 1) { throw new Exception("Can't process faces with inner boundaries."); } EdgeArray faceBoundary = faceBoundaries.get_Item(0); foreach (Edge edge in faceBoundary) { if (edge.get_Face(0) == null || edge.get_Face(1) == null) { boundaryEdges.Add(edge); } } } return(origBodyRepHnd); }
/// <summary> /// Change the swept profile edges from EdgeArray type to line list /// </summary> /// <param name="edges">the swept profile edges</param> /// <returns>the line list which stores the swept profile edges</returns> private List<Line> ChangeEdgeToLine(EdgeArray edges) { // create the line list instance. List<Line> edgeLines = new List<Line>(); // get each edge from swept profile, // and changed the geometry information in line list foreach (Edge edge in edges) { //get the two points of each edge List<XYZ> points = edge.Tessellate() as List<XYZ>; Autodesk.Revit.DB.XYZ first = Transform(points[0]); Autodesk.Revit.DB.XYZ second = Transform(points[1]); // create new line and add them into line list edgeLines.Add(Line.get_Bound(first, second)); } return edgeLines; }
public virtual void Stream(EdgeArray edgeArray) { foreach (Edge edge in edgeArray) { Stream(edge); } }