Client/Desktop/KMBIM3.0/23.11.03/Cmd/Z_TEST/Util.cs

725 lines
21 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WinForms = System.Windows.Forms;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using System.Diagnostics;
using System.IO;
using Autodesk.Revit.Creation;
using Microsoft.Win32;
namespace COME4Revit
{
class Util
{
//레지스트리 가져오기
public static string getReg(string regKey)
{
RegistryKey reg = Registry.CurrentUser;
reg = reg.OpenSubKey("Software\\DCS_COME\\CO-ME4Revit\\1.0", true);
if (reg == null)
return "";
else
return Convert.ToString(reg.GetValue(regKey));
}
//레지스트리 쓰기
public static void setReg(string regKey, string regVal)
{
RegistryKey reg = Registry.CurrentUser;
reg = reg.CreateSubKey("Software\\DCS_COME\\CO-ME4Revit\\1.0", RegistryKeyPermissionCheck.ReadWriteSubTree);
reg.SetValue(regKey, regVal, RegistryValueKind.String);
reg.Close();
}
// predefined constants for common angles
public const double kPi = 3.14159265358979323846;
// TBD: have to use Revit's version of Pi for Ellipse else it will fail!
public const double kRevitPi = 3.14159265358979;
public const double kHalfPi = 3.14159265358979323846 / 2.0;
public const double kTwoPi = 3.14159265358979323846 * 2.0;
public const double kRad0 = 0.0;
public const double kRad45 = 3.14159265358979323846 / 4.0;
public const double kRad90 = 3.14159265358979323846 / 2.0;
public const double kRad135 = (3.14159265358979323846 * 3.0) / 4.0;
public const double kRad180 = 3.14159265358979323846;
public const double kRad270 = 3.14159265358979323846 * 1.5;
public const double kRad360 = 3.14159265358979323846 * 2.0;
public static double
RTD(double rads)
{
return rads * (180.0 / kPi);
}
public static double
DTR(double degrees)
{
return degrees * (kPi / 180.0);
}
public static XYZ GetMidPoint(XYZ pt1, XYZ pt2)
{
XYZ ptMid = pt1 + (pt2 - pt1) * 0.5;
return ptMid;
}
public static XYZ GetMiddlePointOfCurve(Curve curve)
{
return curve.Evaluate(0.5, true);
}
public static XYZ GetCurvesIntersectionPoint(Curve line1, Curve line2)
{
IntersectionResultArray resultArray = null;
line1.Intersect(line2, out resultArray);
if (resultArray != null)
{
foreach (IntersectionResult result in resultArray)
{
if (result.XYZPoint != null)
{
return result.XYZPoint;
}
}
}
return null;
}
public static XYZ GetPointOnLine(Curve line, XYZ point)
{
XYZ xYZPoint = null;
IntersectionResult result = line.Project(point);
if ((result != null) && (result.XYZPoint != null))
{
xYZPoint = result.XYZPoint;
}
return xYZPoint;
}
/// <summary>
/// 파이프의 시작점 끝점을 넘겨준다.
/// </summary>
/// <param name="pipe"></param>
/// <param name="startPoint"></param>
/// <param name="endPoint"></param>
/// <returns></returns>
public static bool GetStartEndPoint(Autodesk.Revit.DB.Plumbing.Pipe pipe, ref XYZ startPoint, ref XYZ endPoint)
{
bool bRC = false;
if (pipe == null) return bRC;
LocationCurve lc = pipe.Location as LocationCurve;
bRC = GetStartEndPoint(lc, ref startPoint, ref endPoint);
return bRC;
}
/// <summary>
/// 커브의 시작점과 끝점을 넘겨준다.
/// </summary>
/// <param name="lc"></param>
/// <param name="startPoint"></param>
/// <param name="endPoint"></param>
/// <returns></returns>
public static bool GetStartEndPoint(LocationCurve lc, ref XYZ startPoint, ref XYZ endPoint)
{
bool bRC = false;
if (lc != null)
{
startPoint = lc.Curve.GetEndPoint(0);
endPoint = lc.Curve.GetEndPoint(1);
bRC = true;
}
return bRC;
}
/// <summary>
/// 한 점에서 평면에 가장 가까운 점을 구한다.
/// </summary>
/// <param name="plane">평면</param>
/// <param name="p">한 점</param>
/// <returns></returns>
public static XYZ PlaneProject(Plane plane, XYZ p )
{
// signedDistanceTo( p );
double[,] xform = new double[3, 3];
XYZ normal=plane.Normal;
xform[0,0] = 1.0 - normal.X * normal.X;
xform[0,1] = -normal.X * normal.Y;
xform[0,2] = -normal.X * normal.Z;
xform[1,0] = -normal.Y * normal.X;
xform[1,1] = 1.0 - normal.Y * normal.Y;
xform[1,2] = -normal.Y * normal.Z;
xform[2,0] = -normal.Z * normal.X;
xform[2,1] = -normal.Z * normal.Y;
xform[2,2] = 1.0 - normal.Z * normal.Z;
double[] ptTmp = new double[3];
for (int iRow = 0; iRow < 3; iRow++)
{
ptTmp[iRow] =
xform[iRow, 0] * p[0] +
xform[iRow, 1] * p[1] +
xform[iRow, 2] * p[2];
}
return new XYZ(ptTmp[0], ptTmp[1], ptTmp[2]);
}
public static ModelArc NewModelArc(UIApplication app, SketchPlane plane, Autodesk.Revit.DB.XYZ ptE1, Autodesk.Revit.DB.XYZ ptE2, Autodesk.Revit.DB.XYZ ptOnCurve)
{
ModelArc arc = null;
try
{
Autodesk.Revit.Creation.Application creApp = app.Application.Create;
Arc line = Arc.Create(ptE1, ptE2, ptOnCurve);
arc= (ModelArc)app.ActiveUIDocument.Document.Create.NewModelCurve(line, plane);
}
catch (Exception)
{
}
return arc;
}
public static DetailCurve NewDetailLine(UIApplication app, Autodesk.Revit.DB.XYZ startPoint, Autodesk.Revit.DB.XYZ endPoint)
{
try
{
Autodesk.Revit.DB.Document doc = app.ActiveUIDocument.Document;
View view = doc.ActiveView;
Autodesk.Revit.Creation.Application creApp = app.Application.Create;
XYZ sp = PlaneProject(view.SketchPlane.GetPlane(), startPoint);
XYZ ep = PlaneProject(view.SketchPlane.GetPlane(), endPoint);
Line line = Line.CreateBound(sp, ep);
return doc.Create.NewDetailCurve(view, line);
}
catch (Exception ex)
{
string strMsg = ex.Message;
return null;
}
}
#region Geometrical Comparison
const double _eps = 1.0e-9;
public static double Eps
{
get
{
return _eps;
}
}
public static double MinLineLength
{
get
{
return _eps;
}
}
public static double TolPointOnPlane
{
get
{
return _eps;
}
}
public static bool IsZero(double a, double tolerance)
{
return tolerance > Math.Abs(a);
}
public static bool IsZero(double a)
{
return IsZero(a, _eps);
}
public static bool IsEqual(double a, double b)
{
return IsZero(b - a);
}
public static int Compare(double a, double b)
{
return IsEqual(a, b) ? 0 : (a < b ? -1 : 1);
}
public static int Compare(XYZ p, XYZ q)
{
int diff = Compare(p.X, q.X);
if (0 == diff)
{
diff = Compare(p.Y, q.Y);
if (0 == diff)
{
diff = Compare(p.Z, q.Z);
}
}
return diff;
}
public static bool IsHorizontal(XYZ v)
{
return IsZero(v.Z);
}
public static bool IsVertical(XYZ v)
{
return IsZero(v.X) && IsZero(v.Y);
}
public static bool IsVertical(XYZ v, double tolerance)
{
return IsZero(v.X, tolerance)
&& IsZero(v.Y, tolerance);
}
public static bool IsHorizontal(Edge e)
{
XYZ p = e.Evaluate(0);
XYZ q = e.Evaluate(1);
return IsHorizontal(q - p);
}
public static bool IsVertical(CylindricalFace f)
{
return IsVertical(f.Axis);
}
/// <summary>
/// Return the maximum value from an array of real numbers.
/// </summary>
public static double Max(double[] a)
{
Debug.Assert(1 == a.Rank, "expected one-dimensional array");
Debug.Assert(0 == a.GetLowerBound(0), "expected zero-based array");
Debug.Assert(0 < a.GetUpperBound(0), "expected non-empty array");
double max = a[0];
for (int i = 1; i <= a.GetUpperBound(0); ++i)
{
if (max < a[i])
{
max = a[i];
}
}
return max;
}
#endregion // Geometrical Comparison
#region Unit Handling
const double _convertFootToMm = 12 * 25.4;
const double _convertFootToMeter
= _convertFootToMm * 0.001;
const double _convertCubicFootToCubicMeter
= _convertFootToMeter
* _convertFootToMeter
* _convertFootToMeter;
/// <summary>
/// Convert a given length in feet to millimetres.
/// </summary>
public static double FootToMm(double length)
{
return length * _convertFootToMm;
}
/// <summary>
/// Convert a given length in millimetres to feet.
/// </summary>
public static double MmToFoot(double length)
{
return length / _convertFootToMm;
}
/// <summary>
/// Convert a given volume in feet to cubic meters.
/// </summary>
public static double CubicFootToCubicMeter(double volume)
{
return volume * _convertCubicFootToCubicMeter;
}
#endregion // Unit Handling
#region Formatting
/// <summary>
/// Return an English plural suffix 's' or
/// nothing for the given number of items.
/// </summary>
public static string PluralSuffix(int n)
{
return 1 == n ? "" : "s";
}
/// <summary>
/// Return an English plural suffix 'ies' or
/// 'y' for the given number of items.
/// </summary>
public static string PluralSuffixY(int n)
{
return 1 == n ? "y" : "ies";
}
public static string DotOrColon(int n)
{
return 0 < n ? ":" : ".";
}
public static string RealString(double a)
{
return a.ToString("0.##");
}
public static string AngleString(double angle)
{
return RealString(angle * 180 / Math.PI) + " degrees";
}
public static string MmString(double length)
{
return RealString(FootToMm(length)) + " mm";
}
public static string PointString(UV p)
{
return string.Format("({0},{1})",
RealString(p.U),
RealString(p.V));
}
public static string PointString(XYZ p)
{
return string.Format("({0},{1},{2})",
RealString(p.X),
RealString(p.Y),
RealString(p.Z));
}
public static string PlaneString(Plane p)
{
return string.Format("plane origin {0}, plane normal {1}",
PointString(p.Origin),
PointString(p.Normal));
}
public static string TransformString(Transform t)
{
return string.Format("({0},{1},{2},{3})", PointString(t.Origin),
PointString(t.BasisX), PointString(t.BasisY), PointString(t.BasisZ));
}
public static string PointArrayString(IList<XYZ> pts)
{
string s = string.Empty;
foreach (XYZ p in pts)
{
if (0 < s.Length)
{
s += ", ";
}
s += PointString(p);
}
return s;
}
public static string CurveString(Curve curve)
{
return "curve tesselation " + PointArrayString(curve.Tessellate());
}
#endregion // Formatting
#region Display a message
const string _caption = "DCS Tools";
public static void InfoMsg(string msg)
{
Debug.WriteLine(msg);
WinForms.MessageBox.Show(msg,
_caption,
WinForms.MessageBoxButtons.OK,
WinForms.MessageBoxIcon.Information);
}
public static void ErrorMsg(string msg)
{
Debug.WriteLine(msg);
WinForms.MessageBox.Show(msg,
_caption,
WinForms.MessageBoxButtons.OK,
WinForms.MessageBoxIcon.Error);
}
public static string ElementDescription(Element e)
{
if (null == e)
{
return "<null>";
}
// for a wall, the element name equals the
// wall type name, which is equivalent to the
// family name ...
FamilyInstance fi = e as FamilyInstance;
string fn = (null == fi)
? string.Empty
: fi.Symbol.Family.Name + " ";
string cn = (null == e.Category)
? e.GetType().Name
: e.Category.Name;
return string.Format("{0} {1}<{2} {3}>",
cn, fn, e.Id.IntegerValue, e.Name);
}
#endregion // Display a message
public static Element GetElement(Autodesk.Revit.DB.Document document, int id)
{
ElementId id2 = new ElementId(id);
return document.GetElement(id2);
}
public static Element GetElement(ExternalCommandData commandData, int id)
{
ElementId id2 = new ElementId(id);
return commandData.Application.ActiveUIDocument.Document.GetElement(id2);
}
public static XYZ GetCurveNormal(Curve curve)
{
IList<XYZ> pts = curve.Tessellate();
int n = pts.Count;
Debug.Assert(1 < n,
"expected at least two points "
+ "from curve tessellation");
XYZ p = pts[0];
XYZ q = pts[n - 1];
XYZ v = q - p;
XYZ w, normal = null;
if (2 == n)
{
Debug.Assert(curve is Line,
"expected non-line element to have "
+ "more than two tessellation points");
// for non-vertical lines, use Z axis to
// span the plane, otherwise Y axis:
double dxy = Math.Abs(v.X) + Math.Abs(v.Y);
w = (dxy > Util.TolPointOnPlane)
? XYZ.BasisZ
: XYZ.BasisY;
normal = v.CrossProduct(w).Normalize();
}
else
{
int i = 0;
while (++i < n - 1)
{
w = pts[i] - p;
normal = v.CrossProduct(w);
if (!normal.IsZeroLength())
{
normal = normal.Normalize();
break;
}
}
#if DEBUG
{
XYZ normal2;
while (++i < n - 1)
{
w = pts[i] - p;
normal2 = v.CrossProduct(w);
Debug.Assert(normal2.IsZeroLength()
|| Util.IsZero(normal2.AngleTo(normal)),
"expected all points of curve to "
+ "lie in same plane");
}
}
#endif // DEBUG
}
return normal;
}
public static Element SelectSingleElement(
UIDocument doc,
string description)
{
Selection sel = doc.Selection;
Reference r = null;
try
{
r = sel.PickObject(ObjectType.Element, description);
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
r = null;
}
return null == r ? null : doc.Document.GetElement(r);
}
static bool HasRequestedType(
Element e,
Type t,
bool acceptDerivedClass)
{
return (null != e)
&& (acceptDerivedClass
? e.GetType().IsSubclassOf(t)
: e.GetType().Equals(t));
}
public static string GetFileName(string fileName, string subFolder, bool deleteIfExist)
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\" + "DCS.CO.KR" + @"\" + "CO-ME4Revit" + @"\" + subFolder;
if (!Directory.Exists(path))
{
string[] strArray = path.Split(new char[] { '\\' });
string str2 = "";
str2 = str2 + strArray[0];
for (int i = 1; i <= (strArray.Length - 1); i++)
{
str2 = str2 + @"\" + strArray[i];
if (!Directory.Exists(str2))
{
Directory.CreateDirectory(str2);
}
}
}
string str3 = path + @"\" + fileName;
if (File.Exists(str3) && deleteIfExist)
{
File.Delete(str3);
}
return str3;
}
public static double GetSignedPolygonArea(List<UV> p)
{
int n = p.Count;
int j = 0;
double sum = 0;
for (int i = 0; i < n ; i++)
{
j = (i + 1) % n;
sum += (p[i].U * p[j].V - p[j].U * p[i].V);
}
return 0.5 * sum;
}
public static UV GetSignedPolygonCenter(List<UV> p)
{
int n = p.Count;
int j = 0;
double centerx = 0;
double centery = 0;
for (int i = 0; i < n ; i++)
{
j = (i + 1) % n;
centerx += ((p[i].U + p[j].U) * ((p[i].U * p[j].V) - (p[j].U * p[i].V)));
centery += ((p[i].V + p[j].V) * ((p[i].U * p[j].V) - (p[j].U * p[i].V)));
}
UV center = new UV(centerx, centery);
return center;
}
public static bool PickPoint(UIDocument uidoc, string msg, ref XYZ pt)
{
bool bRC=false;
try
{
pt = uidoc.Selection.PickPoint(msg);
bRC = true;
}
catch (OperationCanceledException)
{
}
catch (Exception)
{
}
catch
{
}
return bRC;
}
/// <summary>
/// 주어진 점들로 이루어진 폴리곤의 면적을 넘겨준다.
/// </summary>
/// <param name="pts">폴리곤 점들</param>
/// <param name="dut">표시 단위</param>
/// <returns></returns>
public static double GetArea(List<XYZ> pts, DisplayUnitType dut)
{
List<UV> lstUV = new List<UV>();
foreach (XYZ curPt in pts)
{
lstUV.Add(new UV(curPt.X, curPt.Y));
}
lstUV.Add(new UV(pts[0].X, pts[1].Y));
// dut = DisplayUnitType.DUT_SQUARE_METERS
double area = Unit.CovertFromAPI(dut, Util.GetSignedPolygonArea(lstUV));
return area;
}
}
}