GetProfile(Solid solid, double offset, Revit.ApplicationServices.Application app) { CurveArray curveArray = app.Create.NewCurveArray(); EdgeArray edgeArray = GetEdgesOnPlaneAtOffset(solid.Edges, GeomUtils.kZAxis, offset); curveArray = ToCurveArray(edgeArray, curveArray); return curveArray; }
/// <summary> /// Creates a SimpleSweptSolidAnalyzer and computes the swept solid. /// </summary> /// <param name="solid">The solid geometry.</param> /// <param name="normal">The normal of the reference plane that a path might lie on. If it is null, try to guess based on the geometry.</param> /// <returns>The analyzer.</returns> public static SimpleSweptSolidAnalyzer Create(Solid solid, XYZ normal) { if (solid == null) throw new ArgumentNullException(); ICollection<Face> faces = new List<Face>(); foreach (Face face in solid.Faces) { faces.Add(face); } return Create(faces, normal); }
/// <summary> /// Creates a SweptSolidExporter. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="element">The element.</param> /// <param name="solid">The solid.</param> /// <param name="normal">The normal of the plane that the path lies on.</param> /// <returns>The SweptSolidExporter.</returns> public static SweptSolidExporter Create(ExporterIFC exporterIFC, Element element, Solid solid, XYZ normal) { try { SweptSolidExporter sweptSolidExporter = null; SimpleSweptSolidAnalyzer sweptAnalyzer = SimpleSweptSolidAnalyzer.Create(element.Document.Application.Create, solid, normal); if (sweptAnalyzer != null) { // TODO: support openings and recess for a swept solid if (sweptAnalyzer.UnalignedFaces != null && sweptAnalyzer.UnalignedFaces.Count > 0) return null; IList<GeometryUtil.FaceBoundaryType> faceBoundaryTypes; IList<CurveLoop> faceBoundaries = GeometryUtil.GetFaceBoundaries(sweptAnalyzer.ProfileFace, null, out faceBoundaryTypes); string profileName = null; if (element != null) { ElementType type = element.Document.GetElement(element.GetTypeId()) as ElementType; if (type != null) profileName = type.Name; } // is extrusion? if (sweptAnalyzer.PathCurve is Line) { Line line = sweptAnalyzer.PathCurve as Line; // invalid case if (MathUtil.VectorsAreOrthogonal(line.Direction, sweptAnalyzer.ProfileFace.Normal)) return null; sweptSolidExporter = new SweptSolidExporter(); sweptSolidExporter.m_IsExtrusion = true; Plane plane = new Plane(sweptAnalyzer.ProfileFace.Normal, sweptAnalyzer.ProfileFace.Origin); sweptSolidExporter.m_RepresentationItem = ExtrusionExporter.CreateExtrudedSolidFromCurveLoop(exporterIFC, profileName, faceBoundaries, plane, line.Direction, line.Length * exporterIFC.LinearScale); } else { sweptSolidExporter = new SweptSolidExporter(); sweptSolidExporter.m_RepresentationItem = CreateSimpleSweptSolid(exporterIFC, profileName, faceBoundaries, normal, sweptAnalyzer.PathCurve); } } return sweptSolidExporter; } catch (Exception) { return null; } }
/// <summary> /// Creates a SimpleSweptSolidAnalyzer and computes the swept solid. /// </summary> /// <param name="solid">The solid geometry.</param> /// <param name="normal">The normal of the reference plane that a path might lie on.</param> /// <returns>The analyzer.</returns> public static SimpleSweptSolidAnalyzer Create(Autodesk.Revit.Creation.Application creation, Solid solid, XYZ normal) { if (solid == null || normal == null) throw new ArgumentNullException(); m_appCreation = creation; ICollection<Face> faces = new List<Face>(); foreach (Face face in solid.Faces) { faces.Add(face); } return Create(faces, normal); }
public void TestCreate() { var solid = new Solid(); Assert.Null(solid.Name); Assert.Equal(SolidFormat.Memory, solid.Format); Assert.NotNull(solid.Facets); Assert.Equal(0, solid.Facets.Count); solid = new Solid("Test", new Facet[] { new Facet(), new Facet() }); Assert.Equal("Test", solid.Name); Assert.Equal(SolidFormat.Memory, solid.Format); Assert.NotNull(solid.Facets); Assert.Equal(2, solid.Facets.Count); }
/// <summary> /// creates slices using a curve as the spine /// </summary> /// <param name="solid">Solid: geometry that is to be parsed</param> /// <param name="curve">Curve: defines the normal used to create cut planes perpendicular to parameter "plane". /// If curve is too short, it will be extended using built-in extend function</param> /// <param name="thickness">Thickness: the thickness of the slices, or the thickness of the material to be used for the assembly</param> /// <param name="spacing">Spacing: the distance between each slice</param> /// <returns>A newly-constructed Slicer object</returns> internal Slicer(Solid solid, Curve curve, double thickness, double spacing, double origin) { Solid = solid; Thickness = thickness; Spacing = spacing; Plane plane = Plane.ByOriginNormal(curve.StartPoint, curve.Normal); Curve curvePlanar = curve; if(!curve.IsPlanar) { plane = Plane.ByBestFitThroughPoints(curve.ToNurbsCurve().ControlPoints()); curvePlanar = curve.PullOntoPlane(plane); } CutPlanesPrimary.AddRange(GenerateCutPlanes(plane)); CutPlanesSecondary.AddRange(GenerateCutPlanes(curvePlanar, origin)); InitialGeometry = new List<Geometry>(1){curvePlanar}; }
public static Solid Clone( /*this*/ Solid solid ) { if( solid == null ) { return null; } // Better than unioning the solid with itself: // use a small cube contained within the original // solid instead, e.g. a 1x1x1 cube at the origin // or something. return BooleanOperationsUtils .ExecuteBooleanOperation( solid, solid, BooleanOperationsType.Union ); }
/// <summary> /// Determines if we can create a swept solid from the passed in geometry. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="element">The element.</param> /// <param name="solid">The solid.</param> /// <param name="normal">The optional normal of the plane that the path lies on.</param> /// <returns>If it is possible to create a swept solid, the SimpleSweptSolidAnalyzer that contains the information, otherwise null.</returns> public static SimpleSweptSolidAnalyzer CanExportAsSweptSolid(ExporterIFC exporterIFC, Solid solid, XYZ normal) { try { SimpleSweptSolidAnalyzer sweptAnalyzer = SimpleSweptSolidAnalyzer.Create(solid, normal); if (sweptAnalyzer == null) return null; // TODO: support openings and recess for a swept solid if (sweptAnalyzer.UnalignedFaces != null && sweptAnalyzer.UnalignedFaces.Count > 0) return null; return sweptAnalyzer; } catch (Exception) { return null; } }
//**CONSTRUCTORS /// <summary> /// Internal constructor for the class that has all geometric inputs to create sliced model /// </summary> /// <param name="solid">Solid: geometry that is to be parsed</param> /// <param name="plane">Plane: primary cutplane</param> /// <param name="line1">Line1: (optional) defines secondary cutplane</param> /// <param name="line2">Line2: (optional) defines tertiary cutplane</param> /// <param name="thickness">Thickness: the thickness of the slices, or the thickness of the material to be used for the assembly</param> /// <param name="spacing">Spacing: the distance between each slice</param> internal Slicer(Solid solid, Plane plane, Line line1, Line line2, double thickness, double spacing) { Solid = solid; Thickness = thickness; Spacing = spacing; CutPlanesPrimary.AddRange(GenerateCutPlanes(plane)); InitialGeometry = new List<Geometry>(); InitialGeometry.Add(plane); if (line1 != null) { CutPlanesSecondary.AddRange(GenerateCutPlanes(Plane.ByThreePoints(line1.StartPoint, line1.EndPoint, line1.StartPoint.Add(plane.Normal)))); InitialGeometry.Add(line1); } if (line2 != null) { CutPlanesTertiary.AddRange(GenerateCutPlanes(Plane.ByThreePoints(line2.StartPoint, line2.EndPoint, line2.StartPoint.Add(plane.Normal)))); InitialGeometry.Add(line2); } }
public override bool WorldDraw(Drawable drawable, WorldDraw wd) { if (wd.RegenAbort || wd.IsDragging) { return base.WorldDraw(drawable, wd); } RebarPos pos = drawable as RebarPos; if (pos == null || (pos.IncludeInBOQ && !pos.Detached)) { return base.WorldDraw(drawable, wd); } // Get geometry Point3d minpt; Point3d maxpt; pos.TextBox(out minpt, out maxpt); minpt = minpt.DivideBy(pos.Scale); maxpt = maxpt.DivideBy(pos.Scale); using (Solid solid = new Solid()) { solid.SetPointAt(0, new Point3d(minpt.X - 0.15, minpt.Y - 0.15, 0)); solid.SetPointAt(1, new Point3d(maxpt.X + 0.15, minpt.Y - 0.15, 0)); solid.SetPointAt(2, new Point3d(minpt.X - 0.15, maxpt.Y + 0.15, 0)); solid.SetPointAt(3, new Point3d(maxpt.X + 0.15, maxpt.Y + 0.15, 0)); solid.Color = mColor; solid.LayerId = PosUtility.DefpointsLayer; Matrix3d trans = Matrix3d.AlignCoordinateSystem( Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, pos.BasePoint, pos.DirectionVector, pos.UpVector, pos.NormalVector); solid.TransformBy(trans); wd.Geometry.Draw(solid); } // Draw the entity over shading return base.WorldDraw(drawable, wd); }
public void TestTextWriter() { Solid solid1 = new Solid("test", new List<Facet>() { new Facet(new Vertex( 0.23f, 0, 1), new Vertex[] { new Vertex( 0, 0, 0), new Vertex(-10.123f, -10, 0), new Vertex(-10.123f, 0, 0) }, 0) }); byte[] data; string dataString1; using (MemoryStream stream = new MemoryStream()) using (var writer = new StlTextWriter(stream)) { writer.WriteSolid(solid1); data = stream.ToArray(); dataString1 = Consts.FileEncoding.GetString(data); } Solid solid2; using (MemoryStream stream = new MemoryStream(data)) using (var reader = new StlReader(stream)) { solid2 = reader.ReadSolid(); } Assert.Equal(solid1.Name, solid2.Name); Assert.Equal(solid1.Facets.Count, solid2.Facets.Count); for (int i = 0; i < solid1.Facets.Count; i++) Assert.True(solid1.Facets[i].Equals(solid2.Facets[i])); }
private static bool GetDifferenceFromWallJoins(Document doc, ElementId wallId, Solid baseSolid, IList<IList<IFCConnectedWallData>> connectedWalls) { Options options = GeometryUtil.GetIFCExportGeometryOptions(); foreach (IList<IFCConnectedWallData> wallDataList in connectedWalls) { foreach (IFCConnectedWallData wallData in wallDataList) { ElementId otherWallId = wallData.ElementId; if (otherWallId == wallId) continue; Element otherElem = doc.GetElement(otherWallId); GeometryElement otherGeomElem = (otherElem != null) ? otherElem.get_Geometry(options) : null; if (otherGeomElem == null) continue; SolidMeshGeometryInfo solidMeshInfo = GeometryUtil.GetSplitSolidMeshGeometry(otherGeomElem); if (solidMeshInfo.GetMeshes().Count != 0) return false; IList<Solid> otherSolids = solidMeshInfo.GetSolids(); foreach (Solid otherSolid in otherSolids) { try { BooleanOperationsUtils.ExecuteBooleanOperationModifyingOriginalSolid(baseSolid, otherSolid, BooleanOperationsType.Difference); } catch { return false; } } } } return true; }
public void TestBinaryWriter() { Solid solid1 = new Solid("test", new Facet[] { new Facet(new Vertex( 0, 0, 1), new Vertex[] { new Vertex( 0, 0, 0), new Vertex(-10, -10, 0), new Vertex(-10, 0, 0) }, 0) }); byte[] data; using (MemoryStream stream = new MemoryStream()) using (var writer = new StlBinaryWriter(stream)) { writer.WriteSolid(solid1); data = stream.ToArray(); } Solid solid2; using (MemoryStream stream = new MemoryStream(data)) using (var reader = new StlReader(stream)) { solid2 = reader.ReadSolid(); } Assert.NotEqual(solid1.Name, solid2.Name); Assert.Null(solid2.Name); Assert.Equal(solid1.Facets.Count, solid2.Facets.Count); for (int i = 0; i < solid1.Facets.Count; i++) Assert.True(solid1.Facets[i].Equals(solid2.Facets[i])); }
/// <summary> /// Boolean difference geometric operation, return a new solid as the result /// </summary> /// <param name="solid1">Operation solid 1</param> /// <param name="solid2">Operation solid 2</param> /// <returns>The operation result</returns> public static Solid BooleanOperation_Difference(Solid solid1, Solid solid2) { return(BooleanOperationsUtils.ExecuteBooleanOperation(solid1, solid2, BooleanOperationsType.Difference)); }
/// <summary> /// Creates a SimpleSweptSolidAnalyzer and computes the swept solid. /// </summary> /// <param name="solid">The solid geometry.</param> /// <param name="normal">The normal of the reference plane that a path might lie on.</param> /// <returns>The analyzer.</returns> public static SimpleSweptSolidAnalyzer Create(Autodesk.Revit.Creation.Application creation, Solid solid, XYZ normal) { if (solid == null || normal == null) { throw new ArgumentNullException(); } m_appCreation = creation; ICollection <Face> faces = new List <Face>(); foreach (Face face in solid.Faces) { faces.Add(face); } return(Create(faces, normal)); }
/// <summary> /// Boolean intersect geometric operation, modify the original solid as the result /// </summary> /// <param name="solid1">Operation solid 1 and operation result</param> /// <param name="solid2">Operation solid 2</param> public static void BooleanOperation_Intersect(ref Solid solid1, Solid solid2) { BooleanOperationsUtils.ExecuteBooleanOperationModifyingOriginalSolid(solid1, solid2, BooleanOperationsType.Intersect); }
public static Edge GetInstanceEdgeFromSymbolRef( Reference symbolRef, Document dbDoc) { Edge instEdge = null; Options gOptions = new Options(); gOptions.ComputeReferences = true; gOptions.DetailLevel = ViewDetailLevel.Undefined; gOptions.IncludeNonVisibleObjects = false; Element elem = dbDoc.GetElement(symbolRef.ElementId); string stableRefSymbol = symbolRef .ConvertToStableRepresentation(dbDoc); string[] tokenList = stableRefSymbol.Split( new char[] { ':' }); string stableRefInst = tokenList[3] + ":" + tokenList[4] + ":" + tokenList[5]; GeometryElement geomElem = elem.get_Geometry( gOptions); foreach (GeometryObject geomElemObj in geomElem) { GeometryInstance geomInst = geomElemObj as GeometryInstance; if (geomInst != null) { GeometryElement gInstGeom = geomInst .GetInstanceGeometry(); foreach (GeometryObject gGeomObject in gInstGeom) { Solid solid = gGeomObject as Solid; if (solid != null) { foreach (Edge edge in solid.Edges) { string stableRef = edge.Reference .ConvertToStableRepresentation( dbDoc); if (stableRef == stableRefInst) { instEdge = edge; break; } } } if (instEdge != null) { // already found, exit early break; } } } if (instEdge != null) { // already found, exit early break; } } return(instEdge); }
public void analyzeWallGeometry() { try { #region uiApp.ActiveUIDocument.Selection.GetElementIds().Clear(); ISelectionFilter selFilter = new WallSelectionFilter(); this.Hide(); IList <Reference> walls = uiApp.ActiveUIDocument.Selection.PickObjects(ObjectType.Element, selFilter, "Select walls"); this.Show(); //MessageBox.Show(walls.Count.ToString()); #endregion #region set computing options Options opt = new Options(); opt.ComputeReferences = true; opt.IncludeNonVisibleObjects = true; opt.View = doc.ActiveView; #endregion String faceInfo = ""; String lineInfo = ""; List <Face> faceList = new List <Face>(); foreach (Reference r in walls) { Wall wall = doc.GetElement(r) as Wall; Autodesk.Revit.DB.GeometryElement geomElem = wall.get_Geometry(opt); #region loop foreach (GeometryObject geomObj in geomElem) { Solid geomSolid = geomObj as Solid; if (null != geomSolid) { int faces = 0; int edges = 0; double totalArea = 0; double totalLength = 0; foreach (Face geomFace in geomSolid.Faces) { UV myUV = new UV(0, 0); XYZ normal = geomFace.ComputeNormal(myUV); //MessageBox.Show(normal.ToString()); if ((normal.Z == -1) || (normal.Z == 1)) { faceList.Add(geomFace); } } } } #endregion } if (faceList.Count > 0) { for (int i = 0; i < faceList.Count; ++i) { Face myFace = faceList[i]; EdgeArrayArray eaa = myFace.EdgeLoops; foreach (EdgeArray ea in eaa) { foreach (Edge e in ea) { List <XYZ> yeniListe = new List <XYZ>(); IList <XYZ> pointList = e.Tessellate(); foreach (XYZ point in pointList) { yeniListe.Add(point); } lineCiz(yeniListe); } } } } } catch (Exception ex) { } }
public Brep BrepToSpeckle(Solid solid) { #if REVIT2021 // TODO: Incomplete implementation!! var brep = new Brep(); brep.units = ModelUnits; if (solid is null || solid.Faces.IsEmpty) { return(null); } var faceIndex = 0; var edgeIndex = 0; var curve2dIndex = 0; var curve3dIndex = 0; var loopIndex = 0; var trimIndex = 0; var surfaceIndex = 0; var speckleFaces = new Dictionary <Face, BrepFace>(); var speckleEdges = new Dictionary <Edge, BrepEdge>(); var speckleEdgeIndexes = new Dictionary <Edge, int>(); var speckle3dCurves = new ICurve[solid.Edges.Size]; var speckle2dCurves = new List <ICurve>(); var speckleLoops = new List <BrepLoop>(); var speckleTrims = new List <BrepTrim>(); foreach (var face in solid.Faces.Cast <Face>()) { var surface = FaceToSpeckle(face, out bool orientation, 0.0); var iterator = face.EdgeLoops.ForwardIterator(); var loopIndices = new List <int>(); while (iterator.MoveNext()) { var loop = iterator.Current as EdgeArray; var loopTrimIndices = new List <int>(); // Loop through the edges in the loop. var loopIterator = loop.ForwardIterator(); while (loopIterator.MoveNext()) { // Each edge should create a 2d curve, a 3d curve, a BrepTrim and a BrepEdge. var edge = loopIterator.Current as Edge; var faceA = edge.GetFace(0); // Determine what face side are we currently on. var edgeSide = face == faceA ? 0 : 1; // Get curve, create trim and save index var trim = edge.GetCurveUV(edgeSide); var sTrim = new BrepTrim(brep, edgeIndex, faceIndex, loopIndex, curve2dIndex, 0, BrepTrimType.Boundary, edge.IsFlippedOnFace(edgeSide), -1, -1); var sTrimIndex = trimIndex; loopTrimIndices.Add(sTrimIndex); // Add curve and trim, increase index counters. speckle2dCurves.Add(CurveToSpeckle(trim.As3DCurveInXYPlane())); speckleTrims.Add(sTrim); curve2dIndex++; trimIndex++; // Check if we have visited this edge before. if (!speckleEdges.ContainsKey(edge)) { // First time we visit this edge, add 3d curve and create new BrepEdge. var edgeCurve = edge.AsCurve(); speckle3dCurves[curve3dIndex] = CurveToSpeckle(edgeCurve); var sCurveIndex = curve3dIndex; curve3dIndex++; // Create a trim with just one of the trimIndices set, the second one will be set on the opposite condition. var sEdge = new BrepEdge(brep, sCurveIndex, new[] { sTrimIndex }, -1, -1, edge.IsFlippedOnFace(face), null); speckleEdges.Add(edge, sEdge); speckleEdgeIndexes.Add(edge, edgeIndex); edgeIndex++; } else { // Already visited this edge, skip curve 3d var sEdge = speckleEdges[edge]; var sEdgeIndex = speckleEdgeIndexes[edge]; sTrim.EdgeIndex = sEdgeIndex; // Update trim indices with new item. // TODO: Make this better. var trimIndices = sEdge.TrimIndices.ToList(); trimIndices.Append(sTrimIndex); sEdge.TrimIndices = trimIndices.ToArray(); } } var speckleLoop = new BrepLoop(brep, faceIndex, loopTrimIndices, BrepLoopType.Outer); speckleLoops.Add(speckleLoop); var sLoopIndex = loopIndex; loopIndex++; loopIndices.Add(sLoopIndex); } speckleFaces.Add(face, new BrepFace(brep, surfaceIndex, loopIndices, loopIndices[0], !face.OrientationMatchesSurfaceOrientation)); faceIndex++; brep.Surfaces.Add(surface); surfaceIndex++; } var mesh = new Mesh(); (mesh.faces, mesh.vertices) = GetFaceVertexArrFromSolids(new List <Solid> { solid }); mesh.units = ModelUnits; // TODO: Revit has no brep vertices. Must call 'brep.SetVertices()' in rhino when provenance is revit. // TODO: Set tolerances and flags in rhino when provenance is revit. brep.Faces = speckleFaces.Values.ToList(); brep.Curve2D = speckle2dCurves; brep.Curve3D = speckle3dCurves.ToList(); brep.Trims = speckleTrims; brep.Edges = speckleEdges.Values.ToList(); brep.Loops = speckleLoops; brep.displayValue = mesh; return(brep); #else throw new Exception("Converting BREPs to Speckle is currently only supported in Revit 2021."); #endif }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; UIDocument uidoc = app.ActiveUIDocument; Document doc = uidoc.Document; List <Element> a = new List <Element>(); if (!Util.GetSelectedElementsOrAll(a, uidoc, typeof(FamilyInstance))) { Selection sel = uidoc.Selection; message = (0 < sel.GetElementIds().Count) ? "Please select some family instances." : "No family instances found."; return(Result.Failed); } FamilyInstance inst = a[0] as FamilyInstance; // Here are two ways to traverse the nested instance geometry. // The first way can get the right position, but can't get the right structure. // The second way can get the right structure, but can't get the right position. // What I want is the right structure and right position. // First way: // In the current project project1.rvt, I can get myFamily3 instance via API, // the class is Autodesk.Revit.Elements.FamilyInstance. // Then i try to get its geometry: Options opt = app.Application.Create.NewGeometryOptions(); GeometryElement geoElement = inst.get_Geometry(opt); //GeometryObjectArray a1 = geoElement.Objects; // 2012 //int n = a1.Size; // 2012 int n = geoElement.Count <GeometryObject>(); // 2013 Debug.Print( "Family instance geometry has {0} geometry object{1}{2}", n, Util.PluralSuffix(n), Util.DotOrColon(n)); int i = 0; //foreach( GeometryObject o1 in a1 ) // 2012 foreach (GeometryObject o1 in geoElement) // 2013 { GeometryInstance geoInstance = o1 as GeometryInstance; if (null != geoInstance) { // geometry includes one instance, so get its geometry: GeometryElement symbolGeo = geoInstance.SymbolGeometry; //GeometryObjectArray a2 = symbolGeo.Objects; // 2012 //foreach( GeometryObject o2 in a2 ) // 2012 // the symbol geometry contains five solids. // how can I find out which solid belongs to which column? // how to relate the solid to the family instance? foreach (GeometryObject o2 in symbolGeo) { Solid s = o2 as Solid; if (null != s && 0 < s.Edges.Size) { List <XYZ> vertices = new List <XYZ>(); GetVertices(vertices, s); n = vertices.Count; Debug.Print("Solid {0} has {1} vertices{2} {3}", i++, n, Util.DotOrColon(n), Util.PointArrayString(vertices)); } } } } // In the Revit 2009 API, we can use // FamilyInstance.Symbol.Family.Components // to obtain the nested family instances // within the top level family instance. // In the Revit 2010 API, this property has been // removed, since we can iterate through the elements // of a family just like any other document; // cf. What's New in the RevitAPI.chm: #if REQUIRES_REVIT_2009_API ElementSet components = inst.Symbol.Family.Components; n = components.Size; #endif // REQUIRES_REVIT_2009_API Document fdoc = doc.EditFamily(inst.Symbol.Family); #if REQUIRES_REVIT_2010_API List <Element> components = new List <Element>(); fdoc.get_Elements(typeof(FamilyInstance), components); n = components.Count; #endif // REQUIRES_REVIT_2010_API FilteredElementCollector collector = new FilteredElementCollector(fdoc); collector.OfClass(typeof(FamilyInstance)); IList <Element> components = collector.ToElements(); Debug.Print( "Family instance symbol family has {0} component{1}{2}", n, Util.PluralSuffix(n), Util.DotOrColon(n)); foreach (Element e in components) { // there are 3 FamilyInstance: Column, myFamily1, myFamily2 // then we can loop myFamily1, myFamily2 also. // then get all the Column geometry // But all the Column's position is the same, // because the geometry is defined by the Symbol. // Not the actually position in project1.rvt LocationPoint lp = e.Location as LocationPoint; Debug.Print("{0} at {1}", Util.ElementDescription(e), Util.PointString(lp.Point)); } return(Result.Failed); }
/// <summary> /// Boolean union geometric operation, return a new solid as the result /// </summary> /// <param name="solid1">Operation solid 1</param> /// <param name="solid2">Operation solid 2</param> /// <returns>The operation result</returns> public static Solid BooleanOperation_Union(Solid solid1, Solid solid2) { return(BooleanOperationsUtils.ExecuteBooleanOperation(solid1, solid2, BooleanOperationsType.Union)); }
//Adds a process shape and line and returns a process private Process AddProcessImplementation(string key, Shape parent, Port port, FlowchartStencilType type) { PointF location = new PointF(); Shape flowShape = null; Solid start = (port == null) ? (Solid)parent : (Solid)port; //Set the location if (Orientation == FlowchartOrientation.Vertical) { location = new PointF(start.Location.X, start.Location.Y + Spacing.Height); if (port == null) { location.Y += parent.Bounds.Height; } } else { location = new PointF(start.Location.X + Spacing.Width, start.Location.Y); if (port == null) { location.X += parent.Bounds.Width; } } flowShape = AddFlowShape(key, location, type); //Offset shape depending on size if (Orientation == FlowchartOrientation.Vertical) { flowShape.Location = new PointF(location.X + (start.Bounds.Width - flowShape.Bounds.Width) / 2, location.Y); } else { flowShape.Location = new PointF(location.X, location.Y + (start.Bounds.Height - flowShape.Bounds.Height) / 2); } //Add connecting flowline Link line = CreateElement(LineMode); if (port == null) { line.Start.Shape = parent; } else { line.Start.Port = port; } line.End.Shape = flowShape; line.End.Marker = new Arrow(false); Model.Lines.Add(Model.Lines.CreateKey(), line); //Create the process object and return it Process process = new Process(); process.Line = line; process.Shape = flowShape; process.Port = port; return(process); }
//Adds a process shape and line and returns a process private SubChart AddSubChartImplementation(string key, Shape parent, Port port) { SubChart subChart = new SubChart(); PointF location = new PointF(); Group group = Controller.Factory.CreateGroup(); Solid start = (port == null) ? (Solid)parent : (Solid)port; //Set the location if (Orientation == FlowchartOrientation.Vertical) { location = new PointF(start.Location.X, start.Location.Y + Spacing.Height); if (port == null) { location.Y += parent.Bounds.Height; } } else { location = new PointF(start.Location.X + start.Bounds.Width + Spacing.Width, start.Location.Y); if (port == null) { location.X += parent.Bounds.Width; } } group.Location = location; Model.Shapes.Add(key, group); //Offset the group if (Orientation == FlowchartOrientation.Vertical) { group.Location = new PointF(location.X + (start.Bounds.Width - group.Bounds.Width) / 2, location.Y); } else { group.Location = new PointF(location.X, location.Y + (start.Bounds.Height - group.Bounds.Height) / 2); } //Next add two ports depending on the orientation Port newport = null; if (Orientation == FlowchartOrientation.Vertical) { newport = new Port(PortOrientation.Top); //Keep reference to add line group.Ports.Add("top", newport); group.Ports.Add("bottom", new Port(PortOrientation.Bottom)); } else { newport = new Port(PortOrientation.Left); //Keep reference to add line group.Ports.Add("left", newport); group.Ports.Add("right", new Port(PortOrientation.Right)); } //Finally link the group to the parent shape Link line = CreateElement(LineMode); if (port == null) { line.Start.Shape = parent; } else { line.Start.Port = port; } line.End.Port = newport; line.End.Marker = new Arrow(false); Model.Lines.Add(Model.Lines.CreateKey(), line); //Set up subchart subChart.Line = line; subChart.Group = group; subChart.Port = port; return(subChart); }
public static void Split(Document doc, ElementId elemId) { document = doc; selectedElemId = elemId; selectedElem = document.GetElement(elemId); selectedElemSolid = GetUppermostSolid(selectedElem); try { // Acquire interfering elements IList <Element> interferingElems = GetInterferingElems(selectedElem); if (interferingElems.Count == 0) { return; } if (selectedElem is Wall) { IList <ElementId> inserts = (selectedElem as Wall).FindInserts(true, true, true, true); if (inserts.Count != 0) { return; } if (ModifiedProfile((Wall)selectedElem)) { return; } // Get hold of all solids involed in the clash IList <Solid> interferingSolids = GetInterferingElemsAsSolids(interferingElems); // Perform the boolean opeartions to get the resulting solid Solid resultingSolid = GetResultingSolid(selectedElemSolid, interferingSolids); // Find the face whose normal matches the wall's normal Face face = null; XYZ wallOrientation = ((Wall)selectedElem).Orientation; foreach (Face currFace in resultingSolid.Faces) { XYZ faceNormal = currFace .ComputeNormal(new UV(0, 0)).Normalize(); if (Math.Round( wallOrientation.DotProduct(faceNormal), 2) > 0.1) { face = currFace; break; } } if (face == null) { throw new ArgumentNullException("Face is null"); } // Get a set of curveloops from the face IList <CurveLoop> crvLoops = face.GetEdgesAsCurveLoops(); IList <CurveLoop> orderedCrvloops = (crvLoops.OrderBy(crvloop => { Curve crv = crvloop .Where(c => GetDirectionVector(c).Z == 1) .First(); return(crv.GetEndPoint(0).Z); })).ToList(); // Get Wall's properties Wall wall = (Wall)selectedElem; WallType wallType = wall.WallType; using (Transaction t = new Transaction(doc, "Create walls")) { t.Start(); for (int i = 0; i < orderedCrvloops.Count; i++) { // Select a curve Curve selectedCrv = orderedCrvloops[i].Where(crv => GetDirectionVector(crv).Z == 1).First(); double currWallHeight = selectedCrv.ApproximateLength; if (i == 0) { double offset = wall.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).AsDouble(); Wall.Create(doc, ((LocationCurve)wall.Location).Curve, wallType.Id, wall.LevelId, currWallHeight, offset, false, true); } else { Element intruder = interferingElems .ElementAt(i - 1); ElementId currLevelId = intruder.LevelId; double offset = intruder .get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM) .AsDouble(); Wall.Create(doc, ((LocationCurve)wall.Location).Curve, wallType.Id, currLevelId, currWallHeight, offset, false, true); } } doc.Delete(wall.Id); t.Commit(); } } else { List <Curve> crvs = new List <Curve>(); IDictionary <Curve, Level> crvsLvls = new Dictionary <Curve, Level>(); Curve currCrv = GetColumnAxis(selectedElem); ElementId prevElemId = interferingElems.ElementAt(0).LevelId; for (int i = 0; i < interferingElems.Count; i++) { Element currElem = interferingElems.ElementAt(i); Solid elemSolid = GetUppermostSolid(currElem); SolidCurveIntersection results = elemSolid.IntersectWithCurve (currCrv, new SolidCurveIntersectionOptions { ResultType = SolidCurveIntersectionMode.CurveSegmentsOutside }); if (results.SegmentCount == 2) { // if it is not the last segment if (i != interferingElems.Count - 1) { crvs.Add(results.GetCurveSegment(0)); currCrv = results.GetCurveSegment(1); crvsLvls.Add(results.GetCurveSegment(0), (Level)doc.GetElement(prevElemId)); } else { crvs.Add(results.GetCurveSegment(0)); crvs.Add(results.GetCurveSegment(1)); crvsLvls.Add(results.GetCurveSegment(0), (Level)doc.GetElement(prevElemId)); crvsLvls.Add(results.GetCurveSegment(1), (Level)doc.GetElement(currElem.LevelId)); } } else { currCrv = results.GetCurveSegment(0); } prevElemId = currElem.LevelId; } FamilySymbol columnType = ((FamilyInstance)selectedElem).Symbol; using (Transaction t = new Transaction(doc, "Split Column")) { t.Start(); foreach (Curve crv in crvsLvls.Keys) { doc.Create.NewFamilyInstance (crv, columnType, crvsLvls[crv], StructuralType.Column); } doc.Delete(selectedElem.Id); t.Commit(); } } } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { } catch (Exception ex) { TaskDialog.Show("Exception", string.Format("StackTrace:\n{0}\nMessage:\n{1}", ex.StackTrace, ex.Message)); } }
/// <summary> /// Find elements blocking egress /// </summary> /// <param name="egresses">The egresses to be detected</param> /// <returns>The detection result</returns> public XElement findBlockingElements(ICollection <Element> egresses) { // create a node that place all egresses. XElement egressesNode = new XElement("Egresses", new XAttribute("Name", "Egresses")); try { // find the elements blocking egress foreach (Element egressElement in egresses) { XElement egressNode = new XElement("Egress", new XAttribute("Name", egressElement.Name)); int count = 1; IEnumerator <GeometryObject> Objects = egressElement.get_Geometry(new Autodesk.Revit.DB.Options()).GetEnumerator(); Objects.MoveNext(); GeometryInstance gi = Objects.Current as GeometryInstance; IEnumerator <GeometryObject> Objects1 = gi.GetInstanceGeometry().GetEnumerator(); //foreach (GeometryObject egressGObj in // (egressElement.get_Geometry(new Autodesk.Revit.DB.Options()).Objects.get_Item(0) as GeometryInstance).GetInstanceGeometry().Objects) while (Objects1.MoveNext()) { GeometryObject egressGObj = Objects1.Current; if (egressGObj is Solid) { Solid egressVolume = egressGObj as Solid; //calculated from shape and location of a given door XElement solidNode = new XElement("ElementSolid" + count.ToString()); // Iterate to find all instance types FilteredElementCollector blockingcollector = new FilteredElementCollector(m_doc); blockingcollector.WhereElementIsNotElementType(); // Apply geometric filter ElementIntersectsSolidFilter testElementIntersectsSolidFilter = new ElementIntersectsSolidFilter(egressVolume); blockingcollector.WherePasses(testElementIntersectsSolidFilter); IEnumerable <Element> blockingElement = blockingcollector; // Exclude the door itself List <ElementId> exclusions = new List <ElementId>(); exclusions.Add(egressElement.Id); blockingcollector.Excluding(exclusions); XElement blockingegressNode = new XElement("blocking_egress_elements", new XAttribute("Count", blockingElement.Count().ToString())); foreach (Element blockingelement in blockingElement) { blockingegressNode.Add(new XElement("blocking_egress_element", new XAttribute("Name", blockingelement.Name))); } solidNode.Add(blockingegressNode); egressNode.Add(solidNode); count++; } } egressesNode.Add(egressNode); } } catch (Exception ex) { egressesNode.Add(new XElement("Error", new XAttribute("Exception", ex.ToString()))); } // return the whole Egresses Node return(egressesNode); }
/// <summary> /// Return a reference to the topmost face of the given element. /// </summary> private Reference FindTopMostReference(Element e) { Reference ret = null; Document doc = e.Document; #region Revit 2012 #if _2012 using (SubTransaction t = new SubTransaction(doc)) { t.Start(); // Create temporary 3D view //View3D view3D = doc.Create.NewView3D( // 2012 // viewDirection ); // 2012 ViewFamilyType vft = new FilteredElementCollector(doc) .OfClass(typeof(ViewFamilyType)) .Cast <ViewFamilyType>() .FirstOrDefault <ViewFamilyType>(x => ViewFamily.ThreeDimensional == x.ViewFamily); Debug.Assert(null != vft, "expected to find a valid 3D view family type"); View3D view = View3D.CreateIsometric(doc, vft.Id); // 2013 XYZ eyePosition = XYZ.BasisZ; XYZ upDirection = XYZ.BasisY; XYZ forwardDirection = -XYZ.BasisZ; view.SetOrientation(new ViewOrientation3D( eyePosition, upDirection, forwardDirection)); XYZ viewDirection = -XYZ.BasisZ; BoundingBoxXYZ bb = e.get_BoundingBox(view); XYZ max = bb.Max; XYZ minAtMaxElevation = Create.NewXYZ( bb.Min.X, bb.Min.Y, max.Z); XYZ centerOfTopOfBox = 0.5 * (minAtMaxElevation + max); centerOfTopOfBox += 10 * XYZ.BasisZ; // Cast a ray through the model // to find the topmost surface #if DEBUG //ReferenceArray references // = doc.FindReferencesByDirection( // centerOfTopOfBox, viewDirection, view3D ); // 2011 IList <ReferenceWithContext> references = doc.FindReferencesWithContextByDirection( centerOfTopOfBox, viewDirection, view); // 2012 double closest = double.PositiveInfinity; //foreach( Reference r in references ) //{ // // 'Autodesk.Revit.DB.Reference.Element' is // // obsolete: Property will be removed. Use // // Document.GetElement(Reference) instead. // //Element re = r.Element; // 2011 // Element re = doc.GetElement( r ); // 2012 // if( re.Id.IntegerValue == e.Id.IntegerValue // && r.ProximityParameter < closest ) // { // ret = r; // closest = r.ProximityParameter; // } //} foreach (ReferenceWithContext r in references) { Element re = doc.GetElement( r.GetReference()); // 2012 if (re.Id.IntegerValue == e.Id.IntegerValue && r.Proximity < closest) { ret = r.GetReference(); closest = r.Proximity; } } string stable_reference = null == ret ? null : ret.ConvertToStableRepresentation(doc); #endif // DEBUG ReferenceIntersector ri = new ReferenceIntersector( e.Id, FindReferenceTarget.Element, view); ReferenceWithContext r2 = ri.FindNearest( centerOfTopOfBox, viewDirection); if (null == r2) { Debug.Print("ReferenceIntersector.FindNearest returned null!"); } else { ret = r2.GetReference(); Debug.Assert(stable_reference.Equals(ret .ConvertToStableRepresentation(doc)), "expected same reference from " + "FindReferencesWithContextByDirection and " + "ReferenceIntersector"); } t.RollBack(); } #endif // _2012 #endregion // Revit 2012 Options opt = doc.Application.Create .NewGeometryOptions(); opt.ComputeReferences = true; GeometryElement geo = e.get_Geometry(opt); foreach (GeometryObject obj in geo) { GeometryInstance inst = obj as GeometryInstance; if (null != inst) { geo = inst.GetSymbolGeometry(); break; } } Solid solid = geo.OfType <Solid>() .First <Solid>(sol => null != sol); double z = double.MinValue; foreach (Face f in solid.Faces) { BoundingBoxUV b = f.GetBoundingBox(); UV p = b.Min; UV q = b.Max; UV midparam = p + 0.5 * (q - p); XYZ midpoint = f.Evaluate(midparam); XYZ normal = f.ComputeNormal(midparam); if (Util.PointsUpwards(normal)) { if (midpoint.Z > z) { z = midpoint.Z; ret = f.Reference; } } } return(ret); }
/// <summary> /// Boolean union geometric operation, modify the original solid as the result /// </summary> /// <param name="solid1">Operation solid 1 and operation result</param> /// <param name="solid2">Operation solid 2</param> public static void BooleanOperation_Union(ref Solid solid1, Solid solid2) { BooleanOperationsUtils.ExecuteBooleanOperationModifyingOriginalSolid(solid1, solid2, BooleanOperationsType.Union); }
static void CreateFaceWalls( Document doc) { Application app = doc.Application; Document massDoc = app.NewFamilyDocument( _conceptual_mass_template_path); CreateMassExtrusion(massDoc); //if( File.Exists( _family_path ) ) // File.Delete( _family_path ); SaveAsOptions opt = new SaveAsOptions(); opt.OverwriteExistingFile = true; massDoc.SaveAs(_family_path, opt); using (Transaction tx = new Transaction(doc)) { tx.Start("Create FaceWall"); if (!doc.LoadFamily(_family_path)) { throw new Exception("DID NOT LOAD FAMILY"); } Family family = new FilteredElementCollector(doc) .OfClass(typeof(Family)) .Where <Element>(x => x.Name.Equals(_family_name)) .Cast <Family>() .FirstOrDefault(); FamilySymbol fs = doc.GetElement( family.GetFamilySymbolIds().First <ElementId>()) as FamilySymbol; // Create a family instance Level level = doc.ActiveView.GenLevel; FamilyInstance fi = doc.Create.NewFamilyInstance( XYZ.Zero, fs, level, StructuralType.NonStructural); doc.Regenerate(); // required to generate the geometry! // Determine wall type. WallType wallType = new FilteredElementCollector(doc) .OfClass(typeof(WallType)) .Cast <WallType>() .Where <WallType>(x => FaceWall.IsWallTypeValidForFaceWall(doc, x.Id)) .FirstOrDefault(); // Retrieve mass element geometry. Options options = app.Create.NewGeometryOptions(); options.ComputeReferences = true; //options.View = doc.ActiveView; // conceptual mass is not visible in default view GeometryElement geo = fi.get_Geometry(options); // Create a sloped wall from the geometry. foreach (GeometryObject obj in geo) { Solid solid = obj as Solid; if (null != solid) { foreach (Face f in solid.Faces) { Debug.Assert(null != f.Reference, "we asked for references, didn't we?"); PlanarFace pf = f as PlanarFace; if (null != pf) { XYZ v = pf.FaceNormal; // Errors: // // Could not create a face wall. // // Caused by using ActiveView.Level // instead of ActiveView.GenLevel. // // This reference cannot be applied to a face wall. // // Caused by using this on a horizontal face. if (!Util.IsVertical(v)) { FaceWall.Create( doc, wallType.Id, WallLocationLine.CoreCenterline, f.Reference); } } } } } tx.Commit(); } }
/// <summary> /// Retrieve the planar face normal and origin /// from all of the solid's planar faces and /// insert them into the map mapping face normals /// to a list of all origins of different faces /// sharing this normal. /// </summary> /// <param name="naos">Map mapping each normal vector /// to a list of the origins of all planar faces /// sharing this normal direction</param> /// <param name="solid">Input solid</param> void getFaceNaos( Dictionary<XYZ, List<XYZ>> naos, Solid solid) { foreach( Face face in solid.Faces ) { PlanarFace planarFace = face as PlanarFace; if( null != planarFace ) { XYZ normal = planarFace.Normal; XYZ origin = planarFace.Origin; List<XYZ> normals = new List<XYZ>( naos.Keys ); int i = normals.FindIndex( delegate( XYZ v ) { return XyzParallel( v, normal ); } ); if( -1 == i ) { Debug.Print( "Face at {0} has new normal {1}", Util.PointString( origin ), Util.PointString( normal ) ); naos.Add( normal, new List<XYZ>() ); naos[normal].Add( origin ); } else { Debug.Print( "Face at {0} normal {1} matches {2}", Util.PointString( origin ), Util.PointString( normal ), Util.PointString( normals[i] ) ); naos[normals[i]].Add( origin ); } } } }
public static void SlopedWallTest( ExternalCommandData revit) { Document massDoc = revit.Application.Application.NewFamilyDocument( @"C:\ProgramData\Autodesk\RAC 2012\Family Templates\English_I\Conceptual Mass\Mass.rft"); Transaction transaction = new Transaction(massDoc); transaction.SetName("TEST"); transaction.Start(); ExternalCommandData cdata = revit; Autodesk.Revit.ApplicationServices.Application app = revit.Application.Application; app = revit.Application.Application; // Create one profile ReferenceArray ref_ar = new ReferenceArray(); Autodesk.Revit.DB.XYZ ptA = new XYZ(0, 0, 0); XYZ ptB = new XYZ(0, 30, 0); ModelCurve modelcurve = MakeLine(revit.Application, ptA, ptB, massDoc); ref_ar.Append(modelcurve.GeometryCurve.Reference); ptA = new XYZ(0, 30, 0); ptB = new XYZ(2, 30, 0); modelcurve = MakeLine(revit.Application, ptA, ptB, massDoc); ref_ar.Append(modelcurve.GeometryCurve.Reference); ptA = new XYZ(2, 30, 0); ptB = new XYZ(2, 0, 0); modelcurve = MakeLine(revit.Application, ptA, ptB, massDoc); ref_ar.Append(modelcurve.GeometryCurve.Reference); ptA = new XYZ(2, 0, 0); ptB = new XYZ(0, 0, 0); modelcurve = MakeLine(revit.Application, ptA, ptB, massDoc); ref_ar.Append(modelcurve.GeometryCurve.Reference); // The extrusion form direction XYZ direction = new XYZ(-6, 0, 50); Form form = massDoc.FamilyCreate.NewExtrusionForm(true, ref_ar, direction); transaction.Commit(); if (File.Exists(@"C:\TestFamily.rfa")) { File.Delete(@"C:\TestFamily.rfa"); } massDoc.SaveAs(@"C:\TestFamily.rfa"); if (!revit.Application.ActiveUIDocument.Document.LoadFamily(@"C:\TestFamily.rfa")) { throw new Exception("DID NOT LOAD FAMILY"); } Family family = null; foreach (Element el in new FilteredElementCollector( revit.Application.ActiveUIDocument.Document).WhereElementIsNotElementType().ToElements()) { if (el is Family) { if (((Family)el).Name.ToUpper().Trim().StartsWith("TEST")) { family = (Family)el; } } } FamilySymbol fs = null; foreach (FamilySymbol sym in family.Symbols) { fs = sym; } // Create a family instance. revit.Application.ActiveUIDocument.Document.Create.NewFamilyInstance( new XYZ(0, 0, 0), fs, revit.Application.ActiveUIDocument.Document.ActiveView.Level, StructuralType.NonStructural); WallType wallType = null; foreach (WallType wt in revit.Application.ActiveUIDocument.Document.WallTypes) { if (FaceWall.IsWallTypeValidForFaceWall(revit.Application.ActiveUIDocument.Document, wt.Id)) { wallType = wt; break; } } foreach (Element el in new FilteredElementCollector( revit.Application.ActiveUIDocument.Document).WhereElementIsNotElementType().ToElements()) { if (el is FamilyInstance) { if (((FamilyInstance)el).Symbol.Family.Name.ToUpper().StartsWith("TEST")) { Options options = revit.Application.Application.Create.NewGeometryOptions(); options.ComputeReferences = true; options.View = revit.Application.ActiveUIDocument.Document.ActiveView; GeometryElement geoel = el.get_Geometry(options); // Attempt to create a slopped wall from the geometry. for (int i = 0; i < geoel.Objects.Size; i++) { if (geoel.Objects.get_Item(i) is Solid) { Solid solid = (Solid)geoel.Objects.get_Item(i); for (int j = 0; j < solid.Faces.Size; j++) { try { if (solid.Faces.get_Item(i).Reference != null) { FaceWall.Create(revit.Application.ActiveUIDocument.Document, wallType.Id, WallLocationLine.CoreCenterline, solid.Faces.get_Item(i).Reference); } } catch (System.Exception e) { System.Windows.Forms.MessageBox.Show(e.Message); } } } } } } } }
public Solid TransformSolid(Transform targetTransform, Transform sourceTransform, Solid solid) { var transform = targetTransform.Multiply(sourceTransform); var solidInTargetModel = SolidUtils.CreateTransformed(solid, transform); return(solidInTargetModel); }
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); }
public void Setup() { this.solid = new Solid(); }
private bool IsRiding(Solid solid) { return(CollideCheck(solid)); }
/// <summary> /// Sample file is at /// C:\a\j\adn\case\bsd\1242980\attach\mullion.rvt /// </summary> public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; UIDocument uidoc = app.ActiveUIDocument; Document doc = app.ActiveUIDocument.Document; Selection sel = uidoc.Selection; Options options = app.Application.Create.NewGeometryOptions(); string s, msg = string.Empty; int n; foreach (ElementId id in sel.GetElementIds()) { Mullion mullion = doc.GetElement(id) as Mullion; if (null != mullion) { //Location location = mullion.AsFamilyInstance.Location; // seems to be uninitialised // 2011 Location location = mullion.Location; // 2012 LocationPoint lp = mullion.Location as LocationPoint; Debug.Assert(null != lp, "expected a valid mullion location point"); Debug.Assert(null != mullion.LocationCurve, // 2012 "in Revit 2012, the mullion also has a valid location curve"); // 2012 GeometryElement geoElem = mullion.get_Geometry(options); //GeometryObjectArray objects = geoElem.Objects; // 2012 //n = objects.Size; // 2012 n = geoElem.Count <GeometryObject>(); // 2013 s = string.Format( "Mullion <{0} {1}> at {2} rotation" + " {3} has {4} geo object{5}:", mullion.Name, mullion.Id.IntegerValue, Util.PointString(lp.Point), Util.RealString(lp.Rotation), n, Util.PluralSuffix(n)); if (0 < msg.Length) { msg += "\n\n"; } msg += s; //foreach( GeometryObject obj in objects ) // 2012 foreach (GeometryObject obj in geoElem) // 2013 { GeometryInstance inst = obj as GeometryInstance; Transform t = inst.Transform; s = " Transform " + Util.TransformString(t); msg += "\n" + s; GeometryElement elem2 = inst.SymbolGeometry; //foreach( GeometryObject obj2 in elem2.Objects ) // 2012 foreach (GeometryObject obj2 in elem2) // 2013 { Solid solid = obj2 as Solid; if (null != solid) { FaceArray faces = solid.Faces; n = faces.Size; s = string.Format( " {0} face{1}, face point > WCS point:", n, Util.PluralSuffix(n)); msg += "\n" + s; foreach (Face face in solid.Faces) { s = string.Empty; Mesh mesh = face.Triangulate(); foreach (XYZ p in mesh.Vertices) { s += (0 == s.Length) ? " " : ", "; s += string.Format("{0} > {1}", Util.PointString(p), Util.PointString(t.OfPoint(p))); } msg += "\n" + s; } } } } } } if (0 == msg.Length) { msg = "Please select some mullions."; } Util.InfoMsg(msg); return(Result.Failed); }
/// <summary> /// Subtracts right solid from left one. /// </summary> /// <remarks> /// <para> /// Implementation of this operation comes from set theory: subtraction is negation of union /// of negated first object with second one. /// </para> /// <code> /// +-------+ +-------+ /// | | | | /// | A | | | /// | +--+----+ = | +--+ /// +----+--+ | +----+ /// | B | /// | | /// +-------+ /// </code> /// </remarks> /// <example> /// <code> /// // Create a tube. /// const float tubeOuterRadius = 2; /// const float tubeShellThickness = 0.1f; /// const float tubeLength = 100; /// /// Vector3 leftCapPoint = new Vector3(); /// Vector3 rightCapPoint = new Vector3(tubeLength, 0, 0); /// /// Solid outerCylinder = Solid.Cylinder(leftCapPoint, rightCapPoint, tubeOuterRadius); /// Solid innerCylinder = Solid.Cylinder(leftCapPoint, rightCapPoint, /// tubeOuterRadius - tubeShellThickness); /// /// Solid tube = CSG.Subtract(outerCylinder, innerCylinder); /// // Create a frame. /// const float frameSize = 10; /// const float frameThickness = 0.5f; /// /// const float innerCuboidThickness = frameSize - frameThickness * 2; /// /// Solid outerCube = Solid.Cuboid(null, new Vector3(frameSize)); /// Solid firstInnerCuboid = Solid.Cuboid /// ( /// null, /// new Vector3 /// ( /// frameSize + 2, /// innerCuboidThickness, /// innerCuboidThickness /// ) /// ); /// Solid secondInnerCuboid = Solid.Cuboid /// ( /// null, /// new Vector3 /// ( /// innerCuboidThickness, /// frameSize + 2, /// innerCuboidThickness /// ) /// ); /// Solid thirdInnerCuboid = Solid.Cuboid /// ( /// null, /// new Vector3 /// ( /// innerCuboidThickness, /// innerCuboidThickness, /// frameSize + 2 /// ) /// ); /// /// Solid cubeFrame = /// ConstructiveSolidGeometry.Subtract /// ( /// outerCube, /// ConstructiveSolidGeometry.Union /// ( /// firstInnerCuboid, /// ConstructiveSolidGeometry.Union /// ( /// secondInnerCuboid, /// thirdInnerCuboid /// ) /// ) /// ); /// </code></example> /// <param name="a">First solid.</param> /// <param name="b">Second solid.</param> /// <returns>Result of subtraction.</returns> public static Solid Subtract(Solid a, Solid b) { // Initialize BSP trees. Node aNode = new Node(a.Polygons); Node bNode = new Node(b.Polygons); aNode.Invert(); // Invert A. aNode.ClipTo(bNode); // bNode.ClipTo(aNode); // bNode.Invert(); // Union of inverted A with B. bNode.ClipTo(aNode); // bNode.Invert(); // aNode.Build(bNode.AllPolygons); // aNode.Invert() // Invert everything since what we've got ; // above is what we need but it's inside out. return new Solid(aNode.AllPolygons); }
public FindIntersection( FamilyInstance jbox, UIDocument uiDoc) { XYZ jboxPoint = (jbox.Location as LocationPoint).Point; FilteredElementCollector filteredCloserConduits = new FilteredElementCollector(uiDoc.Document); List <Element> listOfCloserConduit = filteredCloserConduits .OfClass(typeof(Conduit)) .ToList() .Where(x => ((x as Conduit).Location as LocationCurve).Curve .GetEndPoint(0).DistanceTo(jboxPoint) < 30 || ((x as Conduit).Location as LocationCurve).Curve .GetEndPoint(1).DistanceTo(jboxPoint) < 30) .ToList(); // getting the location of the box and all conduit around. Options opt = new Options(); opt.View = uiDoc.ActiveView; GeometryElement geoEle = jbox.get_Geometry(opt); // getting the geometry of the element to // access the geometry of the instance. foreach (GeometryObject geomObje1 in geoEle) { GeometryElement geoInstance = (geomObje1 as GeometryInstance).GetInstanceGeometry(); // the geometry of the family instance can be // accessed by this method that returns a // GeometryElement type. so we must get the // GeometryObject again to access the Face of // the family instance. if (geoInstance != null) { foreach (GeometryObject geomObje2 in geoInstance) { Solid geoSolid = geomObje2 as Solid; if (geoSolid != null) { foreach (Face face in geoSolid.Faces) { foreach (Element cond in listOfCloserConduit) { Conduit con = cond as Conduit; Curve conCurve = (con.Location as LocationCurve).Curve; SetComparisonResult set = face.Intersect(conCurve); if (set.ToString() == "Overlap") { //getting the conduit the intersect the box. GetListOfConduits.Add(con); } } } } } } } }
public static bool Intersects(Rectangle rect, Solid solid) { Vector2 minDelta = Vector2.Zero; float minDeltaLength = 0; Vector2[] axes = new Vector2[solid.Axes.Length + 2]; axes[0] = new Vector2(1, 0); axes[1] = new Vector2(0, 1); solid.Axes.CopyTo(axes, 2); foreach (var axis in axes) { // проекция персонажа Vector2 projBegin1; projBegin1 = GetProjection(new Vector2(rect.Left, rect.Top), axis); Vector2 proj = GetProjection(new Vector2(rect.Left, rect.Bottom), axis); if ((proj.X < projBegin1.X) || ((proj.X == projBegin1.X) && (proj.Y < projBegin1.Y))) projBegin1 = proj; Vector2 projEnd1; projEnd1 = GetProjection(new Vector2(rect.Right, rect.Top), axis); proj = GetProjection(new Vector2(rect.Right, rect.Bottom), axis); if ((proj.X > projEnd1.X) || ((proj.X == projEnd1.X) && (proj.Y > projEnd1.Y))) projEnd1 = proj; // проекция тела Vector2 projBegin2; Vector2 projEnd2; projBegin2 = projEnd2 = GetProjection(solid.Vertices[0], axis); for (int i = 1; i < solid.Vertices.Length; i++) { proj = GetProjection(solid.Vertices[i], axis); if ((proj.X < projBegin2.X) || ((proj.X == projBegin2.X) && (proj.Y < projBegin2.Y))) projBegin2 = proj; else if ((proj.X > projEnd2.X) || ((proj.X == projEnd2.X) && (proj.Y > projEnd2.Y))) projEnd2 = proj; } Vector2 delta = Vector2.Zero; Vector2 d1 = projEnd1 - projBegin2; if ((d1.X > 0) || ((d1.X == 0) && (d1.Y > 0))) { Vector2 d2 = projEnd2 - projBegin1; if ((d2.X > 0) || ((d2.X == 0) && (d2.Y > 0))) { if ((d1.X < d2.X) || ((d1.X == d2.X) && (d1.Y <= d2.Y))) { delta = -d1; } else { delta = d2; } } } if (delta == Vector2.Zero) { return false; } float deltaLength = delta.Length(); if ((minDelta == Vector2.Zero) || (deltaLength < minDeltaLength)) { minDelta = delta; minDeltaLength = deltaLength; } } return true; }
public static Reference GetSpecialFamilyReference( FamilyInstance inst, SpecialReferenceType refType) { Reference indexRef = null; int idx = (int)refType; if (inst != null) { Document dbDoc = inst.Document; Options geomOptions = dbDoc.Application.Create .NewGeometryOptions(); if (geomOptions != null) { geomOptions.ComputeReferences = true; geomOptions.DetailLevel = ViewDetailLevel.Undefined; geomOptions.IncludeNonVisibleObjects = true; } GeometryElement gElement = inst.get_Geometry( geomOptions); GeometryInstance gInst = gElement.First() as GeometryInstance; String sampleStableRef = null; if (gInst != null) { GeometryElement gSymbol = gInst .GetSymbolGeometry(); if (gSymbol != null) { foreach (GeometryObject geomObj in gSymbol) { if (geomObj is Solid) { Solid solid = geomObj as Solid; if (solid.Faces.Size > 0) { Face face = solid.Faces.get_Item(0); sampleStableRef = face.Reference .ConvertToStableRepresentation( dbDoc); break; } } else if (geomObj is Curve) { Curve curve = geomObj as Curve; sampleStableRef = curve.Reference .ConvertToStableRepresentation(dbDoc); break; } else if (geomObj is Point) { Point point = geomObj as Point; sampleStableRef = point.Reference .ConvertToStableRepresentation(dbDoc); break; } } } if (sampleStableRef != null) { String[] refTokens = sampleStableRef.Split( new char[] { ':' }); String customStableRef = refTokens[0] + ":" + refTokens[1] + ":" + refTokens[2] + ":" + refTokens[3] + ":" + idx.ToString(); indexRef = Reference .ParseFromStableRepresentation( dbDoc, customStableRef); GeometryObject geoObj = inst .GetGeometryObjectFromReference( indexRef); if (geoObj != null) { String finalToken = ""; if (geoObj is Edge) { finalToken = ":LINEAR"; } if (geoObj is Face) { finalToken = ":SURFACE"; } customStableRef += finalToken; indexRef = Reference .ParseFromStableRepresentation( dbDoc, customStableRef); } else { indexRef = null; } } } else { throw new Exception("No Symbol Geometry found..."); } } return(indexRef); }
/// <summary> /// Get the swept profile(face) of the host object(family instance) /// </summary> /// <param name="solid">the solid reference</param> /// <returns>the swept profile</returns> private Face GetSweptProfileFace(Solid solid) { // Get a point on the swept profile from all points in solid Autodesk.Revit.DB.XYZ refPoint = new Autodesk.Revit.DB.XYZ (); // the point on swept profile foreach (Edge edge in solid.Edges) { List<XYZ> points = edge.Tessellate() as List<XYZ>; //get end points of the edge if (2 != points.Count) // make sure all edges are lines { throw new Exception("All edge should be line."); } // get two points of the edge. All points in solid should be transform first Autodesk.Revit.DB.XYZ first = Transform(points[0]); // start point of edge Autodesk.Revit.DB.XYZ second = Transform(points[1]); // end point of edge // some edges should be parallelled with the driving line, // and the start point of that edge should be the wanted point Autodesk.Revit.DB.XYZ edgeVector = GeomUtil.SubXYZ(second, first); if (GeomUtil.IsSameDirection(edgeVector, m_drivingVector)) { refPoint = first; break; } if (GeomUtil.IsOppositeDirection(edgeVector, m_drivingVector)) { refPoint = second; break; } } // Find swept profile(face) Face sweptFace = null; // define the swept face foreach (Face face in solid.Faces) { if (null != sweptFace) { break; } // the swept face should be perpendicular with the driving line if (!GeomUtil.IsVertical(face, m_drivingLine, m_transform, null)) { continue; } // use the gotted point to get the swept face foreach (Autodesk.Revit.DB.XYZ point in face.Triangulate().Vertices) { Autodesk.Revit.DB.XYZ pnt = Transform(point); // all points in solid should be transform if (GeomUtil.IsEqual(refPoint, pnt)) { sweptFace = face; break; } } } return sweptFace; }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; Document doc = app.ActiveUIDocument.Document; View3D view3d = doc.ActiveView as View3D; if (null == view3d) { message = "Please activate a 3D view" + " before running this command."; return(Result.Failed); } using (Transaction t = new Transaction(doc)) { t.Start("Crop to Room"); // get the 3d view crop box: BoundingBoxXYZ bb = view3d.CropBox; // get the transform from the current view // to the 3D model: Transform transform = bb.Transform; // get the transform from the 3D model // to the current view: Transform transformInverse = transform.Inverse; // get all rooms in the model: FilteredElementCollector collector = new FilteredElementCollector(doc); collector.OfClass(typeof(Room)); IList <Element> rooms = collector.ToElements(); int n = rooms.Count; Room room = (0 < n) ? rooms[BumpRoomIndex(n)] as Room : null; if (null == room) { message = "No room element found in project."; return(Result.Failed); } // Collect all vertices of room closed shell // to determine its extents: GeometryElement e = room.ClosedShell; List <XYZ> vertices = new List <XYZ>(); //foreach( GeometryObject o in e.Objects ) // 2012 foreach (GeometryObject o in e) // 2013 { if (o is Solid) { // Iterate over all the edges of all solids: Solid solid = o as Solid; foreach (Edge edge in solid.Edges) { foreach (XYZ p in edge.Tessellate()) { // Collect all vertices, // including duplicates: vertices.Add(p); } } } } List <XYZ> verticesIn3dView = new List <XYZ>(); foreach (XYZ p in vertices) { verticesIn3dView.Add( transformInverse.OfPoint(p)); } // Ignore the Z coorindates and find the // min and max X and Y in the 3d view: double xMin = 0, yMin = 0, xMax = 0, yMax = 0; bool first = true; foreach (XYZ p in verticesIn3dView) { if (first) { xMin = p.X; yMin = p.Y; xMax = p.X; yMax = p.Y; first = false; } else { if (xMin > p.X) { xMin = p.X; } if (yMin > p.Y) { yMin = p.Y; } if (xMax < p.X) { xMax = p.X; } if (yMax < p.Y) { yMax = p.Y; } } } // Grow the crop box by one twentieth of its // size to include the walls of the room: double d = 0.05 * (xMax - xMin); xMin = xMin - d; xMax = xMax + d; d = 0.05 * (yMax - yMin); yMin = yMin - d; yMax = yMax + d; bb.Max = new XYZ(xMax, yMax, bb.Max.Z); bb.Min = new XYZ(xMin, yMin, bb.Min.Z); view3d.CropBox = bb; // Change the crop view setting manually or // programmatically to see the result: view3d.CropBoxActive = true; view3d.CropBoxVisible = true; t.Commit(); } return(Result.Succeeded); }
/// <summary> /// Boolean difference geometric operation, modify the original solid as the result /// </summary> /// <param name="solid1">Operation solid 1 and operation result</param> /// <param name="solid2">Operation solid 2</param> public static void BooleanOperation_Difference(ref Solid solid1, Solid solid2) { BooleanOperationsUtils.ExecuteBooleanOperationModifyingOriginalSolid(solid1, solid2, BooleanOperationsType.Difference); }
/// <summary> /// Combines two solids together into one solid. /// </summary> /// <remarks> /// <code> /// +-------+ +-------+ /// | | | | /// | A | | | /// | +--+----+ = | +----+ /// +----+--+ | +----+ | /// | B | | | /// | | | | /// +-------+ +-------+ /// </code></remarks> /// <example> /// <code> /// // Create 2x1x1 cuboid from two 1x1x1 cubes placed in a row. /// const float blockSideLength = 1; /// /// Solid block1 = Solid.Cuboid(new Vector3(), new Vector3(blockSideLength)); /// Solid block2 = Solid.Cuboid(new Vector3(blockSideLength / 2, 0, 0), new Vector3(blockSideLength)); /// /// Solid twoBlocksInARow = ConstructiveSolidGeometry.Union(block1, block2); /// /// // Create capsule from two spheres and a cylinder. /// const float capsuleHeight = 4; /// const float capsuleRadius = 0.5f; /// /// Vector3 capsuleBodyTop = new Vector3(0, 0, capsuleHeight / 2 - capsuleRadius); /// Vector3 capsuleBodyBottom = new Vector3(0, 0, -(capsuleHeight / 2 - capsuleRadius)); /// /// Solid topCap = Solid.Sphere(capsuleBodyTop, capsuleRadius); /// Solid bottomCap = Solid.Sphere(capsuleBodyBottom, capsuleRadius); /// Solid capsuleBody = Solid.Cylinder(capsuleBodyBottom, capsuleBodyTop, capsuleRadius); /// /// Solid capsule = /// ConstructiveSolidGeometry.Union(topCap, ConstructiveSolidGeometry.Union(capsuleBody, bottomCap)); /// </code> /// </example> /// <param name="a">First solid.</param> /// <param name="b">Second solid.</param> /// <returns>Result of union.</returns> public static Solid Union(Solid a, Solid b) { // Initialize BSP trees. Node aNode = new Node(a.Polygons); Node bNode = new Node(b.Polygons); aNode.ClipTo(bNode); // Remove B geometry from A. bNode.ClipTo(aNode); // Remove A geometry from B. bNode.Invert(); // Invert B, so we can deal with coplanar intersections. bNode.ClipTo(aNode); // Remove coplanars from B. bNode.Invert(); // Invert B back into original form. aNode.Build(bNode.AllPolygons); // Rebuild A to incorporate geometry from B. return new Solid(aNode.AllPolygons); }
/// <summary> /// Creates a simple swept solid. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="element">The element.</param> /// <param name="solid">The solid.</param> /// <param name="normal">The normal of the plane that the path lies on.</param> /// <returns>The swept solid representation handle.</returns> public static IFCAnyHandle CreateSimpleSweptSolid(ExporterIFC exporterIFC, Element element, Solid solid, XYZ normal) { try { if (element == null || element.Document == null) return null; SimpleSweptSolidAnalyzer sweptAnalyzer = SimpleSweptSolidAnalyzer.Create(element.Document.Application.Create, solid, normal); if (sweptAnalyzer != null) { // TODO: support openings and recess for a swept solid if (sweptAnalyzer.UnalignedFaces != null && sweptAnalyzer.UnalignedFaces.Count > 0) return null; IList<GeometryUtil.FaceBoundaryType> faceBoundaryTypes; IList<CurveLoop> faceBoundaries = GeometryUtil.GetFaceBoundaries(sweptAnalyzer.ProfileFace, null, out faceBoundaryTypes); string profileName = null; if (element != null) { ElementType type = element.Document.GetElement(element.GetTypeId()) as ElementType; if (type != null) profileName = type.Name; } return CreateSimpleSweptSolid(exporterIFC, profileName, faceBoundaries, normal, sweptAnalyzer.PathCurve); } } catch (Exception) { return null; } return null; }
/// <summary> /// Find the inforamtion of the swept profile(face), /// and store the points and edges of the profile(face) /// </summary> /// <param name="solid">the solid reference</param> /// <returns>true if the swept profile can be gotten, otherwise false</returns> private bool GetSweptProfile(Solid solid) { // get the swept face Face sweptFace = GetSweptProfileFace(solid); // do some checks if (null == sweptFace || 1 != sweptFace.EdgeLoops.Size) { return false; } // get the points of the swept face foreach (Autodesk.Revit.DB.XYZ point in sweptFace.Triangulate().Vertices) { m_points.Add(Transform(point)); } // get the edges of the swept face m_edges = ChangeEdgeToLine(sweptFace.EdgeLoops.get_Item(0)); // do some checks return (null != m_edges); }
private void Stream(ArrayList data, Solid solid) { data.Add(new Snoop.Data.ClassSeparator(typeof(Solid))); data.Add(new Snoop.Data.Enumerable("Edges", solid.Edges)); data.Add(new Snoop.Data.Enumerable("Faces", solid.Faces)); data.Add(new Snoop.Data.Double("Surface area", solid.SurfaceArea)); data.Add(new Snoop.Data.Double("Volume", solid.Volume)); }
/// <summary> /// constructor /// </summary> /// <param name="element">the host object, must be family instance</param> /// <param name="geoOptions">the geometry option</param> public GeometrySupport(FamilyInstance element, Options geoOptions) { // get the geometry element of the selected element Autodesk.Revit.DB.GeometryElement geoElement = element.get_Geometry(new Options()); if (null == geoElement || 0 == geoElement.Objects.Size) { throw new Exception("Can't get the geometry of selected element."); } AnalyticalModel aModel = element.GetAnalyticalModel(); if (aModel == null) { throw new Exception("The selected FamilyInstance don't have AnalyticalModel."); } AnalyticalModelSweptProfile swProfile = aModel.GetSweptProfile(); if (swProfile == null || !(swProfile.GetDrivingCurve() is Line)) { throw new Exception("The selected element driving curve is not a line."); } // get the driving path and vector of the beam or column Line line = swProfile.GetDrivingCurve() as Line; if (null != line) { m_drivingLine = line; // driving path m_drivingVector = GeomUtil.SubXYZ(line.get_EndPoint(1), line.get_EndPoint(0)); } //get the geometry object foreach (GeometryObject geoObject in geoElement.Objects) { //get the geometry instance which contain the geometry information GeoInstance instance = geoObject as GeoInstance; if (null != instance) { foreach (GeometryObject o in instance.SymbolGeometry.Objects) { // get the solid of beam of column Solid solid = o as Solid; // do some checks. if (null == solid) { continue; } if (0 == solid.Faces.Size || 0 == solid.Edges.Size) { continue; } m_solid = solid; //get the transform value of instance m_transform = instance.Transform; // Get the swept profile curves information if (!GetSweptProfile(solid)) { throw new Exception("Can't get the swept profile curves."); } break; } } } // do some checks about profile curves information if (null == m_edges) { throw new Exception("Can't get the geometry edge information."); } if (4 != m_points.Count) { throw new Exception("The sample only work for rectangular beams or columns."); } }
/// <summary> /// Execute a Boolean operation, and catch the exception. /// </summary> /// <param name="id">The id of the object demanding the Boolean operation.</param> /// <param name="secondId">The id of the object providing the second solid.</param> /// <param name="firstSolid">The first solid parameter to ExecuteBooleanOperation.</param> /// <param name="secondSolid">The second solid parameter to ExecuteBooleanOperation.</param> /// <param name="opType">The Boolean operation type.</param> /// <returns>The result of the Boolean operation, or the first solid if the operation fails.</returns> public static Solid ExecuteSafeBooleanOperation(int id, int secondId, Solid firstSolid, Solid secondSolid, BooleanOperationsType opType) { if (firstSolid == null || secondSolid == null) { if (firstSolid == null && secondSolid == null) return null; if (opType == BooleanOperationsType.Union) { if (firstSolid == null) return secondSolid; return firstSolid; } if (opType == BooleanOperationsType.Difference) { if (firstSolid == null) return null; return firstSolid; } // for .Intersect return null; } Solid resultSolid = null; try { resultSolid = BooleanOperationsUtils.ExecuteBooleanOperation(firstSolid, secondSolid, opType); } catch (Exception ex) { IFCImportFile.TheLog.LogError(id, ex.Message, false); resultSolid = firstSolid; } if (SolidValidator.IsValidGeometry(resultSolid)) return resultSolid; IFCImportFile.TheLog.LogError(id, opType.ToString() + " operation failed with void from #" + secondId.ToString(), false); return firstSolid; }
/// <summary> /// Creates an opening from a solid. /// </summary> /// <param name="exporterIFC">The exporter.</param> /// <param name="hostObjHnd">The host object handle.</param> /// <param name="hostElement">The host element.</param> /// <param name="insertElement">The insert element.</param> /// <param name="openingGUID">The GUID for the opening, depending on how the opening is created.</param> /// <param name="solid">The solid.</param> /// <param name="scaledHostWidth">The scaled host width.</param> /// <param name="isRecess">True if it is recess.</param> /// <param name="extrusionCreationData">The extrusion creation data.</param> /// <param name="setter">The placement setter.</param> /// <param name="localWrapper">The product wrapper.</param> /// <returns>The created opening handle.</returns> static public IFCAnyHandle CreateOpening(ExporterIFC exporterIFC, IFCAnyHandle hostObjHnd, Element hostElement, Element insertElement, string openingGUID, Solid solid, double scaledHostWidth, bool isRecess, IFCExtrusionCreationData extrusionCreationData, PlacementSetter setter, ProductWrapper localWrapper) { IFCFile file = exporterIFC.GetFile(); ElementId catId = CategoryUtil.GetSafeCategoryId(insertElement); XYZ prepToWall; bool isLinearWall = GetOpeningDirection(hostElement, out prepToWall); if (isLinearWall) { extrusionCreationData.CustomAxis = prepToWall; extrusionCreationData.PossibleExtrusionAxes = IFCExtrusionAxes.TryCustom; } BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); BodyData bodyData = BodyExporter.ExportBody(exporterIFC, insertElement, catId, ElementId.InvalidElementId, solid, bodyExporterOptions, extrusionCreationData); IFCAnyHandle openingRepHnd = bodyData.RepresentationHnd; if (IFCAnyHandleUtil.IsNullOrHasNoValue(openingRepHnd)) { extrusionCreationData.ClearOpenings(); return null; } IList<IFCAnyHandle> representations = new List<IFCAnyHandle>(); representations.Add(openingRepHnd); IFCAnyHandle prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); IFCAnyHandle openingPlacement = extrusionCreationData.GetLocalPlacement(); IFCAnyHandle hostObjPlacementHnd = IFCAnyHandleUtil.GetObjectPlacement(hostObjHnd); Transform relTransform = ExporterIFCUtils.GetRelativeLocalPlacementOffsetTransform(openingPlacement, hostObjPlacementHnd); openingPlacement = ExporterUtil.CreateLocalPlacement(file, hostObjPlacementHnd, relTransform.Origin, relTransform.BasisZ, relTransform.BasisX); IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); double scaledOpeningLength = extrusionCreationData.ScaledLength; string openingObjectType = "Opening"; if (!MathUtil.IsAlmostZero(scaledHostWidth) && !MathUtil.IsAlmostZero(scaledOpeningLength)) openingObjectType = scaledOpeningLength < (scaledHostWidth - MathUtil.Eps()) ? "Recess" : "Opening"; else openingObjectType = isRecess ? "Recess" : "Opening"; string openingName = NamingUtil.GetNameOverride(insertElement, null); if (string.IsNullOrEmpty(openingName)) { if (!IFCAnyHandleUtil.IsNullOrHasNoValue(hostObjHnd)) openingName = IFCAnyHandleUtil.GetStringAttribute(hostObjHnd, "Name"); else openingName = NamingUtil.GetNameOverride(hostElement, NamingUtil.CreateIFCObjectName(exporterIFC, hostElement)); } IFCAnyHandle openingHnd = IFCInstanceExporter.CreateOpeningElement(file, openingGUID, ownerHistory, openingName, null, openingObjectType, openingPlacement, prodRep, null); if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities) PropertyUtil.CreateOpeningQuantities(exporterIFC, openingHnd, extrusionCreationData); if (localWrapper != null) { Element elementForProperties = null; if (GUIDUtil.IsGUIDFor(insertElement, openingGUID)) elementForProperties = insertElement; localWrapper.AddElement(insertElement, openingHnd, setter, extrusionCreationData, true); } string voidGuid = GUIDUtil.CreateGUID(); IFCInstanceExporter.CreateRelVoidsElement(file, voidGuid, ownerHistory, null, null, hostObjHnd, openingHnd); return openingHnd; }
/// <summary> /// Checks if a Solid is valid for use in a generic DirectShape or DirecShapeType. /// </summary> /// <param name="solid"></param> /// <returns></returns> public static bool ValidateGeometry(Solid solid) { return SolidValidator.IsValidGeometry(solid); }
/// <summary> /// Return the uppermost horizontal face /// of a given "horizontal" solid object /// such as a floor slab. Currently only /// supports planar faces. /// </summary> PlanarFace GetTopFace( Solid solid ) { PlanarFace topFace = null; FaceArray faces = solid.Faces; foreach( Face f in faces ) { PlanarFace pf = f as PlanarFace; if( null != pf && Util.IsHorizontal( pf ) ) { if( ( null == topFace ) || ( topFace.Origin.Z < pf.Origin.Z ) ) { topFace = pf; } } } return topFace; }
/// <summary> /// Boolean intersect geometric operation, return a new solid as the result /// </summary> /// <param name="solid1">Operation solid 1</param> /// <param name="solid2">Operation solid 2</param> /// <returns>The operation result</returns> public static Solid BooleanOperation_Intersect(Solid solid1, Solid solid2) { return(BooleanOperationsUtils.ExecuteBooleanOperation(solid1, solid2, BooleanOperationsType.Intersect)); }
/// <summary> /// Determine the boundary polygons of the lowest /// horizontal planar face of the given solid. /// </summary> /// <param name="polygons">Return polygonal boundary /// loops of lowest horizontal face, i.e. profile of /// circumference and holes</param> /// <param name="solid">Input solid</param> /// <returns>False if no horizontal planar face was /// found, else true</returns> static bool GetBoundary( List<List<XYZ>> polygons, Solid solid) { PlanarFace lowest = null; FaceArray faces = solid.Faces; foreach( Face f in faces ) { PlanarFace pf = f as PlanarFace; if( null != pf && Util.IsHorizontal( pf ) ) { if( ( null == lowest ) || ( pf.Origin.Z < lowest.Origin.Z ) ) { lowest = pf; } } } if( null != lowest ) { XYZ p, q = XYZ.Zero; bool first; int i, n; EdgeArrayArray loops = lowest.EdgeLoops; foreach( EdgeArray loop in loops ) { List<XYZ> vertices = new List<XYZ>(); first = true; 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 ) { XYZ v = points[i]; v -= _offset * XYZ.BasisZ; vertices.Add( v ); } } q -= _offset * XYZ.BasisZ; Debug.Assert( q.IsAlmostEqualTo( vertices[0] ), "expected last end point to equal" + " first start point" ); polygons.Add( vertices ); } } return null != lowest; }
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication app = commandData.Application; UIDocument uidoc = app.ActiveUIDocument; Document doc = uidoc.Document; Selection sel = uidoc.Selection; Element column = null; if (1 == sel.GetElementIds().Count) { foreach (Element e in sel.Elements) { column = e; } if (!IsColumn(column)) { column = null; } } if (null == column) { #if _2010 sel.Elements.Clear(); sel.StatusbarTip = "Please select a column"; if (sel.PickOne()) { ElementSetIterator i = sel.Elements.ForwardIterator(); i.MoveNext(); column = i.Current as Element; } #endif // _2010 Reference r = uidoc.Selection.PickObject(ObjectType.Element, "Please select a column"); if (null != r) { // 'Autodesk.Revit.DB.Reference.Element' is // obsolete: Property will be removed. Use // Document.GetElement(Reference) instead. //column = r.Element; // 2011 column = doc.GetElement(r); // 2012 if (!IsColumn(column)) { message = "Please select a single column instance"; } } } if (null != column) { Options opt = app.Application.Create.NewGeometryOptions(); GeometryElement geo = column.get_Geometry(opt); GeometryInstance i = null; //GeometryObjectArray objects = geo.Objects; // 2012 //foreach( GeometryObject obj in objects ) // 2012 foreach (GeometryObject obj in geo) // 2013 { i = obj as GeometryInstance; if (null != i) { break; } } if (null == i) { message = "Unable to obtain geometry instance"; } else { bool isCylindrical = false; geo = i.SymbolGeometry; //objects = geo.Objects; // 2012 //foreach( GeometryObject obj in objects ) // 2012 foreach (GeometryObject obj in geo) { Solid solid = obj as Solid; if (null != solid) { foreach (Face face in solid.Faces) { if (face is CylindricalFace) { isCylindrical = true; break; } } } } message = string.Format( "Selected column instance is{0} cylindrical", (isCylindrical ? "" : " NOT")); } } return(Result.Failed); }
/// <summary> /// Splits a Solid into distinct volumes. /// </summary> /// <param name="solid">The initial solid.</param> /// <returns>The list of volumes.</returns> /// <remarks>This calls the internal SolidUtils.SplitVolumes routine, but does additional cleanup work to properly dispose of stale data.</remarks> public static IList<Solid> SplitVolumes(Solid solid) { IList<Solid> splitVolumes = SolidUtils.SplitVolumes(solid); foreach (Solid currSolid in splitVolumes) { // The geometry element created by SplitVolumes is a copy which will have its own allocated // membership - this needs to be stored and disposed of (see AllocatedGeometryObjectCache // for details) ExporterCacheManager.AllocatedGeometryObjectCache.AddGeometryObject(currSolid); } return splitVolumes; }
/// <summary> /// Scan Solid to collect triangles. /// </summary> /// <param name="solid">The solid.</param> /// <param name="trf">The transformation.</param> private void ScanSolid(Document document, Solid solid, Transform transform) { GetTriangular(document, solid, transform); // get triangles in the solid }
/// <summary> /// Creates a list of meshes out a solid by triangulating the faces. /// </summary> /// <param name="solid">The original solid.</param> /// <returns>A list of meshes created from the triangulation of the solid's faces.</returns> public static IList<GeometryObject> CreateMeshesFromSolid(Solid solid) { IList<GeometryObject> triangulations = new List<GeometryObject>(); foreach (Face face in solid.Faces) { Mesh faceMesh = face.Triangulate(); if (faceMesh != null && faceMesh.NumTriangles > 0) triangulations.Add(faceMesh); } return triangulations; }
/// <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 = 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); } } }
/// <summary> /// Appends a given Solid to the solidsList. /// </summary> /// <param name="geomElem"> /// The Solid we are appending to the solidsList. /// </param> public void AddSolid(Solid solidToAdd) { solidsList.Add(solidToAdd); }
public Autodesk.Revit.UI.Result Execute(ExternalCommandData revit, ref string message, ElementSet elements) { //get document UIDocument uiDoc = revit.Application.ActiveUIDocument; Document doc = uiDoc.Document; //work with host file List <Element> tableElments = getAllTablesDataNotLinked(revit); List <ResultClass> resultList = new List <ResultClass>(); List <string> resultsStrings = new List <string>(); //get relevet face turn to solid and get intersecting elements. foreach (Element el in tableElments) { List <Solid> geometrySolidsList = getSolidsListOfElement(revit, el); Solid largestSolid = LargestSolidElement(geometrySolidsList); FaceArray faces = largestSolid.Faces; PlanarFace topFace = TopFaceOriantasion(faces); Solid preTransformSolid = GeometryCreationUtilities.CreateExtrusionGeometry(topFace.GetEdgesAsCurveLoops(), topFace.FaceNormal, 1); var tableFamilyInstance = el as FamilyInstance; Solid solid = SolidUtils.CreateTransformed(preTransformSolid, tableFamilyInstance.GetTransform()); PaintSolid(doc, solid, 1); List <Element> temIntersectingList = getIntersectingSolidElements(solid, uiDoc, doc); List <string> itersectingElms = new List <string>(); //if intersecting elements "write them". if (temIntersectingList.Any()) { foreach (Element intsecEl in temIntersectingList) { itersectingElms.Add(intsecEl.Name); } } //create a result class with all properties. ResultClass resClass = new ResultClass(Int32.Parse(el.Id.ToString()), el.Document.Title, itersectingElms.Any(), itersectingElms); resultsStrings.Add(resClass.instancePrint()); } string finalMessage = ""; foreach (string str in resultsStrings) { finalMessage += str + Environment.NewLine; } //show results. TaskDialog.Show("revit", finalMessage + Environment.NewLine + "Done in host model"); //work with linked doc. List <Element> linkedTables = getLinkedDocFurniture(doc); List <string> linkedResultsStrings = new List <string>(); var linkedTransformed = new FilteredElementCollector(doc).OfClass(typeof(RevitLinkInstance)) .Select(lm => { var linkedModel = ((RevitLinkInstance)lm); return(linkedModel.GetTransform()); }) .FirstOrDefault(); //get relevet face turn to solid and get intersecting elements. foreach (Element el in linkedTables) { List <Solid> geometrySolidsList = getSolidsListOfElement(revit, el); Solid largestSolid = LargestSolidElement(geometrySolidsList); FaceArray faces = largestSolid.Faces; PlanarFace topFace = TopFaceOriantasion(faces); Solid preTransformSolid = GeometryCreationUtilities.CreateExtrusionGeometry( topFace.GetEdgesAsCurveLoops(), topFace.FaceNormal, 1); var tableInstance = el as FamilyInstance; var testSome = el as Instance; Solid customTransformedSolid = TransformSolid(tableInstance.GetTransform(), linkedTransformed, preTransformSolid); PaintSolid(doc, customTransformedSolid, 1); List <Element> interSectsInLinked = getIntersectingSolidElements(customTransformedSolid, uiDoc, doc); List <string> linkedItersectingElms = new List <string>(); if (interSectsInLinked.Any()) { foreach (Element intsecEl in interSectsInLinked) { linkedItersectingElms.Add(intsecEl.Name); } } ResultClass resClass = new ResultClass(Int32.Parse(el.Id.ToString()), el.Document.Title, interSectsInLinked.Any(), linkedItersectingElms); linkedResultsStrings.Add(resClass.instancePrint()); } string linkeFinalMessage = ""; foreach (string str in linkedResultsStrings) { linkeFinalMessage += str + Environment.NewLine; } TaskDialog.Show("revit", linkeFinalMessage + Environment.NewLine + "Done in linked model"); return(Autodesk.Revit.UI.Result.Succeeded); }