1523 lines
66 KiB
C#
1523 lines
66 KiB
C#
using System;
|
|
using Autodesk.Revit.UI;
|
|
using Autodesk.Revit.DB;
|
|
using System.Diagnostics;
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
using Autodesk.Revit.Creation;
|
|
using Autodesk.Revit.UI.Selection;
|
|
using Autodesk.Revit.DB.Structure;
|
|
|
|
using System.IO;
|
|
using System.Windows.Forms;
|
|
using Autodesk.Revit.DB.Plumbing;
|
|
using Autodesk.Revit.ApplicationServices;
|
|
using KDCS.Utils;
|
|
using KMBIM.Revit.Tools;
|
|
|
|
namespace KMBIM
|
|
{
|
|
// 커넥터의 좌표를 소트 하라.
|
|
public class DinoComparer : IComparer<Connector>
|
|
{
|
|
public int Compare(Connector a, Connector b)
|
|
{
|
|
double diff = a.Origin.X - b.Origin.X;
|
|
if (Math.Abs(diff) < 0.0001) return 0;
|
|
else if (diff > 0.0001) return 1;
|
|
else if (diff < 0.0001) return -1;
|
|
else return 0;
|
|
|
|
}
|
|
}
|
|
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
|
|
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
|
|
class HeaderSupply : IExternalCommand
|
|
{
|
|
|
|
UIApplication uiapp;
|
|
UIDocument uidoc;
|
|
ExternalCommandData m_revit;
|
|
Autodesk.Revit.DB.Document doc;
|
|
Autodesk.Revit.Creation.Application creApp;
|
|
Autodesk.Revit.Creation.Document creDoc;
|
|
Autodesk.Revit.DB.View view;
|
|
LanguageType lang;
|
|
|
|
public List<KMBIM.HeValue> m_ArrValue = new List<KMBIM.HeValue>();
|
|
public List<KMBIM.HdValue> m_ArrHdValue = new List<KMBIM.HdValue>();
|
|
public List<string> m_ArrDia = new List<string>();
|
|
double hd1; // 사용자가 선택한 메인ㅌ 헤더의 관경
|
|
|
|
Connector outvalveconn = null, trapvalveconn = null;
|
|
double maxdist = 0.0; // 헤더 다리의 최대거리
|
|
double footdia = 0.0; //헤더 다리의 지름
|
|
double flangedia = 0.0; //플랜지의 지름
|
|
double flangelen = 0.0; //플랜지의 길이
|
|
int totalfooter = 0; // 전체 기둥의개수
|
|
double[] hd_loc_dst; // 가지관의 거리를 기억하는 배열
|
|
double hd2; // 해더의 총 길이
|
|
double[] gd_List = new double[10]; // 헤더 지지관의 거리?
|
|
double[] flst = new double[7];
|
|
double m_headHight = 0.0; //헤더 높이
|
|
int gi_ListEA; //헤더 지지다리의 갯수
|
|
int Cntnum = -1;
|
|
Autodesk.Revit.Creation.ItemFactoryBase m_CreationBase;
|
|
XYZ p1 = new XYZ(); // 삽입점
|
|
XYZ p2 = new XYZ(); //방향
|
|
double[] borlst; // 관경리스트
|
|
int ListBoxCnt = -1; // 다이얼로그에서 설정한 관경의 목록의 개수
|
|
int ListBoxCnt2 = -1; // 다이얼로그에서 설정한 관경의 목록의 개수
|
|
public const double PI = 3.14159265358;
|
|
public double ksv = 7.545932; //2300을 pit로 변환해놓은값
|
|
public FamilyInstance PGfamily = null;
|
|
public List<PipingSystemType> SysTypeNameLst = new List<PipingSystemType>();
|
|
|
|
//패밀리 경로
|
|
public string str_BFpath = null, str_Drainpath = null, str_Safepath = null, str_PGpath = null, str_TGpath = null;
|
|
public PipingSystemType pSysType = null;
|
|
public double m_ControlValHgt = 0;
|
|
|
|
public Autodesk.Revit.UI.Result Execute(ExternalCommandData revit,
|
|
ref string message, ElementSet elements)
|
|
{
|
|
if (!WorkMain.GetInstance().IsValid) return Autodesk.Revit.UI.Result.Succeeded;
|
|
uiapp = revit.Application;
|
|
uidoc = uiapp.ActiveUIDocument;
|
|
doc = uidoc.Document;
|
|
m_revit = revit;
|
|
creApp = uiapp.Application.Create;
|
|
creDoc = doc.Create;
|
|
view = doc.ActiveView;
|
|
lang = revit.Application.Application.Language;
|
|
|
|
try
|
|
{
|
|
//파이프 시스템 유형 리스트에 넣기
|
|
List<string> m_pipeSysTypeList = new List<string>();
|
|
ICollection<Element> SysTypeCollection = new FilteredElementCollector(doc).OfClass(typeof(PipingSystemType)).ToElements();
|
|
foreach (Element elem in SysTypeCollection)
|
|
{
|
|
|
|
if (elem is PipingSystemType)
|
|
{
|
|
PipingSystemType pipingSystemType = elem as PipingSystemType;
|
|
m_pipeSysTypeList.Add(pipingSystemType.Name);
|
|
}
|
|
}
|
|
|
|
Form_Supply dlg = new Form_Supply();
|
|
dlg.m_nMode = 2;
|
|
dlg.m_HeadHgt = 800;
|
|
dlg.m_ValHgt = 800;
|
|
dlg.HeaderSysTypeLst = m_pipeSysTypeList;
|
|
dlg.doc = doc;
|
|
//pSysType = dlg.HeaderSysType;
|
|
//dlg.SysTypeNameLst
|
|
|
|
if (dlg.ShowDialog() == DialogResult.OK)
|
|
{
|
|
//MessageBox.Show("" + dlg.m_BFpath + "\n\n" + dlg.m_Drainpath + "\n\n" + dlg.m_Safepath + "\n\n" + dlg.m_PGpath + "\n\n" + dlg.m_TGpath);
|
|
//패밀리 경로
|
|
str_BFpath = dlg.BFvalvePath;
|
|
str_Drainpath = dlg.m_Drainpath;
|
|
str_Safepath = dlg.m_Safepath;
|
|
str_PGpath = dlg.m_PGpath;
|
|
str_TGpath = dlg.m_TGpath;
|
|
|
|
m_ControlValHgt = dlg.m_ValHgt;
|
|
m_ArrValue = dlg.m_ArrValue;
|
|
m_ArrHdValue = dlg.m_ArrHdValue;
|
|
m_ArrDia = dlg.m_ArrDia;
|
|
|
|
SysTypeNameLst = dlg.SelectedSysTypeNameLst;
|
|
|
|
|
|
// 다이얼로그에서 설정한 데이터를 읽어 들인다.
|
|
ListBoxCnt2 = dlg.listboxcnt;
|
|
|
|
|
|
|
|
hd1 = dlg.mainHeaderDia; //헤더의몸통의 관경
|
|
ListBoxCnt = dlg.listboxcnt; // 가지관의 갯수
|
|
|
|
m_headHight = dlg.m_HeadHgt;
|
|
|
|
if (ListBoxCnt > 0)
|
|
{
|
|
borlst = new double[ListBoxCnt + 2];
|
|
|
|
for (int m = 0; m < ListBoxCnt; m++)
|
|
{
|
|
borlst[m + 1] = dlg.dlst[m];
|
|
}
|
|
}
|
|
|
|
// 1. 삽입점을 묻는다.
|
|
// 2. 방향을 묻는다.
|
|
// 3. 헤더의를 삽입한다.
|
|
// 4. 해더의 가지관을 삽입한다.
|
|
//------------------------------------------------------------------------------------------------------
|
|
//------------------------------------------------------------------------------------------------------
|
|
// 삽입점과 방향을 얻어온다.
|
|
ObjectSnapTypes snapType = ObjectSnapTypes.Centers | ObjectSnapTypes.Endpoints | ObjectSnapTypes.Intersections
|
|
| ObjectSnapTypes.Midpoints | ObjectSnapTypes.Nearest | ObjectSnapTypes.WorkPlaneGrid | ObjectSnapTypes.Points | ObjectSnapTypes.Quadrants | ObjectSnapTypes.Tangents;
|
|
|
|
p1 = m_revit.Application.ActiveUIDocument.Selection.PickPoint(snapType, "삽입점");
|
|
//p2 = m_revit.Application.ActiveUIDocument.Selection.PickPoint(snapType, "방향 지정");
|
|
|
|
//선택한 점이 파이프 위의 점이면 파이프 높이 가져와야
|
|
|
|
|
|
//메인헤더와 플랜지의 값들을 계산
|
|
HDR_MDRAW(p1, 900);
|
|
|
|
// 다리간의 거리및 두께를 계산
|
|
HDR_HHH();
|
|
|
|
// 헤더를 로드및 삽입
|
|
// 2 -> 냉온수 공급
|
|
LoadFamily(2);
|
|
|
|
// 가지관을 삽입한다.
|
|
|
|
//총거리 = hd2
|
|
//메인헤더의 관경은 = hd1
|
|
//지지다리간의 최대 거리 = maxdist
|
|
//다리간의 거리 = gd_list
|
|
//헤더 지금 = hd1
|
|
//플랜지 관경 = flangedia
|
|
//플랜지 길이 = flangelen
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
MessageBox.Show("" + e);
|
|
}
|
|
|
|
|
|
return Autodesk.Revit.UI.Result.Succeeded;
|
|
}
|
|
|
|
private void HDR_MDRAW(XYZ inp, double hg1)
|
|
{
|
|
int m, flg, hd_Cnt;
|
|
double hp1, kts, ang, ds1;
|
|
|
|
|
|
XYZ lp0, lp1, lp2, lp3, lp4, lp5, lp6, lp7, lp8, lp9, lp10;
|
|
XYZ lp11, lp12, lp13, lp14, lp15, lp16, lp17, lp18, lp19;
|
|
XYZ pnt1;
|
|
XYZ brr1, brr3, brr4, brr5, brr6;
|
|
XYZ k1, k2, k3, k4, k5, k6, k7;
|
|
|
|
|
|
flangelen = hd1 * 0.14;
|
|
// pntlst.append(inp);
|
|
// ang = m_Math.arx_angleA(inp, agp);
|
|
// 온도계 존재
|
|
borlst[0] = 32.0;
|
|
borlst[ListBoxCnt2 + 1] = 32.0; // 안전밸브
|
|
|
|
|
|
// 주관 길이
|
|
hd_loc_dst = new double[ListBoxCnt2 + 5];
|
|
|
|
flg = 0;
|
|
hd_Cnt = 0;
|
|
pnt1 = inp;
|
|
|
|
|
|
hd_loc_dst[hd_Cnt] = 150;
|
|
hd_Cnt++;
|
|
|
|
hd_loc_dst[hd_Cnt] = 150;
|
|
hd_Cnt++;
|
|
|
|
for (m = 0; m < ListBoxCnt2 + 1; m++)
|
|
{
|
|
flg = flg + 1;
|
|
ds1 = SL(borlst[m], borlst[flg]); //파이프간 간격
|
|
|
|
hd_loc_dst[hd_Cnt] = ds1; hd_Cnt++;
|
|
|
|
// pntlst.append(pnt`1); //파이프작도 좌표 리스트
|
|
}
|
|
hd_loc_dst[hd_Cnt] = 250; hd_Cnt++; // 안전밸브
|
|
// pnt1 = m_Math.Polar(pnt1, 250, ang);
|
|
// pntlst.append(pnt1);
|
|
FL(hd1);
|
|
hp1 = flst[6] * 0.5; // 플랜지외경지름
|
|
flangedia = hp1;
|
|
// lp0 = m_Math.Polar(inp, hg1, ang + m_Math.RTD(PI * 0.5));
|
|
// / mDrawlp1 = m_Math.Polar(lp0, do1 * 2, ang + m_Math.RTD(PI));
|
|
// brr1 = m_Math.Polar(lp0, 50, ang);
|
|
hd2 = 0;
|
|
for (m = 0; m < hd_Cnt; m++)
|
|
{
|
|
hd2 = hd2 + hd_loc_dst[m];
|
|
}
|
|
} //defun end HDR-MDRAW
|
|
|
|
///헤더 다리 부분
|
|
private void HDR_HHH()
|
|
{
|
|
double chg1, chg2, dst0, dst1, dst2, an1, hg0;
|
|
chg1 = chg2 = dst0 = dst1 = dst2 = an1 = hg0 = 0.0;
|
|
bool chk = false;
|
|
int flg = 0, i = 0;
|
|
string tempS;
|
|
XYZ lp0, lp1, lp2, lp3, lp4, lp5, lp6, lp7, lp8, lp9, lp10, lp11;
|
|
XYZ dp0, dp1, dp2, dp3, dp4, dp5, dp6, br1, br2, bt1;
|
|
XYZ ct1, ct2, ct3, ct4, ct5, ct6, ct7, ct8, ct9, ct10, ct11, ct12, ct13, ct14, ct15;
|
|
XYZ ct16, ct17, ct18, ct19, ct20, ct21, ct22, ct23, ct24, ct25, ct26;
|
|
|
|
// chg1 = 지지관 지름 chg2 = 최대 지지 간격
|
|
if (hd1 == 200)
|
|
{
|
|
//chg1 = 65;
|
|
chg1 = 100;
|
|
chg2 = 1250;
|
|
}
|
|
else if (hd1 == 250)
|
|
{
|
|
//chg1 = 80;
|
|
chg1 = 120;
|
|
chg2 = 1500;
|
|
}
|
|
else if (hd1 >= 300)
|
|
{
|
|
//chg1 = 100;
|
|
chg1 = 150;
|
|
chg2 = 1750;
|
|
} // cond-end
|
|
|
|
|
|
footdia = chg1; //다리 기둥의 지름
|
|
chk = true;
|
|
flg = 0;
|
|
while (chk)
|
|
{
|
|
switch (flg)
|
|
{
|
|
case 0:
|
|
gi_ListEA = HDR_2D(hd2, chg2);
|
|
flg = 1 + flg;
|
|
break;
|
|
case 1:
|
|
gi_ListEA = HDR_3D(hd2, chg2);
|
|
flg = 1 + flg;
|
|
break;
|
|
case 2:
|
|
gi_ListEA = HDR_4D(hd2, chg2);
|
|
flg = 1 + flg;
|
|
break;
|
|
case 3:
|
|
gi_ListEA = HDR_5D(hd2, chg2);
|
|
flg = 1 + flg;
|
|
break;
|
|
default:
|
|
break;
|
|
} // cond-end
|
|
|
|
if (gi_ListEA != 0) chk = false;
|
|
} // while-end
|
|
|
|
//다리의 총 개수
|
|
totalfooter = flg;
|
|
|
|
// ***************************
|
|
// ekfl
|
|
|
|
} // defun hdr-2d
|
|
|
|
private void LoadFamily(int ai_type)
|
|
{
|
|
string versionNumber = doc.Application.VersionNumber.ToString();
|
|
|
|
List<Connector> tttt = new List<Connector>();
|
|
// load a family symbol from file
|
|
FamilySymbol gotSymbol = null;
|
|
List<FamilySymbol> fam1 = new List<FamilySymbol>();
|
|
Connector m_MainHeaderCon = null;//메인 헤더 커넥터 xyz와 비교하기위해
|
|
|
|
if (lang == LanguageType.English_USA || lang == LanguageType.English_GB)
|
|
fam1 = getFamily("Mechanical Equipment");
|
|
else if (lang == LanguageType.Korean)
|
|
fam1 = getFamily("기계 장비");
|
|
|
|
FamilySymbol valve = null;
|
|
bool sw = false;
|
|
//패밀리의 갯수가 하나이상이면 사용자가 선택 할수 있도록 해줘야한다.
|
|
|
|
|
|
//string Tmp = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
|
//Tmp = Tmp.Replace("\\KMBIM2019.dll", "");
|
|
string Tmp = Util.GetKMBIMLibraryFolder("Libraries\\Header");
|
|
// get the active view's level for beam creation
|
|
ViewPlan view = doc.ActiveView as ViewPlan;
|
|
Level level = view.GenLevel;
|
|
//Level level = uidoc.Document.GetElement(uidoc.ActiveView.LevelId) as Level;
|
|
|
|
String fileName = Tmp + "\\family\\"+versionNumber+"\\new Steam Header.rfa";
|
|
// 아래의 이름은 패밀리 고유의 이름이다. 패밀리 작업할때 입력하게 되어있다.
|
|
String name = "Hot Water Header (Supply)";
|
|
|
|
FamilyInstance instance = null;
|
|
|
|
using (Transaction trans = new Transaction(doc))
|
|
{
|
|
trans.Start("FamilyLoad");
|
|
sw = uidoc.Document.LoadFamilySymbol(fileName, name, out gotSymbol);
|
|
trans.Commit();
|
|
}
|
|
|
|
Definition df = null;
|
|
// 패밀리를 로드한다.
|
|
if (sw)
|
|
{
|
|
// 로드가 성공 하였다면 패밀리를 삽입한다.
|
|
Level level2 = uidoc.Document.ActiveView.GenLevel;
|
|
//FamilyInstance familyInstance = uidoc.Document.Create.NewFamilyInstance(new XYZ(p1.X, p1.Y, (p1.Z + Unit.CovertToAPI(800, DisplayUnitType.DUT_MILLIMETERS))), gotSymbol, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
|
|
|
|
FamilyInstance familyInstance = null;
|
|
Parameter familyParam = null;
|
|
|
|
using (Transaction trans = new Transaction(doc))
|
|
{
|
|
trans.Start("symbolActive");
|
|
if (gotSymbol.IsActive == false)
|
|
gotSymbol.Activate();
|
|
//familyInstance = uidoc.Document.Create.NewFamilyInstance(new XYZ(p1.X, p1.Y, (p1.Z + Unit.CovertToAPI(800, DisplayUnitType.DUT_MILLIMETERS))), gotSymbol, Autodesk.Revit.DB.Structure.StructuralType.NonStructural);
|
|
p1 = new XYZ(p1.X, p1.Y, 0);
|
|
familyInstance = uidoc.Document.Create.NewFamilyInstance(p1, gotSymbol, StructuralType.NonStructural);
|
|
uidoc.Document.Regenerate();
|
|
|
|
//헤더 높이 지정
|
|
df = GetDefinition(familyInstance, "foot1dist");
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
//familyParam = familyInstance.get_Parameter("Fdia");
|
|
sw = familyParam.Set(Unit.MMToFeet(m_headHight));
|
|
|
|
uidoc.Document.Regenerate();
|
|
|
|
Parameter param = familyInstance.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
|
|
double dd = Unit.FeetToMM(param.AsDouble());
|
|
param.Set(0);
|
|
uidoc.Document.Regenerate();
|
|
|
|
|
|
m_MainHeaderCon = familyInstance.MEPModel.ConnectorManager.Connectors.Cast<Connector>().First();
|
|
|
|
|
|
// Family asdf = familyInstance.Symbol.Family as Family;
|
|
// 플랜지의 길이 얻고 입력
|
|
// API 내부에서는 사용자가 입력하는 밀리의 단위가 아닌 피트가 쓰인다 그래서 변환해서 입력해 주어야 한다.
|
|
df = GetDefinition(familyInstance, "FSize");
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
//Parameter familyParam = familyInstance.get_Parameter("FSize");
|
|
sw = familyParam.Set(Unit.MMToFeet(flangelen));
|
|
|
|
//플랜지의 반경 얻고 입력
|
|
df = GetDefinition(familyInstance, "Fdia");
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
//familyParam = familyInstance.get_Parameter("Fdia");
|
|
sw = familyParam.Set(Unit.MMToFeet(flangedia));
|
|
|
|
//다리의 지름
|
|
// API 내부에서는 사용자가 입력하는 밀리의 단위가 아닌 피트가 쓰인다 그래서 변환해서 입력해 주어야 한다.
|
|
df = GetDefinition(familyInstance, "footerdia");
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
//familyParam = familyInstance.get_Parameter("footerdia");
|
|
sw = familyParam.Set(Unit.MMToFeet(footdia));
|
|
|
|
//헤더의 반경
|
|
// API 내부에서는 사용자가 입력하는 밀리의 단위가 아닌 피트가 쓰인다 그래서 변환해서 입력해 주어야 한다.
|
|
df = GetDefinition(familyInstance, "HeaderDia");
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
//familyParam = familyInstance.get_Parameter("HeaderDia");
|
|
sw = familyParam.Set(Unit.MMToFeet(hd1));
|
|
|
|
// 헤더의 총거리
|
|
|
|
// API 내부에서는 사용자가 입력하는 밀리의 단위가 아닌 피트가 쓰인다 그래서 변환해서 입력해 주어야 한다.
|
|
df = GetDefinition(familyInstance, "Totaldistance");
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
//familyParam = familyInstance.get_Parameter("Totaldistance");
|
|
sw = familyParam.Set(Unit.MMToFeet(hd2));
|
|
|
|
for (int i = 0; i <= totalfooter; i++)
|
|
{
|
|
string Tm2p = string.Format("footer_{0}", i + 1);
|
|
df = GetDefinition(familyInstance, Tm2p);
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
|
|
//familyParam = familyInstance.get_Parameter(Tm2p);
|
|
sw = familyParam.Set(Unit.MMToFeet(gd_List[i]));
|
|
}
|
|
//안보이는 다리들을 한곳으로 모으자
|
|
if (totalfooter >= 1)
|
|
{
|
|
for (int i = 3; i <= 5; i++)
|
|
{
|
|
string Tm2p = string.Format("footer_{0}", i);
|
|
df = GetDefinition(familyInstance, Tm2p);
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
//familyParam = familyInstance.get_Parameter(Tm2p);
|
|
if (i - 1 > totalfooter)
|
|
{
|
|
familyParam.Set(Unit.MMToFeet(0));
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
//보이는 다리의 거리를 준다.
|
|
for (int i = 0; i <= totalfooter; i++)
|
|
{
|
|
string Tm2p = string.Format("footer_{0}", i + 1);
|
|
df = GetDefinition(familyInstance, Tm2p);
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
//familyParam = familyInstance.get_Parameter(Tm2p);
|
|
sw = familyParam.Set(Unit.MMToFeet(gd_List[i]));
|
|
}
|
|
|
|
// 헤더 지지 다리를 상황에 따라서 보여주고 안보여주고 하는 기능
|
|
if (totalfooter >= 1)
|
|
{
|
|
for (int i = 3; i <= 5; i++)
|
|
{
|
|
string Tm2p = string.Format("FootVisible_{0}", i);
|
|
df = GetDefinition(familyInstance, Tm2p);
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
if (i - 1 <= totalfooter)
|
|
sw = familyParam.Set(1);
|
|
else
|
|
sw = familyParam.Set(0);
|
|
|
|
}
|
|
}
|
|
// 가지관들의 거리르 삽입해준다.
|
|
// 상황에 따라서 압력계나 온도계는 빠질수도 있다. 압력계는 가장 처음 온도계는 두번째 안전밸브는 마지막이다.
|
|
for (int i = 0; i <= hd_loc_dst.Length - 1; i++)
|
|
{
|
|
string Tm2p = string.Format("part_{0}", i + 1);
|
|
df = GetDefinition(familyInstance, Tm2p);
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
sw = familyParam.Set(Unit.MMToFeet(hd_loc_dst[i]));
|
|
}
|
|
|
|
//헤더의 커넥터를 전부 모아라.
|
|
|
|
|
|
FilteredElementCollector collector = new FilteredElementCollector(uidoc.Document);
|
|
collector.OfClass(typeof(PipeType));
|
|
PipeType pipeType = collector.FirstElement() as PipeType;
|
|
|
|
//PipeType pipeType = null;
|
|
//패밀리 위치변경 조정
|
|
doc.Regenerate();
|
|
|
|
|
|
Family family = familyInstance.Symbol.Family;
|
|
|
|
|
|
ConnectorSetIterator csi = null;
|
|
if (null != familyInstance.MEPModel)
|
|
{
|
|
int cnt = 0;
|
|
// 커넥터를 거리별로 정렬 한다.
|
|
|
|
DinoComparer cc = new DinoComparer();
|
|
|
|
List<Connector> OtherZConLst = new List<Connector>();
|
|
List<Connector> bodyConLst = Util.GetElementConnectors(familyInstance);
|
|
bodyConLst.Sort(cc);
|
|
|
|
double LastZ = (bodyConLst.Last().Origin.Z);
|
|
foreach (Connector con in bodyConLst)
|
|
{
|
|
tttt.Add(con);
|
|
if (Math.Abs(LastZ - con.Origin.Z) > Unit.MMToFeet(1))
|
|
{
|
|
OtherZConLst.Add(con);
|
|
//Util.Pyosi(doc, con.Origin, 0);
|
|
}
|
|
}
|
|
|
|
//tttt.Sort(cc);
|
|
|
|
OtherZConLst.Sort(cc);
|
|
foreach (Connector con in OtherZConLst)
|
|
{
|
|
tttt.Remove(con);
|
|
}
|
|
|
|
doc.Regenerate();
|
|
|
|
//outvalveconn = tttt[8];
|
|
trapvalveconn = OtherZConLst[0];
|
|
outvalveconn = OtherZConLst[1];
|
|
|
|
//tttt.RemoveAt(8);
|
|
|
|
/*
|
|
string str = null;
|
|
for (int i = 0; i < tttt.Count; i++)
|
|
{
|
|
str += string.Format("{0}{1}{2}\n", tttt[i].Origin.X, tttt[i].Origin.Y, tttt[i].Origin.Z);
|
|
}
|
|
MessageBox.Show(str);*/
|
|
|
|
|
|
|
|
// 일단 밸브 패밀리가 로드 되어져 있는지를 보라
|
|
List<FamilySymbol> fam = new List<FamilySymbol>();
|
|
if (lang == LanguageType.English_USA || lang == LanguageType.English_GB)
|
|
fam = getFamily("Pipe Accessories");
|
|
else if (lang == LanguageType.Korean)
|
|
fam = getFamily("파이프 액세서리");
|
|
|
|
//패밀리의 갯수가 하나이상이면 사용자가 선택 할수 있도록 해줘야한다.
|
|
if (fam.Count >= 1)
|
|
{
|
|
if (ai_type == 2 || ai_type == 3)
|
|
{
|
|
//valve = LoadFamilys("\\data\\PV_Butterfly Valve - 20-500mm-Handle.rfa", "PV_Butterfly Valve - 20-500mm-Handle");
|
|
valve = LoadFamilys(str_BFpath);
|
|
}
|
|
|
|
if (valve == null)
|
|
{
|
|
if (ai_type == 2 || ai_type == 3)
|
|
{
|
|
//valve = getNameByFamily("PV_Butterfly Valve - 20-500mm-Handle");
|
|
valve = getNameByFamily(Path.GetFileNameWithoutExtension(str_BFpath));
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
if (fam.Count == 0)// 밸브 패밀리가 없다면 로드하라
|
|
{
|
|
if (ai_type == 2 || ai_type == 3)
|
|
{
|
|
//valve = LoadFamilys("\\data\\PV_Butterfly Valve - 20-500mm-Handle.rfa", "PV_Butterfly Valve - 20-500mm-Handle");
|
|
valve = LoadFamilys(str_BFpath);
|
|
}
|
|
|
|
if (valve == null)
|
|
{
|
|
if (ai_type == 2 || ai_type == 3)
|
|
{
|
|
//valve = getNameByFamily("PV_Butterfly Valve - 20-500mm-Handle");
|
|
valve = getNameByFamily(Path.GetFileNameWithoutExtension(str_BFpath));
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
List<Pipe> pipelist = new List<Pipe>();
|
|
List<XYZ> intps = new List<XYZ>();
|
|
|
|
// 상황에 따른 대처를 위해서 변수 생셩
|
|
if (ai_type == 2)
|
|
Cntnum = 2;
|
|
|
|
double m_elevation = view.GenLevel.Elevation;
|
|
// 커넥터수만큼 roof를 돌면서 파이프를 그린다.
|
|
for (int i = Cntnum; i < tttt.Count; i++)
|
|
{
|
|
if (cnt < borlst.Length - 2)
|
|
{
|
|
double con2valDst = Unit.MMToFeet(m_ControlValHgt) - (tttt[i].Origin.Z - m_elevation);
|
|
XYZ inpt = new XYZ(tttt[i].Origin.X, tttt[i].Origin.Y, (tttt[i].Origin.Z + con2valDst * 2.0));
|
|
//XYZ inpt = new XYZ(tttt[i].Origin.X, tttt[i].Origin.Y, (tttt[i].Origin.Z + Unit.CovertToAPI(1000, DisplayUnitType.DUT_MILLIMETERS)));
|
|
Pipe pipe = null;
|
|
pSysType = SysTypeNameLst[cnt];
|
|
pipe = Pipe.Create(doc, pSysType.Id, pipeType.Id, level.Id, tttt[i].Origin, inpt);
|
|
//파이프와 헤더 몸통 커넥터 연결
|
|
List<Connector> pipeConLst = Util.GetElementConnectors(pipe);
|
|
foreach (Connector con in pipeConLst)
|
|
{
|
|
if (con.Origin.IsAlmostEqualTo(tttt[i].Origin, Unit.MMToFeet(0.01)))
|
|
con.ConnectTo(tttt[i]);
|
|
}
|
|
|
|
if (ai_type == 2 || ai_type == 3)
|
|
ChangePipeSize(pipe, borlst[cnt + 1]); // 냉온수일때
|
|
|
|
pipelist.Add(pipe);
|
|
intps.Add(inpt);
|
|
}
|
|
else
|
|
break;
|
|
cnt++;
|
|
}
|
|
|
|
|
|
cnt = 0;
|
|
for (int i = 0; i < pipelist.Count; i++)
|
|
{
|
|
//20210309 파이프 관경이 50이하일 경우 밸브 부착 X
|
|
if (pipelist[i].Diameter <= Unit.MMToFeet(50)) continue;
|
|
|
|
// 밸브를 삽입히가.
|
|
|
|
FamilyInstance fi = null;
|
|
//using(Transaction trans = new Transaction(doc))
|
|
//{
|
|
// trans.Start("valve");
|
|
if (valve.IsActive == false)
|
|
valve.Activate();
|
|
var vel = valve.IsActive;
|
|
fi = uidoc.Document.Create.NewFamilyInstance(XYZ.Zero, valve, StructuralType.NonStructural);
|
|
uidoc.Document.Regenerate();
|
|
// trans.Commit();
|
|
//}
|
|
|
|
XYZ base1 = XYZ.Zero;
|
|
XYZ base2 = -XYZ.BasisY;
|
|
// 회전축을 정의하고
|
|
Line nline = Line.CreateUnbound(base1, base2);
|
|
// 돌린다.
|
|
fi.Location.Rotate(nline, Math.PI / 2);
|
|
|
|
base1 = XYZ.Zero;
|
|
base2 = -XYZ.BasisZ;
|
|
// 다시 회전축을 정의하고
|
|
nline = Line.CreateUnbound(base1, base2);
|
|
//돌린다.
|
|
fi.Location.Rotate(nline, -Math.PI / 2);
|
|
|
|
XYZ vec = (intps[i] - tttt[i + Cntnum].Origin).Normalize();
|
|
XYZ PipeMidPt = Util.Polar(tttt[i + Cntnum].Origin, vec, intps[i].DistanceTo(tttt[i + Cntnum].Origin) / 2.0);
|
|
//Util.Pyosi(doc, PipeMidPt, 0);
|
|
//ElementTransformUtils.MoveElement(uidoc.Document, fi.Id, new XYZ(intps[i].X, intps[i].Y, (intps[i].Z + Unit.CovertToAPI(20, DisplayUnitType.DUT_MILLIMETERS))));
|
|
ElementTransformUtils.MoveElement(uidoc.Document, fi.Id, PipeMidPt);
|
|
|
|
//자르기 전 파이프 시작 끝 커넥터 구하기
|
|
Connector spCon = null, epCon = null;
|
|
Util.GetStartEndConnector(pipelist[i], ref spCon, ref epCon);
|
|
|
|
//파이프 중간점 기준으로 자르기
|
|
List<ElementId> m_DivLst = Util.DivideElement(doc, pipelist[i], PipeMidPt);
|
|
|
|
|
|
Connector divspCon1 = null, divepCon1 = null, divspCon2 = null, divepCon2 = null;
|
|
Util.GetStartEndConnector(doc.GetElement(m_DivLst.First()) as Pipe, ref divspCon1, ref divepCon1);
|
|
Util.GetStartEndConnector(doc.GetElement(m_DivLst[1]) as Pipe, ref divspCon2, ref divepCon2);
|
|
//Util.Pyosi(doc, divspCon1.Origin, 0);
|
|
//Util.Pyosi(doc, divepCon2.Origin, 0);
|
|
|
|
//밸브 커넥터 구하기
|
|
List<Connector> ValConLst = Util.GetElementConnectors(fi);
|
|
//밸브 관경 파이프 관경으로 변경Z
|
|
ValConLst.First().Radius = pipelist[i].Diameter / 2.0;
|
|
doc.Regenerate();
|
|
|
|
//밸브커넥터와 가까운 파이프커넥터끼리 연결
|
|
foreach(Connector valCon in ValConLst)
|
|
{
|
|
//자르기 전 파이프 시작 끝점 거리 비교
|
|
double dist1 = valCon.Origin.DistanceTo(divspCon1.Origin);
|
|
double dist2 = valCon.Origin.DistanceTo(divepCon2.Origin);
|
|
|
|
if (dist1 < dist2)
|
|
{
|
|
divepCon1.Origin = valCon.Origin;
|
|
divepCon1.ConnectTo(valCon);
|
|
}
|
|
else
|
|
{
|
|
divspCon2.Origin = valCon.Origin;
|
|
divspCon2.ConnectTo(valCon);
|
|
}
|
|
|
|
}
|
|
cnt++;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
//가지관들의 관경을 삽입해준다.
|
|
int intype = -1;
|
|
if (ai_type == 2)
|
|
intype = 2;
|
|
|
|
if (ai_type == 2 || ai_type == 3)
|
|
{
|
|
for (int i = 0; i <= borlst.Length - 1; i++)
|
|
{
|
|
|
|
string Tm2p = string.Format("part{0}_dia", i + intype);
|
|
df = GetDefinition(familyInstance, Tm2p);
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
sw = familyParam.Set(Unit.MMToFeet(borlst[i]));
|
|
}
|
|
}
|
|
|
|
if (ai_type == 2)
|
|
{
|
|
string Tm2p = string.Format("part1_dia");
|
|
df = GetDefinition(familyInstance, Tm2p);
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
sw = familyParam.Set(Unit.MMToFeet(32));
|
|
}
|
|
|
|
// 가지관이 많은데 사용자에게 보이는 문제점이 있어서 거리가 없는경우는 전부 한곳으로 겹치도록 처리
|
|
for (int i = hd_loc_dst.Length - 1; i <= 40; i++)
|
|
{
|
|
string Tm2p = string.Format("part_{0}", i);
|
|
df = GetDefinition(familyInstance, Tm2p);
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
sw = familyParam.Set(Unit.MMToFeet(0));
|
|
}
|
|
|
|
|
|
|
|
// 가지관이 총 40개가 있는데 상황에 따라서 보여주고 안보여 주고 하는 기능
|
|
|
|
for (int i = 1; i <= 40; i++)
|
|
{
|
|
string Tm2p = string.Format("PartVisible_{0}", i);
|
|
df = GetDefinition(familyInstance, Tm2p);
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
if (i < hd_loc_dst.Length - 1) //2를 빼는 이유는 마지막 치수는 마지막 파이프 부터 끝쩜까지의 길이이기 때문에 뺀것이다. 그리고 또 하나는 꼬메소스에서 볼때 하나가 남기 때문에사용하지 않는 공간이기때문데 뺏다.
|
|
sw = familyParam.Set(1);
|
|
else
|
|
sw = familyParam.Set(0);
|
|
|
|
}
|
|
//트랩 커넥터 헤더증기에서만 보여줌
|
|
df = GetDefinition(familyInstance, "PartVisible_trap");
|
|
familyParam = familyInstance.get_Parameter(df);
|
|
familyParam.Set(0);
|
|
|
|
// 안전밸브 파이프 그리기
|
|
XYZ safeinpt = new XYZ(tttt[borlst.Length - 2 + Cntnum].Origin.X, tttt[borlst.Length - 2 + Cntnum].Origin.Y, (tttt[borlst.Length - 2 + Cntnum].Origin.Z + Unit.MMToFeet(150)));
|
|
//XYZ safeinpt = new XYZ(tttt[borlst.Length - 2 + Cntnum].Origin.X, tttt[borlst.Length - 2 + Cntnum].Origin.Y, (tttt[borlst.Length - 2 + Cntnum].Origin.Z + Unit.CovertToAPI(150, DisplayUnitType.DUT_MILLIMETERS)));
|
|
|
|
//Pipe pipes = uidoc.Document.Create.NewPipe(safeinpt, tttt[borlst.Length - 2 + Cntnum], pipeType);
|
|
|
|
Pipe pipes = Pipe.Create(doc, pSysType.Id, pipeType.Id, level.Id, tttt[borlst.Length - 2 + Cntnum].Origin, safeinpt);
|
|
|
|
//파이프와 헤더 몸통 커넥터 연결
|
|
List<Connector> pipesConLst = Util.GetElementConnectors(pipes);
|
|
foreach (Connector con in pipesConLst)
|
|
{
|
|
if (con.Origin.IsAlmostEqualTo(tttt[borlst.Length - 2 + Cntnum].Origin, Unit.MMToFeet(0.01)))
|
|
con.ConnectTo(tttt[borlst.Length - 2 + Cntnum]);
|
|
}
|
|
|
|
ChangePipeSize(pipes, 32);
|
|
|
|
//상황에 따라서 안전밸브의 삽입여부가 결정된다.
|
|
|
|
//if (ai_type == 2 || ai_type == 3 || ai_type == 4)
|
|
//{
|
|
|
|
// // 일단 밸브 패밀리가 로드 되어져 있는지를 보라
|
|
// List<FamilySymbol> fam = new List<FamilySymbol>();
|
|
// if (lang == LanguageType.English_USA || lang == LanguageType.English_GB)
|
|
// fam = getFamily("Mechanical Equipment");
|
|
// else if (lang == LanguageType.Korean)
|
|
// fam = getFamily("기계 장비");
|
|
|
|
// FamilySymbol valves = null;
|
|
|
|
// //패밀리의 갯수가 하나이상이면 사용자가 선택 할수 있도록 해줘야한다.
|
|
// if (fam.Count >= 1)
|
|
// {
|
|
// valve = LoadFamilys(str_Safepath);
|
|
// if (valve == null)
|
|
// {
|
|
// valve = getNameByFamily(Path.GetFileNameWithoutExtension(str_Safepath));
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
// if (fam.Count == 0)// 밸브 패밀리가 없다면 로드하라
|
|
// {
|
|
// valve = LoadFamilys(str_Safepath);
|
|
// }
|
|
|
|
// if (valve.IsActive == false)
|
|
// valve.Activate();
|
|
// FamilyInstance fi = uidoc.Document.Create.NewFamilyInstance(XYZ.Zero, valve, StructuralType.NonStructural);
|
|
|
|
// XYZ base1 = XYZ.Zero;
|
|
// XYZ base2 = -XYZ.BasisY;
|
|
|
|
// //uidoc.Document.Move(fi, new XYZ(safeinpt.X, safeinpt.Y, (safeinpt.Z + Unit.CovertToAPI(100, DisplayUnitType.DUT_MILLIMETERS))));
|
|
// ElementTransformUtils.MoveElement(uidoc.Document, fi.Id, new XYZ(safeinpt.X, safeinpt.Y, (safeinpt.Z + Unit.CovertToAPI(100, DisplayUnitType.DUT_MILLIMETERS))));
|
|
|
|
// ConnectorSet connectors = pipes.ConnectorManager.Connectors;
|
|
// Connector pipe_end = null;
|
|
|
|
// // 파이파의 커넥터중에 파이프의 끝나는검과 가장 가까운 커넥터를 얻어와라.
|
|
// double dist = double.MaxValue;
|
|
|
|
// foreach (Connector c in connectors)
|
|
// {
|
|
// XYZ p = c.Origin;
|
|
// XYZ valvept = new XYZ(tttt[borlst.Length - 2 + Cntnum].Origin.X, tttt[borlst.Length - 2 + Cntnum].Origin.Y, (tttt[borlst.Length - 2 + Cntnum].Origin.Z + Unit.CovertToAPI(150, DisplayUnitType.DUT_MILLIMETERS)));
|
|
// double d = p.DistanceTo(safeinpt);
|
|
|
|
// if (d < dist)
|
|
// {
|
|
// dist = d;
|
|
// pipe_end = c;
|
|
// }
|
|
// // break;
|
|
// }
|
|
|
|
|
|
|
|
// Connector first = null;
|
|
// Connector second = null;
|
|
|
|
|
|
// //밸브의 커넥터를 가져와라.
|
|
// ConnectorSet conns = fi.MEPModel.ConnectorManager.Connectors;
|
|
|
|
// // 밸브의 커넥터중에 파이프의 끝점과 가장 가까운 커넥터를 얻어와라.
|
|
// dist = double.MaxValue;
|
|
// foreach (Connector c in conns)
|
|
// {
|
|
// XYZ p = c.Origin;
|
|
// XYZ valvept = pipe_end.Origin;
|
|
// double d = p.DistanceTo(valvept);
|
|
|
|
// if (d < dist)
|
|
// {
|
|
// dist = d;
|
|
// first = c;
|
|
// }
|
|
// }
|
|
|
|
// // 밸브의 커넥터중 파이프의 끝점과 가장 먼 커넥터를 찾아라.
|
|
// foreach (Connector c in conns)
|
|
// {
|
|
// XYZ p = c.Origin;
|
|
// XYZ valvept = pipe_end.Origin;
|
|
// double d = p.DistanceTo(valvept);
|
|
|
|
// if (c != first)
|
|
// {
|
|
// second = c;
|
|
// break;
|
|
// }
|
|
|
|
// }
|
|
|
|
// // 커넥터를 연결해준다.
|
|
// df = GetDefinition(fi, "DI");
|
|
// familyParam = fi.get_Parameter(df);
|
|
// df = GetDefinition(fi.Symbol, "DI");
|
|
// familyParam = fi.Symbol.get_Parameter(df);
|
|
// sw = familyParam.Set(pipe_end.Radius * 2);
|
|
// pipe_end.ConnectTo(first);
|
|
//}
|
|
|
|
// 배수 밸브 파이프 그리기
|
|
XYZ outinpt = new XYZ(outvalveconn.Origin.X, outvalveconn.Origin.Y, (outvalveconn.Origin.Z - Unit.MMToFeet(150)));
|
|
//XYZ outinpt = new XYZ(outvalveconn.Origin.X, outvalveconn.Origin.Y, (outvalveconn.Origin.Z - Unit.CovertToAPI(150, DisplayUnitType.DUT_MILLIMETERS)));
|
|
|
|
//pipes = uidoc.Document.Create.NewPipe(outinpt, outvalveconn, pipeType);
|
|
pipes = Pipe.Create(doc, pSysType.Id, pipeType.Id, level.Id, outvalveconn.Origin, outinpt);
|
|
//파이프와 헤더 몸통 커넥터 연결
|
|
pipesConLst = Util.GetElementConnectors(pipes);
|
|
foreach (Connector con in pipesConLst)
|
|
{
|
|
if (con.Origin.IsAlmostEqualTo(tttt[borlst.Length - 2 + Cntnum].Origin, Unit.MMToFeet(0.01)))
|
|
con.ConnectTo(tttt[borlst.Length - 2 + Cntnum]);
|
|
}
|
|
|
|
ChangePipeSize(pipes, 32);
|
|
|
|
//상황에 따라서 배수밸브의 삽입여부가 결정된다.
|
|
|
|
//if (ai_type == 2 || ai_type == 3)
|
|
//{
|
|
//
|
|
// valve = LoadFamilys(str_Drainpath);
|
|
// if (valve == null)
|
|
// {
|
|
// //valve = getNameByFamily("PV_Ball Valve - 8-100mm -Threaded");
|
|
// valve = getNameByFamily(Path.GetFileNameWithoutExtension(str_Drainpath));
|
|
// }
|
|
//
|
|
// if (valve.IsActive == false)
|
|
// valve.Activate();
|
|
// FamilyInstance fi = uidoc.Document.Create.NewFamilyInstance(XYZ.Zero, valve, StructuralType.NonStructural);
|
|
//
|
|
// XYZ base1 = XYZ.Zero;
|
|
// XYZ base2 = -XYZ.BasisY;
|
|
//
|
|
// Line nline = Line.CreateUnbound(base1, base2);
|
|
//
|
|
// fi.Location.Rotate(nline, Math.PI / 2);
|
|
//
|
|
// base1 = XYZ.Zero;
|
|
// base2 = -XYZ.BasisZ;
|
|
//
|
|
// nline = Line.CreateUnbound(base1, base2);
|
|
//
|
|
// fi.Location.Rotate(nline, -Math.PI / 2);
|
|
//
|
|
//
|
|
// //uidoc.Document.Move(fi, new XYZ(outinpt.X, outinpt.Y, (outinpt.Z - Unit.CovertToAPI(10, DisplayUnitType.DUT_MILLIMETERS))));
|
|
// ElementTransformUtils.MoveElement(uidoc.Document, fi.Id, new XYZ(outinpt.X, outinpt.Y, (outinpt.Z - Unit.CovertToAPI(10, DisplayUnitType.DUT_MILLIMETERS))));
|
|
//
|
|
// ConnectorSet connectors = pipes.ConnectorManager.Connectors;
|
|
// Connector pipe_end = null;
|
|
//
|
|
// // 파이파의 커넥터중에 파이프의 끝나는검과 가장 가까운 커넥터를 얻어와라.
|
|
// double dist = double.MaxValue;
|
|
// foreach (Connector c in connectors)
|
|
// {
|
|
// XYZ p = c.Origin;
|
|
// XYZ valvept = new XYZ(outvalveconn.Origin.X, outvalveconn.Origin.Y, (outvalveconn.Origin.Z - Unit.CovertToAPI(150, DisplayUnitType.DUT_MILLIMETERS)));
|
|
// double d = p.DistanceTo(valvept);
|
|
//
|
|
// if (d < dist)
|
|
// {
|
|
// dist = d;
|
|
// pipe_end = c;
|
|
// }
|
|
// // break;
|
|
// }
|
|
//
|
|
//
|
|
//
|
|
// Connector first = null;
|
|
// Connector second = null;
|
|
//
|
|
//
|
|
// //밸브의 커넥터를 가져와라.
|
|
// ConnectorSet conns = fi.MEPModel.ConnectorManager.Connectors;
|
|
//
|
|
// // 밸브의 커넥터중에 파이프의 끝점과 가장 가까운 커넥터를 얻어와라.
|
|
// dist = double.MaxValue;
|
|
// foreach (Connector c in conns)
|
|
// {
|
|
// XYZ p = c.Origin;
|
|
// XYZ valvept = pipe_end.Origin;
|
|
// double d = p.DistanceTo(valvept);
|
|
//
|
|
// if (d < dist)
|
|
// {
|
|
// dist = d;
|
|
// first = c;
|
|
// }
|
|
// }
|
|
// // 밸브의 커넥터중 파이프의 끝점과 가장 먼 커넥터를 찾아라.
|
|
// foreach (Connector c in conns)
|
|
// {
|
|
// XYZ p = c.Origin;
|
|
// XYZ valvept = pipe_end.Origin;
|
|
// double d = p.DistanceTo(valvept);
|
|
//
|
|
// if (c != first)
|
|
// {
|
|
// second = c;
|
|
// break;
|
|
// }
|
|
//
|
|
// }
|
|
//
|
|
// //밸브의 커넥터 관경을 준다.
|
|
// foreach (Connector c in conns)
|
|
// {
|
|
// c.Radius = pipes.Diameter / 2;
|
|
// }
|
|
//
|
|
//
|
|
// // Curve curve = m_revit.Application.Application.Create.NewLineBound(new XYZ(tttt[i + Cntnum].Origin.X, tttt[i + Cntnum].Origin.Y, tttt[i + Cntnum].Origin.Z), new XYZ(first.Origin.X, first.Origin.Y, first.Origin.Z));
|
|
// // Util.SetCurve(pipelist[i], curve);
|
|
//
|
|
//
|
|
// // 커넥터를 연결해준다.
|
|
// pipe_end.ConnectTo(first);
|
|
// // 두번째 커넥터 부터 파이프를 하나 그려준다.
|
|
//
|
|
//
|
|
//
|
|
// XYZ inpt = new XYZ(second.Origin.X, second.Origin.Y, (second.Origin.Z - Unit.CovertToAPI(200, DisplayUnitType.DUT_MILLIMETERS)));
|
|
// //Pipe pipe = uidoc.Document.Create.NewPipe(inpt, second, pipeType);
|
|
// Pipe pipe = Pipe.Create(doc, pipeType.Id, level.Id, second, inpt);
|
|
// ChangePipeSize(pipe, 32);
|
|
//}
|
|
|
|
|
|
|
|
// 타입에 따라서 압력계를 삽입한다.
|
|
//냉온수 공급,환수 에서는 압력계가 둘다 들어간다.
|
|
if (ai_type == 2 || ai_type == 3)
|
|
{
|
|
|
|
|
|
|
|
valve = LoadFamilys(str_PGpath);
|
|
//valve = LoadFamilys("\\data\\M_Pressure Gauge1.rfa", null);
|
|
if (valve == null)
|
|
{
|
|
valve = getNameByFamily(Path.GetFileNameWithoutExtension(str_PGpath));
|
|
}
|
|
|
|
if (valve.IsActive == false)
|
|
valve.Activate();
|
|
FamilyInstance fi = uidoc.Document.Create.NewFamilyInstance(XYZ.Zero, valve, StructuralType.NonStructural);
|
|
doc.Regenerate();
|
|
XYZ base1 = null;
|
|
XYZ base2 = null;
|
|
Line nline = null;
|
|
Connector Connector = null;
|
|
|
|
Connector = fi.MEPModel.ConnectorManager.Connectors.Cast<Connector>().First();
|
|
|
|
//압력계가 누워있는 경우 세우는 코드.
|
|
XYZ vec1 = Connector.CoordinateSystem.BasisZ;
|
|
XYZ vec2 = m_MainHeaderCon.CoordinateSystem.BasisZ;
|
|
XYZ vec3 = vec1.CrossProduct(vec2);
|
|
base1 = Connector.Origin;
|
|
base2 = base1 + vec3 * 2.0;
|
|
nline = Line.CreateUnbound(base1, base2);
|
|
fi.Location.Rotate(nline, Util.DTR(-90));
|
|
|
|
XYZ vec = new XYZ(tttt[0].Origin.X, tttt[0].Origin.Y, tttt[0].Origin.Z);
|
|
//uidoc.Document.Move(fi, vec);
|
|
ElementTransformUtils.MoveElement(uidoc.Document, fi.Id, vec);
|
|
|
|
ConnectorSet conns = fi.MEPModel.ConnectorManager.Connectors;
|
|
Connector ficonn = null;
|
|
|
|
// 밸브의 커넥터중에 파이프의 끝점과 가장 가까운 커넥터를 얻어와라.
|
|
double dist = double.MaxValue;
|
|
foreach (Connector c in conns)
|
|
{
|
|
ficonn = c;
|
|
break;
|
|
}
|
|
|
|
// familyParam = fi.ObjectType.get_Parameter("Nominal Radius");
|
|
df = GetDefinition(fi.Symbol, "Nominal Radius");
|
|
familyParam = fi.Symbol.get_Parameter(df);
|
|
if (familyParam != null)
|
|
sw = familyParam.Set(tttt[0].Radius);
|
|
|
|
//마지막에 압력게이지 높이 조정하기 위해 패밀리 담아둠.
|
|
PGfamily = fi;
|
|
//df = GetDefinition(fi, "Pressure Gaug_Length");
|
|
//familyParam = fi.get_Parameter(df);
|
|
//if (familyParam != null)
|
|
// sw = familyParam.Set(Unit.MMToFeet(200));
|
|
|
|
// 커넥터 연결해주기
|
|
tttt[0].ConnectTo(ficonn);
|
|
}
|
|
|
|
//타입에 따라서 온도계를 삽입한다.
|
|
//온도계는 냉온수 공급에만 들어간다
|
|
if (ai_type == 2)
|
|
{
|
|
|
|
valve = LoadFamilys(str_TGpath);
|
|
if (valve == null)
|
|
{
|
|
valve = getNameByFamily(Path.GetFileNameWithoutExtension(str_TGpath));
|
|
}
|
|
|
|
if (valve.IsActive == false)
|
|
valve.Activate();
|
|
FamilyInstance fi = uidoc.Document.Create.NewFamilyInstance(XYZ.Zero, valve, StructuralType.NonStructural);
|
|
doc.Regenerate();
|
|
XYZ base1 = null;
|
|
XYZ base2 = null;
|
|
Line nline = null;
|
|
Connector Connector = null;
|
|
|
|
Connector = fi.MEPModel.ConnectorManager.Connectors.Cast<Connector>().First();
|
|
|
|
//압력계가 누워있는 경우 세우는 코드.
|
|
XYZ vec1 = Connector.CoordinateSystem.BasisZ;
|
|
XYZ vec2 = m_MainHeaderCon.CoordinateSystem.BasisZ;
|
|
XYZ vec3 = vec1.CrossProduct(vec2);
|
|
base1 = Connector.Origin;
|
|
base2 = base1 + vec3 * 2.0;
|
|
nline = Line.CreateUnbound(base1, base2);
|
|
fi.Location.Rotate(nline, Util.DTR(-90));
|
|
//압력계 돌림.
|
|
vec1 = Connector.CoordinateSystem.BasisY;
|
|
vec2 = m_MainHeaderCon.CoordinateSystem.BasisY;
|
|
vec3 = vec1.CrossProduct(vec2);
|
|
base1 = Connector.Origin;
|
|
base2 = base1 + vec3 * 2.0;
|
|
nline = Line.CreateUnbound(base1, base2);
|
|
fi.Location.Rotate(nline, Util.DTR(90));
|
|
|
|
XYZ vec = new XYZ(tttt[1].Origin.X, tttt[1].Origin.Y, tttt[1].Origin.Z);
|
|
//uidoc.Document.Move(fi, vec);
|
|
ElementTransformUtils.MoveElement(uidoc.Document, fi.Id, vec);
|
|
|
|
ConnectorSet conns = fi.MEPModel.ConnectorManager.Connectors;
|
|
Connector ficonn = null;
|
|
|
|
// 밸브의 커넥터중에 파이프의 끝점과 가장 가까운 커넥터를 얻어와라.
|
|
double dist = double.MaxValue;
|
|
foreach (Connector c in conns)
|
|
{
|
|
ficonn = c;
|
|
break;
|
|
}
|
|
|
|
df = GetDefinition(fi, "Nominal Radius");
|
|
familyParam = fi.get_Parameter(df);
|
|
df = GetDefinition(fi.Symbol, "Nominal Radius");
|
|
familyParam = fi.Symbol.get_Parameter(df);
|
|
sw = familyParam.Set(tttt[1].Radius);
|
|
|
|
// 커넥터 연결해주기
|
|
tttt[1].ConnectTo(ficonn);
|
|
}
|
|
|
|
uidoc.Document.Regenerate();
|
|
|
|
trans.Commit();
|
|
}
|
|
using (Transaction trans = new Transaction(doc))
|
|
{
|
|
trans.Start("1");
|
|
|
|
//압력계 높이 200으로 조정
|
|
df = GetDefinition(PGfamily, "Pressure Gaug_Length");
|
|
familyParam = PGfamily.get_Parameter(df);
|
|
if (familyParam != null)
|
|
sw = familyParam.Set(Unit.MMToFeet(200));
|
|
|
|
trans.Commit();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("Couldn't load ");
|
|
}
|
|
|
|
|
|
}
|
|
private double SL(double index1, double index2)
|
|
{
|
|
|
|
int i;
|
|
int n;
|
|
double dGet, val1, val2;
|
|
HeValue heval;
|
|
string s;
|
|
|
|
//수정 해야 할 부분 //yong 02.12 return값에 맞춰서 excel data핸들링하게 .....
|
|
|
|
n = (int)m_ArrValue.Count();
|
|
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
heval = m_ArrValue[i];
|
|
val1 = Convert.ToDouble(heval.he);
|
|
val2 = Convert.ToDouble(heval.we);
|
|
|
|
if (((Math.Abs(val1 - index1) < 0.001 && Math.Abs(val2 - index2) < 0.001) ||
|
|
(Math.Abs(val1 - index2) < 0.001 && Math.Abs(val2 - index1) < 0.001)) && (val1 != 0.0f && val2 != 0.0f))
|
|
{
|
|
dGet = Convert.ToDouble(heval.val);
|
|
|
|
return dGet;
|
|
break;//
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////
|
|
return 0.0f;
|
|
} // defun-end
|
|
private void FL(double index)
|
|
{
|
|
|
|
|
|
HdValue val;
|
|
double dHDDIA;
|
|
//HDDIA,BLTSIZE,BLTBORE,BLTNO,FLGID,BLTCENDST,FLGOD
|
|
//헤더지름,볼트 사이즈,구멍크기,구멍개수,플랜지 내경,볼트 중심간 거리 ,플랜지 외경
|
|
for (int i = 0; i < m_ArrHdValue.Count; i++)
|
|
{
|
|
val = m_ArrHdValue[i];
|
|
dHDDIA = Convert.ToDouble(val.HDDIA);
|
|
if (dHDDIA == index)
|
|
{
|
|
flst[0] = dHDDIA;
|
|
flst[1] = Convert.ToDouble(val.BLTSIZE);
|
|
flst[2] = Convert.ToDouble(val.BLTBORE);
|
|
flst[3] = Convert.ToDouble(val.BLTNO);
|
|
flst[4] = Convert.ToDouble(val.FLGID);
|
|
flst[5] = Convert.ToDouble(val.BLTCENDST);
|
|
flst[6] = Convert.ToDouble(val.FLGOD);
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
} //defun-end
|
|
|
|
private int HDR_2D(double hd2, double chg2)
|
|
{
|
|
double dd1, dd2, dd3;
|
|
|
|
dd1 = 0.25 * hd2;
|
|
dd2 = 0.5 * hd2;
|
|
dd3 = 0.25 * hd2;
|
|
|
|
if (dd2 > chg2) return 0;
|
|
else
|
|
{
|
|
gd_List[0] = dd1;
|
|
gd_List[1] = dd2;
|
|
gd_List[2] = dd3;
|
|
|
|
return 2;
|
|
}
|
|
} // defun hdr-2d
|
|
|
|
private int HDR_3D(double hd2, double chg2)
|
|
{
|
|
double dd1, dd2, dd3, dd4;
|
|
|
|
dd1 = 0.13 * hd2;
|
|
dd2 = 0.37 * hd2;
|
|
dd3 = 0.37 * hd2;
|
|
dd4 = 0.13 * hd2;
|
|
|
|
if (dd2 > chg2) return 0;
|
|
else
|
|
{
|
|
gd_List[0] = dd1;
|
|
gd_List[1] = dd2;
|
|
gd_List[2] = dd3;
|
|
gd_List[3] = dd4;
|
|
|
|
return 3;
|
|
}
|
|
} // defun hdr-3d
|
|
|
|
private int HDR_4D(double hd2, double chg2)
|
|
{
|
|
double dd1, dd2, dd3, dd4, dd5;
|
|
|
|
dd1 = 0.095 * hd2;
|
|
dd2 = 0.27 * hd2;
|
|
dd3 = 0.27 * hd2;
|
|
dd4 = 0.27 * hd2;
|
|
dd5 = 0.095 * hd2;
|
|
|
|
if (dd2 > chg2) return 0;
|
|
else
|
|
{
|
|
gd_List[0] = dd1;
|
|
gd_List[1] = dd2;
|
|
gd_List[2] = dd3;
|
|
gd_List[3] = dd4;
|
|
gd_List[4] = dd5;
|
|
|
|
return 4;
|
|
}
|
|
} // defun hdr-4d
|
|
|
|
private int HDR_5D(double hd2, double chg2)
|
|
{
|
|
double dd1, dd2, dd3, dd4, dd5, dd6;
|
|
|
|
dd1 = 0.08 * hd2;
|
|
dd2 = 0.21 * hd2;
|
|
dd3 = 0.21 * hd2;
|
|
dd4 = 0.21 * hd2;
|
|
dd5 = 0.21 * hd2;
|
|
dd6 = 0.08 * hd2;
|
|
|
|
if (dd2 > chg2) return 0;
|
|
else
|
|
{
|
|
gd_List[0] = dd1;
|
|
gd_List[1] = dd2;
|
|
gd_List[2] = dd3;
|
|
gd_List[3] = dd4;
|
|
gd_List[4] = dd5;
|
|
gd_List[5] = dd6;
|
|
|
|
return 5;
|
|
}
|
|
} // defun hdr-2d
|
|
|
|
// 패밀리 존재 여부 검토
|
|
private List<FamilySymbol> getFamily(string categori)
|
|
{
|
|
|
|
List<FamilySymbol> familySymbol = new List<FamilySymbol>();
|
|
List<FamilyInstanceCreationData> fiCreationDatas =
|
|
new List<FamilyInstanceCreationData>();
|
|
ElementSet elementSet = null;
|
|
//Try to get a FamilySymbol
|
|
FilteredElementCollector collector = new FilteredElementCollector(m_revit.Application.ActiveUIDocument.Document);
|
|
ICollection<Element> collection = collector.OfClass(typeof(FamilySymbol)).ToElements();
|
|
FamilySymbol Symbol;
|
|
foreach (Element e in collection)
|
|
{
|
|
|
|
|
|
|
|
Symbol = e as FamilySymbol;
|
|
|
|
if (null != Symbol.Category)
|
|
{
|
|
if (categori == Symbol.Category.Name)
|
|
{
|
|
familySymbol.Add(Symbol);
|
|
}
|
|
}
|
|
}
|
|
|
|
return familySymbol;
|
|
}
|
|
// 패밀리 존재 여부 검토
|
|
private FamilySymbol getNameByFamily(string name)
|
|
{
|
|
|
|
List<FamilyInstanceCreationData> fiCreationDatas = new List<FamilyInstanceCreationData>();
|
|
ElementSet elementSet = null;
|
|
//Try to get a FamilySymbol
|
|
FilteredElementCollector collector = new FilteredElementCollector(m_revit.Application.ActiveUIDocument.Document);
|
|
ICollection<Element> collection = collector.OfClass(typeof(FamilySymbol)).ToElements();
|
|
FamilySymbol Symbol;
|
|
FamilySymbol target = null;
|
|
|
|
foreach (Element e in collection)
|
|
{
|
|
|
|
Symbol = e as FamilySymbol;
|
|
|
|
|
|
|
|
if (null != Symbol.Category)
|
|
{
|
|
if (name == Symbol.Family.Name)
|
|
{
|
|
// MessageBox.Show(Symbol.Family.Name);
|
|
target = Symbol;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return target;
|
|
}
|
|
private FamilySymbol LoadFamilys(string famroot, string famname)
|
|
{
|
|
|
|
//string Tmp = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
|
//Tmp = Tmp.Replace("\\KMBIM2019.dll", "");
|
|
string Tmp = Util.GetKMBIMLibraryFolder("Libraries\\Header");
|
|
// get the active view's level for beam creation
|
|
Level level = uidoc.Document.GetElement(uidoc.ActiveView.LevelId) as Level;
|
|
// load a family symbol from file
|
|
FamilySymbol gotSymbol = null;
|
|
String fileName = Tmp + famroot;// "\\data\\2010-0240312-글로브_밸브_(플랜지형).rfa";
|
|
// 아래의 이름은 패밀리 고유의 이름이다. 패밀리 작업할때 입력하게 되어있다.
|
|
String name = famname;//"2010-0240312-글로브_밸브_(플랜지형)";
|
|
|
|
FamilyInstance instance = null;
|
|
// 패밀리를 로드한다.
|
|
Family fam = null;
|
|
ElementType elemType = null;
|
|
|
|
//uidoc.Document.LoadFamilySymbol(fileName, "", out gotSymbol);
|
|
bool sw = uidoc.Document.LoadFamily(fileName, out fam);
|
|
if (sw == true)
|
|
{
|
|
/*foreach (FamilySymbol c in fam.Symbols)
|
|
{
|
|
gotSymbol = c;
|
|
|
|
}*/
|
|
ISet<ElementId> fam_ids = fam.GetFamilySymbolIds();
|
|
List<string> fam_sym_names = new List<string>();
|
|
|
|
if (fam_ids.Count() == 0) return null;
|
|
gotSymbol = (FamilySymbol)doc.GetElement(fam_ids.ElementAt(0));
|
|
|
|
}
|
|
return gotSymbol;
|
|
}
|
|
|
|
private FamilySymbol LoadFamilys(string FamilyPath)
|
|
{
|
|
// get the active view's level for beam creation
|
|
Level level = uidoc.Document.GetElement(uidoc.ActiveView.LevelId) as Level;
|
|
// load a family symbol from file
|
|
FamilySymbol gotSymbol = null;
|
|
String fileName = FamilyPath;// "\\data\\2010-0240312-글로브_밸브_(플랜지형).rfa";
|
|
// 아래의 이름은 패밀리 고유의 이름이다. 패밀리 작업할때 입력하게 되어있다.
|
|
String name = Path.GetFileNameWithoutExtension(FamilyPath);//"2010-0240312-글로브_밸브_(플랜지형)";
|
|
|
|
// 패밀리를 로드한다.
|
|
Family fam = null;
|
|
bool sw = uidoc.Document.LoadFamily(fileName, out fam);
|
|
if (sw == true)
|
|
{
|
|
ISet<ElementId> fam_ids = fam.GetFamilySymbolIds();
|
|
List<string> fam_sym_names = new List<string>();
|
|
|
|
if (fam_ids.Count() == 0) return null;
|
|
gotSymbol = (FamilySymbol)doc.GetElement(fam_ids.ElementAt(0));
|
|
|
|
}
|
|
return gotSymbol;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 매개 변수 정의를 반환합니다.
|
|
/// 주어진 요소와 매개 변수 이름.
|
|
/// </summary>
|
|
static Definition GetDefinition(Element elem, string parameter_name)
|
|
{
|
|
IList<Parameter> ps = elem.GetParameters(parameter_name);
|
|
|
|
int n = ps.Count;
|
|
|
|
Debug.Assert(1 >= n, "expected maximum one shared parameters" + "named " + parameter_name);
|
|
|
|
Definition d = (0 == n) ? null
|
|
: ps[0].Definition;
|
|
|
|
return d;
|
|
}
|
|
|
|
public void ChangePipeSize(Pipe pipe, double bore)
|
|
{
|
|
Parameter parameter = pipe.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
|
|
// string message = "Pipe diameter: " + parameter.AsValueString();
|
|
|
|
parameter.Set(Unit.MMToFeet(bore)); // set to 6"
|
|
|
|
// message += "\nPipe diameter after set: " + parameter.AsValueString();
|
|
|
|
//MessageBox.Show(message, "Revit");
|
|
}
|
|
|
|
}
|
|
}
|