Client/Desktop/KMBIM3.0/KMBIM3.0_23.08.16_수정최종/Cmd/PipeRack/DrawPipeRack.cs

939 lines
42 KiB
C#

using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using System.Collections.Generic;
using System.Linq;
//using COME4Revit.WinForm;
using System.Diagnostics;
using Autodesk.Revit.UI.Selection;
using System;
using System.Windows.Forms;
using KDCS.Utils;
using View = Autodesk.Revit.DB.View;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.Creation;
using KMBIM.Revit.Tools;
namespace KMBIM
{
public enum EnumPipeRackInstallBase
{
Structure, //구조체
Level //레벨
}
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class DrawPipeRack : IExternalCommand
{
UIApplication uiapp;
UIDocument uidoc;
Autodesk.Revit.DB.Document doc;
Autodesk.Revit.Creation.Application creApp;
Autodesk.Revit.Creation.Document creDoc;
public double m_MarginWidth = 0;
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
uiapp = commandData.Application;
uidoc = uiapp.ActiveUIDocument;
Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
doc = uidoc.Document;
creApp = uiapp.Application.Create;
creDoc = doc.Create;
View view = doc.ActiveView;
Level m_setLvlElem = null;
int RadType = 0;
PipeInfo pipeInfo1 = new PipeInfo();
PipeInfo pipeInfo2 = new PipeInfo();
try
{
//if (!WorkMain.GetInstance().IsValid) return Autodesk.Revit.UI.Result.Succeeded;
//파이프 선택
IList<Reference> pickrefs = commandData.Application.ActiveUIDocument.Selection.PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, new PipeSelectionFilter(), "가대 설치할 배관 선택 : ");
if (pickrefs.Count == 0)
{
MessageBox.Show("선택한 파이프가 없습니다.", "오류");
return Result.Cancelled;
}
//파이프로 변환
List<Pipe> PipeLst = new List<Pipe>();
foreach (Reference refer in pickrefs)
{
PipeLst.Add(doc.GetElement(refer) as Pipe);
}
//가장 큰 관경 구하기
Pipe MaxDiaPipe = getMaxPipe(PipeLst);
//최소 관경 구하기
Pipe MinOffsetPipe = getMinOffsetPipe(PipeLst);
//if(MinOffsetPipe!=null)
//대화상자
Form_PipeRack dlg = new Form_PipeRack();
dlg.revit = commandData;
dlg.MaxDiaPipe = MaxDiaPipe;
dlg.MinOffPipe = MinOffsetPipe;
dlg.ShowDialog();
if (dlg.DialogResult == DialogResult.Cancel) return Result.Cancelled;
m_MarginWidth = dlg.m_MarginDist;
double flr_Height = 0.0;
double selLvl_Height = 0.0;
//가대 설치 기준 (레벨 : T / 구조체 : F)
string PipeRackInstallBase = Reg.getReg("PipeRackInstallBase");
bool InstallBase = PipeRackInstallBase.CompareTo(EnumPipeRackInstallBase.Level.ToString()) == 0 ? true : false;
if (InstallBase)
{
//대화상자 선택한 레벨 가져오기
FilteredElementCollector lvlCollector = new FilteredElementCollector(doc);
ICollection<Element> lvlCollection = lvlCollector.OfClass(typeof(Level)).ToElements();
foreach (Element elem in lvlCollection)
{
Level lvl = elem as Level;
if (lvl.Name == dlg.m_LvlSet)
m_setLvlElem = lvl;
}
// 23.06.07(JYH) 바닥 슬라브가 존재 할 경우
FilteredElementCollector floorcollector = new FilteredElementCollector(doc);
ICollection<ElementId> flrIds = floorcollector.OfClass(typeof(Floor)).ToElementIds();
foreach (ElementId flrId in flrIds)
{
Floor floor = doc.GetElement(flrId) as Floor;
if (floor.LevelId == m_setLvlElem.Id)
{
Parameter offsetParam = floor.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM);
double flr_offset = offsetParam.AsDouble();
flr_Height = flr_offset;
selLvl_Height = m_setLvlElem.Elevation;
break;
}
}
}
else
{
Element nearestFloor = null;
double nearestDist = double.MaxValue;
foreach (Pipe pp in PipeLst)
{
BoundingBoxXYZ pipeBoundingBox = pp.get_BoundingBox(null);
FilteredElementCollector collector = new FilteredElementCollector(doc);
IList<Element> floors = collector.OfCategory(BuiltInCategory.OST_Floors).WhereElementIsNotElementType().ToList();
if (floors.Count <= 0)
{
MessageBox.Show("가대를 설치 할 구조체 (바닥)이 존재하지 않습니다.", "오류");
return Result.Cancelled;
}
foreach (Element floor in floors)
{
BoundingBoxXYZ floorBoundingBox = floor.get_BoundingBox(null);
double dist = pipeBoundingBox.Min.Z - floorBoundingBox.Max.Z;
if (dist > 0 && dist < nearestDist)
{
nearestDist = dist;
nearestFloor = floor;
}
}
Parameter offsetParam = nearestFloor.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM);
flr_Height = offsetParam.AsDouble();
ElementId levelId = nearestFloor.LevelId;
Level level = doc.GetElement(levelId) as Level;
m_setLvlElem = level;
selLvl_Height = level.Elevation;
}
}
//볼트 타입
RadType = dlg.m_Radidx;
if (InstallBase)
{
foreach (Pipe pp in PipeLst)
{
if (m_setLvlElem.Elevation > pp.ReferenceLevel.Elevation + pp.LevelOffset)
{
MessageBox.Show("배치 레벨과 파이프 간격이 좁습니다.", "오류");
return Result.Cancelled;
}
//파이프 리스트 중 높이가 좁을 경우 명령어 취소
if ((dlg.m_LvlCurrent != "Unknown" && dlg.m_LvlCurrent == dlg.m_LvlSet) || dlg.m_LvlCurrent == "Unknown")
{
if (pp.LevelOffset < Unit.MMToFeet(200))
{
MessageBox.Show("배치 레벨과 파이프 간격이 좁습니다.", "오류");
return Result.Cancelled;
}
}
}
}
//가대 심볼 로드되어 있지 않으면 로드
FamilySymbol fs = LoadFamilys("Chanel_Support_lower.rfa", null);
if (fs == null)
fs = getNameByFamily("Chanel_Support_lower");
//U볼트 패밀리 로드
FamilySymbol bolt = LoadFamilys("U_bolt.rfa", null);
if (bolt == null)
bolt = getNameByFamily("U_bolt");
//가이드 슈 패밀리 로드
FamilySymbol shoe = LoadFamilys("Guide_Shoe.rfa", null);
if (shoe == null)
shoe = getNameByFamily("Guide_Shoe");
while (true)
{
//가대 위치 지정
Reference pickref = commandData.Application.ActiveUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, new PipeSelectionFilter(), "가대 위치 지정 : ");
//위치 포인트
XYZ insertPt = pickref.GlobalPoint;
//위치포인트에서 양 쪽 가장 먼 파이프 두개를 찾아 교차점 구하기
//XYZ SideInterPt1 = null, SideInterPt2 = null;
List<PipeInfo> pipeInfoLst = new List<PipeInfo>();
if (PipeLst.Count == 1)
{
pipeInfo1.pipe = doc.GetElement(pickref) as Pipe;
Line line = (pipeInfo1.pipe.Location as LocationCurve).Curve as Line;
IntersectionResult interRes = line.Project(insertPt);
pipeInfo1.InterPt = interRes.XYZPoint;
pipeInfoLst.Add(pipeInfo1);
}
else
{
pipeInfoLst = getSidePipe(PipeLst, insertPt, ref pipeInfo1, ref pipeInfo2);
}
//Util.Pyosi(doc,SideInterPt1,1);
//MessageBox.Show("1");
//심볼이 로드되지 않으면 실행 X
if (fs != null)
{
using (Transaction trans = new Transaction(doc))
{
trans.Start("symbol");
if (fs.IsActive == false)
fs.Activate();
if (bolt.IsActive == false)
bolt.Activate();
if (shoe.IsActive == false)
shoe.Activate();
Pipe firstPipe = doc.GetElement(pickrefs.First()) as Pipe;
XYZ sp = null, ep = null;
Util.GetStartEndPoint(firstPipe, ref sp, ref ep);
XYZ PipeVec = (ep - sp).Normalize();
XYZ RotVec = Util.RotateVector(PipeVec, Util.DTR(90));
FamilyInstance family = null;
FamilyInstance TypeFamily = null;
List<FamilyInstance> boltFamLst = new List<FamilyInstance>();
//파이프 1개 선택 시
if (pipeInfo2.pipe == null)
{
XYZ tmp = new XYZ(0, 0, 0);
//가대 설치
//family = doc.Create.NewFamilyInstance(pipeInfo1.InterPt, fs, RotVec, doc.GetElement(pickref), StructuralType.NonStructural);
family = doc.Create.NewFamilyInstance(pipeInfo1.InterPt, fs, RotVec, doc.GetElement(pickref), StructuralType.NonStructural);
if (RadType == 0)
{
//파이프가 1개일 때 가이드 슈
TypeFamily = doc.Create.NewFamilyInstance(pipeInfo1.InterPt, shoe, PipeVec, doc.GetElement(pickref), StructuralType.NonStructural);
pipeInfoLst.First().family = TypeFamily;
}
else if (RadType == 1)
{
//파이프가 1개일 때 U볼트
TypeFamily = doc.Create.NewFamilyInstance(pipeInfo1.InterPt, bolt, PipeVec, doc.GetElement(pickref), StructuralType.NonStructural);
pipeInfoLst.First().family = TypeFamily;
}
//Util.Pyosi(doc, pipeInfo1.InterPt, 0);
}
else
{
//파이프 여러개 선택 시 양 끝 파이프 센터점에 가대 설치
XYZ centerPt = Util.Polar(pipeInfo1.InterPt, pipeInfo1.InterPt, pipeInfo2.InterPt, pipeInfo1.InterPt.DistanceTo(pipeInfo2.InterPt) / 2.0);
family = doc.Create.NewFamilyInstance(centerPt, fs, RotVec, doc.GetElement(pickref), StructuralType.NonStructural);
//Util.Pyosi(doc, centerPt, 0);
//U볼트 가이드 슈 삽입
foreach (PipeInfo info in pipeInfoLst)
{
XYZ locPt = new XYZ(info.InterPt.X, info.InterPt.Y, info.pipe.ReferenceLevel.Elevation + info.pipe.LevelOffset);
if (RadType == 0)
{
TypeFamily = doc.Create.NewFamilyInstance(locPt, shoe, PipeVec, doc.GetElement(pickref), StructuralType.NonStructural);
info.family = TypeFamily;
doc.Regenerate();
List<Connector> conLst = Util.GetElementConnectors(TypeFamily);
Connector shoeCon = conLst.First();
//Util.Pyosi(doc, pipeInfo1.InterPt, 0);
doc.Regenerate();
//가이드 슈 커넥터 위치를 기준으로 파이프 중심으로 이동
XYZ translation = locPt - shoeCon.Origin;
ElementTransformUtils.MoveElement(doc, TypeFamily.Id, translation);
}
else if (RadType == 1)
{
TypeFamily = doc.Create.NewFamilyInstance(locPt, bolt, PipeVec, doc.GetElement(pickref), StructuralType.NonStructural);
info.family = TypeFamily;
}
}
}
doc.Regenerate();
//패밀리 옵션 설정
FamilyOption(family, pipeInfoLst, pipeInfo1, pipeInfo2, PipeLst, m_setLvlElem, RadType, flr_Height, selLvl_Height);
trans.Commit();
}
}
else
break;
}//while end
}
catch (Exception e)
{
//MessageBox.Show("" + e);
}
return Result.Succeeded;
}
//패밀리 옵션 설정
private void FamilyOption(FamilyInstance Rack, List<PipeInfo> pipeInfoLst, PipeInfo pipeInfo1, PipeInfo pipeInfo2, List<Pipe> pipeLst, Level SelectLevel, int BoltType, double flr_Height, double selLvl_Height)
{
//////////////////////////////가대 설정////////////////////////////////////
Definition df = null;
double MaxPipeOutDia = 0;
double MinOffPipeOutDia = 0;
//가장 큰 관경 구하기
Pipe MaxDiaPipe = getMaxPipe(pipeLst);
//가장 큰 관경 외경
Parameter maxOutDiaParam = MaxDiaPipe.get_Parameter(BuiltInParameter.RBS_PIPE_OUTER_DIAMETER);
if (maxOutDiaParam != null)
MaxPipeOutDia = maxOutDiaParam.AsDouble();
//오프셋 값이 가장 높은 값.
Pipe MinOffsetPipe = getMinOffsetPipe(pipeLst);
//파이프 단열제 두께
double MaxinsulThk = 0, MininsulThk = 0;
if (MinOffsetPipe != null)
{
MininsulThk = Util.GetPipeInsulationThickness(doc, MinOffsetPipe);
Parameter minOutDiaParam = MinOffsetPipe.get_Parameter(BuiltInParameter.RBS_PIPE_OUTER_DIAMETER);
if (minOutDiaParam != null)
MinOffPipeOutDia = minOutDiaParam.AsDouble();
}
else
MaxinsulThk = Util.GetPipeInsulationThickness(doc, MaxDiaPipe);
//가대 설정
if (Rack != null)
{
//가대 채널 on
df = GetDefinition(Rack, "First_Chanel");
if (df != null)
{
Parameter paramChanel = Rack.get_Parameter(df);
if (paramChanel != null)
paramChanel.Set(1);
}
//가대 폭
df = GetDefinition(Rack, "Support_Width");
if (df != null)
{
Parameter paramWidth = Rack.get_Parameter(df);
if (paramWidth != null)
{
if (pipeInfo2.pipe == null)
{
double sidePipeDia = pipeInfo1.pipe.Diameter;
//파이프 관경 + 여유분(100)
paramWidth.Set(sidePipeDia + Unit.MMToFeet(m_MarginWidth));
}
else
{
double sidePipeDia = pipeInfo1.pipe.Diameter;
double side2PipeDia = pipeInfo2.pipe.Diameter;
//양 쪽 사이드 파이프 관경 + 양 사이드 파이프 거리 + 여유분(100)
paramWidth.Set(sidePipeDia + side2PipeDia + pipeInfo1.InterPt.DistanceTo(pipeInfo2.InterPt) + Unit.MMToFeet(m_MarginWidth));
}
}
}
//간격 띄우기 값 구하기
double m_Offset = 0;
Parameter paramOffset = Rack.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
if (paramOffset != null)
{
m_Offset = paramOffset.AsDouble();
if (MinOffsetPipe == null)
m_Offset = MaxDiaPipe.LevelOffset;//모든 파이프 offset 같다 = 관경 가장 큰 파이프 offset
else
m_Offset = MinOffsetPipe.LevelOffset;//모든 파이프 offset 같지 X = offset 가장 낮은 파이프의 offset
//가장 큰 관경만큼 간격띄우기 조정
if (MinOffsetPipe != null)
{
//paramOffset.Set(MinOffsetPipe.LevelOffset - MinOffsetPipe.Diameter / 2.0 - MininsulThk + MinOffsetPipe.ReferenceLevel.Elevation);
paramOffset.Set(MinOffsetPipe.LevelOffset - MinOffPipeOutDia / 2.0 - MininsulThk + MinOffsetPipe.ReferenceLevel.Elevation);
}
else
{
//paramOffset.Set(MaxDiaPipe.LevelOffset - MaxDiaPipe.Diameter / 2.0 - MaxinsulThk + MaxDiaPipe.ReferenceLevel.Elevation);
paramOffset.Set(MaxDiaPipe.LevelOffset - MaxDiaPipe.Diameter / 2.0 - MaxinsulThk + MaxDiaPipe.ReferenceLevel.Elevation);
}
}
doc.Regenerate();
//다리 길이1
df = GetDefinition(Rack, "Support_Height1");
if (df != null)
{
Parameter paramLeg1 = Rack.get_Parameter(df);
if (paramLeg1 != null)
{
//가대 변경된 offset 값과 같음.
paramOffset = Rack.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
//현재 뷰의 레벨만큼 빼서 다리길이 조정(대화상자 만든다면 제거할것)
//MinOffsetPipe의 offset - MinOffsetPipe 반지름 - 배치레벨높이
if (MinOffsetPipe != null)
{
paramLeg1.Set(m_Offset - MinOffPipeOutDia / 2.0 - MininsulThk + (MinOffsetPipe.ReferenceLevel.Elevation - SelectLevel.Elevation) - flr_Height);
//paramLeg1.Set(m_Offset - MinOffsetPipe.Diameter / 2.0 - MininsulThk + (MinOffsetPipe.ReferenceLevel.Elevation - SelectLevel.Elevation));
}
else
{
paramLeg1.Set(m_Offset - MaxPipeOutDia / 2.0 - MaxinsulThk + (MaxDiaPipe.ReferenceLevel.Elevation - SelectLevel.Elevation) - flr_Height);
//paramLeg1.Set(m_Offset - MaxDiaPipe.Diameter / 2.0 - MaxinsulThk + (MaxDiaPipe.ReferenceLevel.Elevation - SelectLevel.Elevation));
}
}
}
//doc.Regenerate();
//다리 길이2
df = GetDefinition(Rack, "Support_Height2");
if (df != null)
{
Parameter paramLeg2 = Rack.get_Parameter(df);
if (paramLeg2 != null)
{
//현재 뷰의 레벨만큼 빼서 다리길이 조정(대화상자 만든다면 제거할것)
//MinOffsetPipe의 offset - MinOffsetPipe 반지름 - 배치레벨높이
if (MinOffsetPipe != null)
{
paramLeg2.Set(m_Offset - MinOffPipeOutDia / 2.0 - MininsulThk + (MinOffsetPipe.ReferenceLevel.Elevation - SelectLevel.Elevation) - flr_Height);
//paramLeg2.Set(m_Offset - MinOffsetPipe.Diameter / 2.0 - MininsulThk + (MinOffsetPipe.ReferenceLevel.Elevation - SelectLevel.Elevation));
}
else
{
paramLeg2.Set(m_Offset - MaxPipeOutDia / 2.0 - MaxinsulThk + (MaxDiaPipe.ReferenceLevel.Elevation - SelectLevel.Elevation) - flr_Height);
//paramLeg2.Set(m_Offset - MaxDiaPipe.Diameter / 2.0 - MaxinsulThk + (MaxDiaPipe.ReferenceLevel.Elevation - SelectLevel.Elevation));
}
}
}
}
double m_CoverThk = 0, m_plateHgt = 0, m_plateThk = 0;
//////////////////////////////U볼트 가이드슈 설정////////////////////////////////////
foreach (PipeInfo info in pipeInfoLst)
{
//파이프 단열제 두께
double insulThk = Util.GetPipeInsulationThickness(doc, info.pipe);
//파이프 외경
Parameter param = info.pipe.get_Parameter(BuiltInParameter.RBS_PIPE_OUTER_DIAMETER);
double m_CurPipeOutDia = 0;
if (param != null)
m_CurPipeOutDia = param.AsDouble();
//가이드 슈
if (BoltType == 0)//가이드 슈
{
if (info.family != null)
{
//관경(외경) 변경
df = GetDefinition(info.family, "GuideShoeCoverInRad");
if (df != null)
{
Parameter paramSteelDia = info.family.get_Parameter(df);
if (paramSteelDia != null)
paramSteelDia.Set(m_CurPipeOutDia / 2.0 + insulThk);
//paramSteelDia.Set(info.pipe.Diameter / 2.0 + insulThk);
}
//커넥터 관경 변경
df = GetDefinition(info.family, "ConRad");
if (df != null)
{
Parameter paramConRad = info.family.get_Parameter(df);
if (paramConRad != null)
paramConRad.Set(m_CurPipeOutDia / 2.0 + insulThk);
//paramConRad.Set(info.pipe.Diameter / 2.0 + insulThk);
}
//슈 폭 변경
df = GetDefinition(info.family, "HalfGuideShoeCoverWidth");
if (df != null)
{
Parameter paramSteelHalfWidth = info.family.get_Parameter(df);
if (paramSteelHalfWidth != null)
paramSteelHalfWidth.Set(Unit.MMToFeet(25));
}
df = GetDefinition(info.family, "GuideShoeCoverGap");
if (df != null)
{
Parameter paramCoverGap = info.family.get_Parameter(df);
if (paramCoverGap != null)
paramCoverGap.Set(Unit.MMToFeet(3));
}
//가대 높이 재설정
//가이드 슈 두께
df = GetDefinition(info.family, "GuideShoeCoverThk");
if (df != null)
{
Parameter paramCoverThk = info.family.get_Parameter(df);
if (paramCoverThk != null)
{
paramCoverThk.Set(Unit.MMToFeet(5));//default value = 5
}
}
doc.Regenerate();
df = GetDefinition(info.family, "GuideShoeCoverThk");
if (df != null)
{
Parameter paramCoverThk = info.family.get_Parameter(df);
if (paramCoverThk != null)
m_CoverThk = paramCoverThk.AsDouble();
}
//판 두께
df = GetDefinition(info.family, "SupportThk");
if (df != null)
{
Parameter paramPlateThk = info.family.get_Parameter(df);
if (paramPlateThk != null)
m_plateThk = paramPlateThk.AsDouble();
}
//판 높이
df = GetDefinition(info.family, "SupportHeight");
if (df != null)
{
Parameter paramPlateHgt = info.family.get_Parameter(df);
if (paramPlateHgt != null)
{
m_plateHgt = paramPlateHgt.AsDouble();
if (MinOffsetPipe != null)
{
//판높이 + (MinOffsetPipe 반지름 - 현재 파이프 반지름) + (현재 파이프offset - MinOffsetPipe의offset)
paramPlateHgt.Set(m_plateHgt + ((MinOffPipeOutDia / 2.0 + MininsulThk) - (m_CurPipeOutDia / 2.0 + insulThk))
+ (info.pipe.LevelOffset - MinOffsetPipe.LevelOffset));
//paramPlateHgt.Set(m_plateHgt + ((MinOffsetPipe.Diameter / 2.0 + MininsulThk) - (info.pipe.Diameter / 2.0 + insulThk))
//+ (info.pipe.LevelOffset - MinOffsetPipe.LevelOffset));
}
else
{
//판높이 +(MaxDiaPipe반지름 - 현재파이프 반지름)
paramPlateHgt.Set(m_plateHgt + ((MaxPipeOutDia / 2.0 + MaxinsulThk) - (m_CurPipeOutDia / 2.0 + insulThk)));
//paramPlateHgt.Set(m_plateHgt + ((MaxDiaPipe.Diameter / 2.0 + MaxinsulThk) - (info.pipe.Diameter / 2.0 + insulThk)));
}
}
}
}
}
else if (BoltType == 1)//U볼트
{
//U볼트 패밀리 설정
if (info.family != null)
{
//간격 띄우기 값 구하기
double m_Offset = 0;
Parameter paramOffset = info.family.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
if (paramOffset != null)
{
m_Offset = paramOffset.AsDouble();
//가장 큰 관경만큼 간격띄우기 조정
if (MinOffsetPipe != null)
paramOffset.Set(m_Offset - MinOffPipeOutDia / 2.0 - MininsulThk - (info.pipe.LevelOffset - MinOffsetPipe.LevelOffset));
else
paramOffset.Set(m_Offset - MaxPipeOutDia / 2.0 - MaxinsulThk);
}
//관경 변경
df = GetDefinition(info.family, "Diameter");
if (df != null)
{
Parameter paramDia = info.family.get_Parameter(df);
if (paramDia != null)
{
paramDia.Set(info.pipe.Diameter + insulThk * 2);
}
}
//외경 변경
df = GetDefinition(info.family, "OutDiameter");
if (df != null)
{
Parameter paramOutDia = info.family.get_Parameter(df);
if (paramOutDia != null)
{
Parameter p_outDia = info.pipe.get_Parameter(BuiltInParameter.RBS_PIPE_OUTER_DIAMETER);
if (MinOffsetPipe != null)
paramOutDia.Set(p_outDia.AsDouble() + MininsulThk * 2);
else
paramOutDia.Set(p_outDia.AsDouble() + MaxinsulThk * 2);
}
}
double boltDia = 0;
double mm_PipeDia = Unit.FeetToMM(info.pipe.Diameter + insulThk * 2);
if (mm_PipeDia >= 15 && mm_PipeDia <= 50)
boltDia = Unit.MMToFeet(10);
else if (mm_PipeDia >= 65 && mm_PipeDia <= 90)
boltDia = Unit.MMToFeet(12);
else if (mm_PipeDia > 90 && mm_PipeDia <= 175)
boltDia = Unit.MMToFeet(16);
else if (mm_PipeDia > 175 && mm_PipeDia <= 250)
boltDia = Unit.MMToFeet(20);
else if (mm_PipeDia > 250 && mm_PipeDia <= 400)
boltDia = Unit.MMToFeet(24);
else if (mm_PipeDia > 400 && mm_PipeDia <= 500)
boltDia = Unit.MMToFeet(30);
else if (mm_PipeDia > 500)
boltDia = Unit.MMToFeet(32);
else
boltDia = Unit.MMToFeet(8);
df = GetDefinition(info.family, "Bolt_Diameter");
if (df != null)
{
Parameter paramBoltDia = info.family.get_Parameter(df);
if (paramBoltDia != null)
paramBoltDia.Set(boltDia);
}
//높이 지정
df = GetDefinition(info.family, "Support_Height");
if (df != null)
{
Parameter paramSupportHgt = info.family.get_Parameter(df);
if (paramSupportHgt != null)
{
if (MinOffsetPipe != null)
{
paramSupportHgt.Set(MinOffPipeOutDia / 2.0 + MininsulThk + (info.pipe.LevelOffset - MinOffsetPipe.LevelOffset));
}
else
paramSupportHgt.Set(MaxPipeOutDia / 2.0 + MaxinsulThk);
}
}
doc.Regenerate();
}
}
}
//
//가이드 슈 일 경우 가대 높이, 다리길이 재조정
if (BoltType == 0)
{
doc.Regenerate();
//가대간격 띄우기 값 구하기
Parameter paramOffset = Rack.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
double m_Offset = 0;
if (paramOffset != null)
{
m_Offset = paramOffset.AsDouble();
//가장 큰 관경만큼 간격띄우기 조정
paramOffset.Set(m_Offset - (m_CoverThk + m_plateThk + m_plateHgt));
}
df = GetDefinition(Rack, "Support_Height1");
if (df != null)
{
Parameter paramLeg1 = Rack.get_Parameter(df);
if (paramLeg1 != null)
{
double supLength = paramLeg1.AsDouble();
paramLeg1.Set(supLength - (m_CoverThk + m_plateThk + m_plateHgt));
}
}
df = GetDefinition(Rack, "Support_Height2");
if (df != null)
{
Parameter paramLeg2 = Rack.get_Parameter(df);
if (paramLeg2 != null)
{
double supLength = paramLeg2.AsDouble();
paramLeg2.Set(supLength - (m_CoverThk + m_plateThk + m_plateHgt));
}
}
}
}
/// <summary>
/// 관경이 가장 큰 파이프 구하기
/// </summary>
/// <param name="pipeLst"></param> 파이프 리스트
/// <returns></returns>
private Pipe getMaxPipe(List<Pipe> pipeLst)
{
double MaxDia = 0;
Pipe MaxPipe = null;
foreach (Pipe pp in pipeLst)
{
double m_PipeDia = pp.Diameter;
//단열재 두께
double insulThk = Util.GetPipeInsulationThickness(doc, pp);
if (MaxDia < m_PipeDia + insulThk)
{
MaxDia = m_PipeDia + (insulThk * 2);
MaxPipe = pp;
}
}
return MaxPipe;
}
private Pipe getMinOffsetPipe(List<Pipe> pipeLst)
{
double MinOffset = double.MaxValue;
Pipe MinOffsetPipe = null;
bool b_other = false;
//파이프 간격띄우기 값이 다 같으면 null 리턴
foreach (Pipe pp in pipeLst)
{
if (pipeLst.First().LevelOffset != pp.LevelOffset)
{
b_other = true;
break;
}
}
//파이프 간격띄우기 값이 다른게 있다면 실행
if (b_other)
{
foreach (Pipe pp in pipeLst)
{
double pipeOffset = pp.LevelOffset;
if (MinOffset > pipeOffset)
{
MinOffset = pipeOffset;
MinOffsetPipe = pp;
}
}
}
return MinOffsetPipe;
}
/// <summary>
/// 기준점에서 가장 먼 파이프 구하기
/// </summary>
/// <param name="pipeList"></param> 파이프 리스트
/// <param name="DirPt"></param> 기준점
/// <param name="SideInterPt"></param> 기준점과 파이프 교차점
/// <returns></returns>
private List<PipeInfo> getSidePipe(List<Pipe> pipeList, XYZ DirPt, ref PipeInfo sideInfo1, ref PipeInfo sideInfo2)
{
double minDist = double.MaxValue;
double maxDist = 0;
List<PipeInfo> PipeInfoLst = new List<PipeInfo>();
foreach (Pipe pipe in pipeList)
{
Line line = (pipe.Location as LocationCurve).Curve as Line;
IntersectionResult interRes = line.Project(DirPt);
XYZ interPt = new XYZ(interRes.XYZPoint.X, interRes.XYZPoint.Y, 0);
PipeInfo info = new PipeInfo();
info.pipe = pipe;
info.InterPt = interPt;
PipeInfoLst.Add(info);
}
XYZ vec = (PipeInfoLst.First().InterPt - PipeInfoLst.Last().InterPt).Normalize();
XYZ virtualPt = Util.Polar(PipeInfoLst.First().InterPt, vec, Unit.MMToFeet(10000));
foreach (PipeInfo pipeInfo in PipeInfoLst)
{
if (maxDist < virtualPt.DistanceTo(pipeInfo.InterPt))
{
sideInfo1 = pipeInfo;
maxDist = virtualPt.DistanceTo(pipeInfo.InterPt);
}
if (minDist > virtualPt.DistanceTo(pipeInfo.InterPt))
{
sideInfo2 = pipeInfo;
minDist = virtualPt.DistanceTo(pipeInfo.InterPt);
}
}
//Util.Pyosi(doc, sideInfo1.InterPt, 1);
//MessageBox.Show("1");
//Util.Pyosi(doc, sideInfo2.InterPt, 1);
//MessageBox.Show("2");
return PipeInfoLst;
}
// 패밀리 존재 여부 검토
private FamilySymbol getNameByFamily(string name)
{
List<FamilyInstanceCreationData> fiCreationDatas = new List<FamilyInstanceCreationData>();
//Try to get a FamilySymbol
FilteredElementCollector collector = new FilteredElementCollector(doc);
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 versionNumber = doc.Application.VersionNumber.ToString();
//string Tmp = System.Reflection.Assembly.GetExecutingAssembly().Location;
//Tmp = Tmp.Replace("\\KMBIM2019.dll", "");
string Tmp = Util.GetKMBIMLibraryFolder("Libraries\\PipeRack");
// get the active view's level for beam creation
Level level = doc.GetElement(doc.ActiveView.LevelId) as Level;
// load a family symbol from file
FamilySymbol gotSymbol = null;
String fileName = Tmp + "\\" + versionNumber + "\\" + famroot;
// 아래의 이름은 패밀리 고유의 이름이다. 패밀리 작업할때 입력하게 되어있다.
String name = famname;
// 패밀리를 로드한다.
Family fam = null;
//m_document.Document.LoadFamilySymbol(fileName, "", out gotSymbol);
bool sw = false;
using (Transaction trans = new Transaction(doc))
{
trans.Start("LoadFamily");
sw = doc.LoadFamily(fileName, out fam);
trans.Commit();
}
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;
}
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 class PipeSelectionFilter : ISelectionFilter
{
public bool AllowElement(Element element)
{
if (element.Category == null) return false;
if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_PipeCurves)
{
return true;
}
return false;
}
public bool AllowReference(Reference refer, XYZ point)
{
return false;
}
}
}
}