using System;
using System.Collections.Generic;
using System.Text;
using Revit = Autodesk.Revit;
using Autodesk.Revit.DB;
using Autodesk.Revit.ApplicationServices;
namespace RevitLookup.Utils {
///
///
///
public class Geometry {
///
/// Given a solid, returns a curve array containing the edges
/// which are visible in plan view
///
/// solid whose plan view edges are needed
/// offset from plane
/// revit application
/// curve array of plan view curves
public static CurveArray
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;
}
///
/// Given an array of edges, weeds out any edges
/// not present on the desired plane
///
/// the array of edges
/// normal to the desired plane
/// edges on the desired plane
public static EdgeArray
GetEdgesOnPlane(EdgeArray edgeArray, XYZ normal)
{
EdgeArray edgesOnPlane = new EdgeArray();
for (int i = 0; i < edgeArray.Size; i++) {
IList 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;
}
///
/// Given an array of edges, weeds out any edges
/// not present at the given offset
///
/// the array of edges
/// normal to the desired plane
/// offset from the plane
/// edges on a plane at given offset
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 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;
}
///
/// Given an edge Array converts it to a curveArray
///
/// edgeArray to convert
/// curveArray to fill
/// a curveArray
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.get_Bound(startPt, endPt);
curveArray.Append(curve);
}
return curveArray;
}
///
/// Given a curve, mirrors it along the given axis
///
/// curve to mirror
/// axis to mirror along
/// revit application
/// a mirrored curve
public static Curve
Mirror(Curve curve, XYZ axis, Application app)
{
XYZ startPt = curve.get_EndPoint(0);
XYZ endPt = curve.get_EndPoint(1);
XYZ p = new XYZ();
XYZ newStart = null;
XYZ newEnd = null;
if (axis.Equals(GeomUtils.kXAxis)) {
newStart = new XYZ(startPt.X, -startPt.Y, startPt.Z);
newEnd = new XYZ(endPt.X, -endPt.Y, endPt.Z);
}
if (axis.Equals(GeomUtils.kYAxis)) {
newStart = new XYZ(-startPt.X, startPt.Y, startPt.Z);
newEnd = new XYZ(-endPt.X, -endPt.Y, endPt.Z);
}
if (axis.Equals(GeomUtils.kZAxis)) {
newStart = new XYZ(startPt.X, startPt.Y, -startPt.Z);
newEnd = new XYZ(endPt.X, endPt.Y, -endPt.Z);
}
return app.Create.NewLine(startPt, endPt, true);
}
///
/// Given a point, mirrors it along the given axis
///
/// point to mirror
/// axis to mirror along
/// a mirrored point
public static XYZ
Mirror(XYZ point, XYZ axis)
{
XYZ Point = null;
if (axis.Equals(GeomUtils.kXAxis)) {
Point = new XYZ(point.X, -point.Y, point.Z);
}
if (axis.Equals(GeomUtils.kYAxis)) {
Point = new XYZ(-point.X, point.Y, point.Z);
}
if (axis.Equals(GeomUtils.kZAxis)) {
Point = new XYZ(point.X, point.Y, -point.Z);
}
return Point;
}
///
/// Get the "standard" plane (equiv. to WCS in AutoCAD terms)
///
///
/// A new sketch plane
public static SketchPlane
GetWorldPlane(Autodesk.Revit.UI.UIApplication app)
{
Plane plane = app.Application.Create.NewPlane(GeomUtils.kZAxis, GeomUtils.kOrigin);
SketchPlane sketchPlane = app.ActiveUIDocument.Document.Create.NewSketchPlane(plane);
return sketchPlane;
}
}
}