Client/Desktop/KMBIM3.0/23.10.18/Cmd/PipeRack/bracingTest.cs

250 lines
9.0 KiB
C#

using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using System.Collections.Generic;
using System.Linq;
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
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
public class bracingTest : IExternalCommand
{
UIApplication uiapp;
UIDocument uidoc;
Autodesk.Revit.DB.Document doc;
Autodesk.Revit.Creation.Application creApp;
Autodesk.Revit.Creation.Document creDoc;
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;
try
{
//버팀대 패밀리 로드
FamilySymbol bracing = LoadFamilys("횡방향버팀대.rfa", null);
if (bracing == null)
bracing = getNameByFamily("횡방향버팀대");
Reference PipeRef = commandData.Application.ActiveUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "볼트 설치할 배관 선택 : ");
Pipe pickPipe = doc.GetElement(PipeRef) as Pipe;
Curve PipeCur = ((pickPipe.Location) as LocationCurve).Curve;
IntersectionResult interRes = PipeCur.Project(PipeRef.GlobalPoint);
XYZ insertPt = interRes.XYZPoint;
XYZ PipePt = insertPt;
XYZ PipeSp = null, PipeEp = null;
Util.GetStartEndPoint(pickPipe, ref PipeSp, ref PipeEp);
//파이프 방향
XYZ DirVec = (PipeEp - PipeSp).Normalize();
XYZ rDirVec = (PipeSp - PipeEp).Normalize();
//Z값 기준
XYZ VecZ = XYZ.BasisZ;
using (Transaction trans = new Transaction(doc))
{
trans.Start("process");
bracing.Activate();
//레벨 배치 프로세스
bool b_tf = LevelProcess(PipeRef, "레벨 1", bracing, pickPipe);
trans.Commit();
}
}
catch
{
}
return Result.Succeeded;
}
//배치기준 레벨
public bool LevelProcess(Reference PipeRef, string setLevelName, FamilySymbol bracing,Pipe PipeHost)
{
bool b_TF = true;
FamilyInstance family = null;
IntersectionResult interRes = new IntersectionResult();
Pipe PickPipe = doc.GetElement(PipeRef) as Pipe;
Curve PipeCur = (PickPipe.Location as LocationCurve).Curve;
interRes = PipeCur.Project(PipeRef.GlobalPoint);
//선택 파이프 점으로 파이프 중심점 구하기
XYZ insertPt = interRes.XYZPoint;
XYZ PipePt = insertPt;
XYZ PipeSp = null, PipeEp = null;
Util.GetStartEndPoint(PickPipe, ref PipeSp, ref PipeEp);
//레벨 찾기
Level m_SetLevel = Util.GetLevel(doc, setLevelName);
//if (m_SetLevel.Elevation - PickPipe.ReferenceLevel.Elevation - PickPipe.LevelOffset < 0)
//{
// MessageBox.Show("배치기준 레벨보다 파이프가 더 높이 있습니다.", "오류");
// return b_TF = false;
//}
//참조평면 생성
XYZ p2 = new XYZ(insertPt.X + Unit.MMToFeet(10), insertPt.Y, insertPt.Z);
XYZ p1 = new XYZ(insertPt.X, insertPt.Y, insertPt.Z);
XYZ p3 = new XYZ(insertPt.X, insertPt.Y + Unit.MMToFeet(10), insertPt.Z);
ReferencePlane referPlane = doc.Create.NewReferencePlane2(p3, p1, p2, doc.ActiveView);
//doc.Create.NewReferencePlane()
family = doc.Create.NewFamilyInstance(referPlane.GetReference(), insertPt, (PipeEp - PipeSp).Normalize(), bracing);
//family = doc.Create.NewFamilyInstance(insertPt,bracing, (PipeEp - PipeSp).Normalize(),PipeHost as Pipe,StructuralType.NonStructural);
//family.IsWorkPlaneFlipped = false;
doc.Regenerate();
//패밀리 옵션
SetFamilyOpt(family, PickPipe, m_SetLevel);
//SetLevelBoltOpt(family, BoltType, PickPipe, m_SetLevel);
return b_TF;
}
//패밀리 옵션
private void SetFamilyOpt(FamilyInstance bracing, Pipe pickPipe, Level setLevel)
{
Definition df = null;
//파이프 단열제 두께
double insulThk = Util.GetPipeInsulationThickness(doc, pickPipe);
//배관 반지름
df = GetDefinition(bracing, "BCoverInRad");
if (df != null)
{
Parameter paramCoverRad = bracing.get_Parameter(df);
if (paramCoverRad != null)
paramCoverRad.Set(pickPipe.Diameter / 2.0 + insulThk);
}
//배관 각도
df = GetDefinition(bracing, "PipeAngle");
if (df != null)
{
Parameter paramPipeAngle = bracing.get_Parameter(df);
if (paramPipeAngle != null)
paramPipeAngle.Set(Util.DTR(45));
}
//버팀대 길이
df = GetDefinition(bracing, "Totaldist");
if (df != null)
{
Parameter paramTdist = bracing.get_Parameter(df);
if (paramTdist != null)
paramTdist.Set(Unit.MMToFeet(1000));
}
}
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;
}
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\\Bracing");
// 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;
}
// 패밀리 존재 여부 검토
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;
}
}
}