470 lines
19 KiB
C#
470 lines
19 KiB
C#
using Autodesk.Revit.UI;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Autodesk.Revit.DB;
|
|
using Autodesk.Revit.UI.Selection;
|
|
using System.Threading.Tasks;
|
|
using KMBIM.Revit.Tools.Cmd.MatchProp;
|
|
using KDCS.Utils;
|
|
using System.Collections;
|
|
using System.Windows.Forms;
|
|
using KMBIM.Revit.Tools;
|
|
using Autodesk.Revit.DB.Plumbing;
|
|
using Autodesk.Revit.DB.Mechanical;
|
|
|
|
namespace KMBIM
|
|
{
|
|
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
|
|
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
|
|
[Autodesk.Revit.Attributes.Journaling(Autodesk.Revit.Attributes.JournalingMode.NoCommandData)]
|
|
|
|
public class MatchProp : IExternalCommand
|
|
{
|
|
private UIApplication uiapp = null;
|
|
private UIDocument uidoc = null;
|
|
private Autodesk.Revit.ApplicationServices.Application app = null;
|
|
private Document doc = null;
|
|
|
|
public Result Execute(ExternalCommandData commandData, ref string message, Autodesk.Revit.DB.ElementSet elements)
|
|
{
|
|
try
|
|
{
|
|
if (!WorkMain.GetInstance().IsValid) return Autodesk.Revit.UI.Result.Succeeded;
|
|
Element eSrc = null;
|
|
|
|
// Verify active document
|
|
if (null == commandData.Application.ActiveUIDocument.Document)
|
|
{
|
|
message = "현재 활성화된 뷰가 없습니다.";
|
|
return Result.Failed;
|
|
}
|
|
|
|
uiapp = commandData.Application;
|
|
uidoc = uiapp.ActiveUIDocument;
|
|
app = uiapp.Application;
|
|
doc = uidoc.Document;
|
|
|
|
// 선택한 패밀리요소로부터 파라미터를 복사합니다.
|
|
try
|
|
{
|
|
var r = uidoc.Selection.PickObject(ObjectType.Element, "파라미터를 복사할 기준 패밀리 선택: ");
|
|
if (r == null) return Result.Succeeded;
|
|
|
|
eSrc = doc.GetElement(r.ElementId);
|
|
if (eSrc != null)
|
|
{
|
|
FormSelectParameter1 wf = new FormSelectParameter1(eSrc);
|
|
wf.ShowDialog();
|
|
}
|
|
}
|
|
catch (OperationCanceledException)
|
|
{
|
|
return Result.Cancelled;
|
|
}
|
|
|
|
if (eSrc != null)
|
|
{
|
|
// 파라미터 복사(리스트박스-다중선택)
|
|
FormSelectParameter1 wf = new FormSelectParameter1(eSrc);
|
|
}
|
|
|
|
if (eSrc == null)// 파라미터를 복사한 경우에만 처리
|
|
{
|
|
MessageBox.Show("이 명령을 실행하기 전에 매개변수를 복사해야 합니다.");
|
|
return Result.Failed;
|
|
}
|
|
|
|
if (eSrc.IsValidObject != true) // 복사한 파라미터의 소유자(패밀리요소)가 삭제되어 유효하지 않는 경우
|
|
{
|
|
MessageBox.Show("복사한 파라미터의 소유자(패밀리요소)가 더이상 유효하지 않습니다.");
|
|
return Result.Failed;
|
|
}
|
|
var wm = WorkMain.GetInstance();
|
|
eSrc = wm.CopiedParametersElement;
|
|
var ListElementParameter = wm.CopiedParameters; // 복사한 파라미터
|
|
|
|
|
|
// 복사 대상 요소 선택
|
|
string msg = "매개변수 값을 붙여넣을 패밀리 선택: ";
|
|
List<Element> eList = SelectMultipleElements(uidoc, doc, msg);
|
|
List<Parameter> pa = new List<Parameter>();
|
|
if (eList == null) return Result.Succeeded;
|
|
|
|
pa = GetCopyParameterList(eList);//바뀐 파이프와 덕트 정보 가져오기(파이프: 관경 / 덕트: 높이, 폭, 관경)
|
|
|
|
//레듀셔를 선택하더라도 리스트에서 제외
|
|
List<Element> last = new List<Element>();
|
|
foreach (Element eTarget in eList)
|
|
{
|
|
if (GetFamilyPartType(eTarget, PartType.Transition) || eTarget is Level)
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
last.Add(eTarget);
|
|
}
|
|
}
|
|
|
|
using (Transaction tx = new Transaction(doc))
|
|
{
|
|
tx.Start("update-parameter-value");
|
|
|
|
foreach (Element eTarget in last)
|
|
{
|
|
if (eTarget == null) return Result.Succeeded;
|
|
|
|
doc.Regenerate();
|
|
|
|
if (eTarget == eSrc) continue;
|
|
|
|
Hashtable htTargetParameters = new Hashtable();
|
|
FamilyInstance famInst = null;
|
|
|
|
var parameters = eTarget.GetOrderedParameters().ToList();
|
|
|
|
//예외 선언
|
|
if (eSrc is Pipe && eTarget is Duct)
|
|
{
|
|
MessageBox.Show("파이프 특성을 덕트에 매치할 수 없습니다.", "오류");
|
|
return Result.Succeeded;
|
|
}
|
|
else if (eSrc is Duct && eTarget is Pipe)
|
|
{
|
|
MessageBox.Show("덕트 특성을 파이프에 매치할 수 없습니다.", "오류");
|
|
return Result.Succeeded;
|
|
}
|
|
|
|
if (eTarget is Pipe || eTarget is Duct || eTarget.Category.Name.ToString() == "배관 부속류" ||
|
|
eTarget.Category.Name.ToString() == "덕트 부속류")
|
|
{
|
|
if (Util.GetFamilyPartType(eTarget, PartType.Transition))
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// 복사 대상 파라미터
|
|
htTargetParameters.Clear();
|
|
foreach (var p in parameters)
|
|
{
|
|
string strGroup = LabelUtils.GetLabelFor(p.Definition.ParameterGroup);
|
|
string strGropAndParameterName = strGroup + "/" + p.Definition.Name;
|
|
if (htTargetParameters.Contains(strGropAndParameterName) == false)
|
|
{
|
|
htTargetParameters.Add(strGropAndParameterName, p);
|
|
}
|
|
}
|
|
|
|
// 기준 요소의 파라미터 값을 대상 요소의 파라미터에 복사한다.
|
|
foreach (Parameter p in ListElementParameter)// 기준 요소 파라미터
|
|
{
|
|
string strGroup = LabelUtils.GetLabelFor(p.Definition.ParameterGroup);
|
|
string defName = p.Definition.Name;
|
|
string strGropAndParameterName = strGroup + "/" + defName;
|
|
object oParam = htTargetParameters[strGropAndParameterName];
|
|
|
|
if (oParam != null)
|
|
{
|
|
Parameter curParam = oParam as Parameter;
|
|
|
|
if (curParam.IsReadOnly == false && strGroup.Contains("ID") == false)//쓸데없는 정보 안띄우기
|
|
{
|
|
Util.SetParameterValue(curParam, Util.GetParameterValue(p));// 붙혀넣기
|
|
}
|
|
}
|
|
|
|
//덕트나 파이프 수정
|
|
if (eSrc is Pipe || eSrc is Duct || eSrc is FamilyInstance)
|
|
{
|
|
if (eTarget is Pipe || eTarget is Duct || eTarget is FamilyInstance)
|
|
{
|
|
List<Connector> conList = new List<Connector>();
|
|
|
|
conList = Util.GetElementConnectors(eTarget);//모든 커넥터 가져오기
|
|
|
|
if (defName == "지름" || defName == "높이" || defName == "폭")
|
|
{
|
|
if (eTarget is FamilyInstance)
|
|
{
|
|
famInst = eTarget as FamilyInstance;
|
|
|
|
foreach (Connector c in conList)//커넥터의 Owner 파악하기
|
|
{
|
|
//파이프 수정
|
|
ChangePipeProperties(eTarget, pa, famInst);
|
|
|
|
//덕트 수정
|
|
ChangeDuctProperties(eTarget, pa, famInst);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
tx.Commit();
|
|
}//end - Transition
|
|
}
|
|
|
|
catch (Exception ex)
|
|
{
|
|
//message = ex.ToString();
|
|
return Result.Failed;
|
|
}
|
|
|
|
return Result.Succeeded;
|
|
}
|
|
|
|
#region Element Selection
|
|
public static Element SelectSingleElement(UIDocument uidoc, string description)
|
|
{
|
|
if (ViewType.Internal == uidoc.ActiveView.ViewType)
|
|
{
|
|
string msg = "현재 보기에서 요소를 선택할 수 없습니다.";
|
|
TaskDialog.Show("Error", msg + uidoc.ActiveView.Name);
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
Reference r = uidoc.Selection.PickObject(ObjectType.Element, description);
|
|
return uidoc.Document.GetElement(r);
|
|
}
|
|
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public static List<Element> SelectMultipleElements(UIDocument uidoc, Document doc, string description)
|
|
{
|
|
if (ViewType.Internal == uidoc.ActiveView.ViewType)
|
|
{
|
|
string msg = "현재 보기에서 요소를 선택할 수 없습니다,";
|
|
TaskDialog.Show("Error", msg + uidoc.ActiveView.Name);
|
|
}
|
|
List<Element> SelElemList = new List<Element>();
|
|
try
|
|
{
|
|
IList<Reference> r = new List<Reference>();
|
|
r = uidoc.Selection.PickObjects(ObjectType.Element, description);
|
|
foreach (Reference Ref in r)
|
|
{
|
|
//SelElem = doc.GetElement(Ref.ElementId) as Element;
|
|
SelElemList.Add(doc.GetElement(Ref.ElementId) as Element);
|
|
}
|
|
return SelElemList;
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 붙혀넣을 패밀리에 BuiltInParameter값이 없는 경우 복사한 파라미터 값 넣기
|
|
/// </summary>
|
|
/// <param name="p">복사한 파라미터</param>
|
|
/// <param name="targetFamily">target 패밀리</param>
|
|
/// <param name="targeParameterName">target 파라미터 이름</param>
|
|
/// <param name="isRadius">target 파라미터가 반지름인지 여부</param>
|
|
public void SetParameterValue(Parameter copyParam, FamilyInstance targetFamily, string targeParameterName, bool isRadius)
|
|
{
|
|
Parameter targetParam = targetFamily.LookupParameter(targeParameterName);//targetParameterName 찾기
|
|
|
|
if (targetParam != null)
|
|
{
|
|
if (isRadius == true)//targetParameter가 반지름일 경우에 나누기 2
|
|
{
|
|
targetParam.Set(copyParam.AsDouble() / 2);
|
|
}
|
|
else
|
|
{
|
|
targetParam.Set(copyParam.AsDouble());
|
|
}
|
|
}
|
|
}
|
|
|
|
public List<Parameter> GetCopyParameterList(List<Element> eList)
|
|
{
|
|
List<Parameter> paramList = new List<Parameter>();
|
|
|
|
foreach (Element eTarget in eList)
|
|
{
|
|
if (eTarget is Pipe)//파이프인 경우
|
|
{
|
|
Parameter pipeParam = eTarget.get_Parameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);//관경
|
|
paramList.Add(pipeParam);
|
|
}
|
|
else if (eTarget is Duct)//덕트인 경우
|
|
{
|
|
//바뀐 덕트 정보 가져오기
|
|
Parameter ductHeightParam = eTarget.get_Parameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);//높이
|
|
Parameter ductWidthParam = eTarget.get_Parameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);//폭
|
|
Parameter ductDiameterParam = eTarget.get_Parameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM);//관경(원형덕트)
|
|
|
|
if (ductHeightParam != null)
|
|
{
|
|
paramList.Add(ductHeightParam);
|
|
}
|
|
if (ductWidthParam != null)
|
|
{
|
|
paramList.Add(ductWidthParam);
|
|
}
|
|
if (ductDiameterParam != null)//원형덕트
|
|
{
|
|
paramList.Add(ductDiameterParam);
|
|
}
|
|
}
|
|
}
|
|
|
|
return paramList;
|
|
}
|
|
|
|
//패밀리의 타입구분
|
|
public static bool GetFamilyPartType(Element element, PartType partType)
|
|
{
|
|
List<Connector> ConLst = GetElementConnectors(element);
|
|
if (ConLst == null || ConLst.Count() <= 0) return false;
|
|
|
|
Connector baseCon = ConLst.First();
|
|
|
|
if (baseCon.Owner is FamilyInstance)
|
|
{
|
|
FamilyInstance family = baseCon.Owner as FamilyInstance;
|
|
Parameter param = family.Symbol.Family.get_Parameter(BuiltInParameter.FAMILY_CONTENT_PART_TYPE);
|
|
if (partType == (PartType)param.AsInteger())
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//객체의 커넥터 구하기.(파이프,덕트,패밀리)
|
|
public static List<Connector> GetElementConnectors(Element elem)
|
|
{
|
|
List<Connector> ConLst = new List<Connector>();
|
|
ConnectorSet connectorSet = null;
|
|
|
|
if (elem is Pipe)
|
|
connectorSet = (elem as Pipe).ConnectorManager.Connectors;
|
|
else if (elem is Duct)
|
|
connectorSet = (elem as Duct).ConnectorManager.Connectors;
|
|
else if (elem is FamilyInstance)
|
|
connectorSet = (elem as FamilyInstance).MEPModel.ConnectorManager.Connectors;
|
|
|
|
if (connectorSet == null) return null;
|
|
|
|
foreach (Connector con in connectorSet)
|
|
{
|
|
ConLst.Add(con);
|
|
}
|
|
|
|
return ConLst;
|
|
}
|
|
|
|
public void ChangePipeProperties(Element eTarget, List<Parameter> pa, FamilyInstance famInst)
|
|
{
|
|
if (eTarget.Category.Name.ToString() == "배관 부속류")//Pipe부속인 경우
|
|
{
|
|
foreach (Parameter pm in pa)
|
|
{
|
|
Parameter param = famInst.Symbol.Family.get_Parameter(BuiltInParameter.FAMILY_CONTENT_PART_TYPE);
|
|
PartType partType = (PartType)param.AsInteger();
|
|
|
|
switch (partType.ToString())
|
|
{
|
|
case "Elbow":
|
|
SetParameterValue(pm, famInst, "공칭 반지름", true);
|
|
break;
|
|
|
|
case "Tee":
|
|
SetParameterValue(pm, famInst, "공칭 반지름", true);
|
|
break;
|
|
|
|
case "Cross":
|
|
SetParameterValue(pm, famInst, "공칭 반지름", true);
|
|
break;
|
|
|
|
case "Wye":
|
|
SetParameterValue(pm, famInst, "공칭 반지름", true);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ChangeDuctProperties(Element eTarget, List<Parameter> pa, FamilyInstance famInst)
|
|
{
|
|
if (eTarget.Category.Name.ToString() == "덕트 부속")//덕트 부속인 경우
|
|
{
|
|
Parameter param = famInst.Symbol.Family.get_Parameter(BuiltInParameter.FAMILY_CONTENT_PART_TYPE);
|
|
PartType partType = (PartType)param.AsInteger();
|
|
|
|
switch (partType.ToString())
|
|
{
|
|
case "Elbow":
|
|
if (famInst.LookupParameter("덕트 높이") != null)
|
|
{
|
|
SetParameterValue(pa[0], famInst, "덕트 높이", false);
|
|
}
|
|
if (famInst.LookupParameter("덕트 폭") != null)
|
|
{
|
|
SetParameterValue(pa[1], famInst, "덕트 폭", false);
|
|
}
|
|
if (famInst.LookupParameter("덕트 반지름") != null)
|
|
{
|
|
SetParameterValue(pa[0], famInst, "덕트 반지름", true);
|
|
}
|
|
break;
|
|
|
|
case "Tee":
|
|
if (famInst.LookupParameter("덕트 높이") != null)
|
|
{
|
|
SetParameterValue(pa[0], famInst, "덕트 높이", false);
|
|
}
|
|
if (famInst.LookupParameter("덕트 폭") != null)
|
|
{
|
|
SetParameterValue(pa[1], famInst, "덕트 폭", false);
|
|
}
|
|
if (famInst.LookupParameter("덕트 반지름 1") != null)
|
|
{
|
|
SetParameterValue(pa[0], famInst, "덕트 반지름 1", true);
|
|
}
|
|
break;
|
|
|
|
case "Damper":
|
|
if (famInst.LookupParameter("덕트 높이") != null)
|
|
{
|
|
SetParameterValue(pa[0], famInst, "덕트 높이", false);
|
|
}
|
|
if (famInst.LookupParameter("덕트 폭") != null)
|
|
{
|
|
SetParameterValue(pa[1], famInst, "덕트 폭", false);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if(eTarget.Category.Name.ToString() == "덕트 액세서리")
|
|
{
|
|
if (famInst.LookupParameter("덕트 높이") != null)
|
|
{
|
|
SetParameterValue(pa[0], famInst, "덕트 높이", false);
|
|
}
|
|
if (famInst.LookupParameter("덕트 폭") != null)
|
|
{
|
|
SetParameterValue(pa[1], famInst, "덕트 폭", false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
|