Revit Family Lab3 - Add Formula and Material_CS
Family Lab3 - Add Formula and Material_CS_번역.docx
이번 LAB에서는 기둥패밀리를 제작하고 Lab2에 이어서 파라미터에 공식을 적용하면 재질을 설정하는 방법을 학습합니다.
1. 외부명령을 정의
2. 패밀리를 제작할 수 있는 문서의 유효성을 확인
3. 추가적을 필요한 참조평명를 추가하기
4. L자형의 프로파일을 만들어서 솔리드모델을 생성
5. 솔리드 도델을 참조면에 정렬하여 구속하기
6. 매개변수 추가하기
7. 치수를 만들어 매개변수 적용하기
8. 타입을 추가하기
9. 파라미터에 공식을 적용하기
10. 생성된 모델에 재질을 적용하기
Class
RvtCmd_FamilyCreateColumnFormulaMaterial - 기둥패밀리를 만들어서 공식및 재질 적용하는 클래스
Field
RvApp - 응용프로그램의 멤버변수
RvDoc - 작업하는 문서의 멤버변수
Method
// IExternalCommand 함수를 상속받아서 클래스를 시작하기
Execute(ExternalCommandData, string, ElementSet)
// Metric Column.rft 템플릿 파일에서 작업하는 확인하기
isRightTemplate(BuiltInCategory)
// L자형에 해당하는 참조면 2개 만들기
addReferencePlanes()
// mm단위로 입력된 값을 피트단위로 변경
mmToFeet(double) // 도움함수
// L자형 기둥에 해당하는 솔리드 모델 만들기
createSolid()
// mm단위로 입력된 값을 피트단위로 변경
mmToFeet(double) // 도움함수
// L자형의 프로파일 만들기
createProfileLShape()
// mm단위로 입력된 값을 피트단위로 변경
mmToFeet(double) // 도움함수
// 미적용: 직사각형 프로파일 만들기
createProfileRectangle()
// mm단위로 입력된 값을 피트단위로 변경
mmToFeet(double) // 도움함수
// 생성된 솔리드의 면을 참조면에 맟추어서 정렬
addAlignments(Extrusion)
// 참조면에서 객체의 기준좌표와 일치하는 면을 찾기
findFace(Extrusion, XYZ, ReferencePlane) // 도움함수
// 객체의 기준좌표와 일치하는 면을 찾기
findFace(Extrusion, XYZ) // 도움함수
// 해당되는 타입의 뷰이름과 일치하는 요소를 찾기
findElement(Type, string)
// 두께에 해당하는 파라미터 생성
addParameters()
// mm단위로 입력된 값을 피트단위로 변경
mmToFeet(double) // 도움함수
// 두께에 해당하는 치수를 작성하고 생선된 파라미터 적용하기
addDimensions()
// 기둥의 크기에 대한 유형을 입력하기
addTypes()
// 유형이름, 폭, 너비, 두께를 입력받아 새로운 유형을 만들기
addType(string, double, double, double, double)
// mm단위로 입력된 값을 피트단위로 변경
mmToFeet(double) // 도움함수
// 미적용: 유형이름, 폭, 너비를 입력받아 새로운 유형을 만들기
addType(string, double, double)
// mm단위로 입력된 값을 피트단위로 변경
mmToFeet(double) // 도움함수
// 매개변수에 공식을 대입하기
addFormulas()
// 생성된 솔리드 객체에 유리재질 적용하기
addMaterials(Extrusion)
using System; using System.Collections.Generic; using System.Linq; // in System.Core using Autodesk.Revit; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using Autodesk.Revit.ApplicationServices; namespace FamilyCs { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Automatic)] // 메소드 구문: IExternalCommand의 값을 상속받는 클래스 시작 class RvtCmd_FamilyCreateColumnFormulaMaterial : IExternalCommand { Application _app; Document _doc; public Result Execute(ExternalCommandData commandData,ref string message,ElementSet elements) { _app = commandData.Application.Application; _doc = commandData.Application.ActiveUIDocument.Document; if (!isRightTemplate(BuiltInCategory.OST_Columns)) { Util.ErrorMsg("Please open Metric Column.rft"); return Result.Failed; } addReferencePlanes(); Extrusion pSolid = createSolid(); _doc.Regenerate(); addAlignments(pSolid); addParameters(); addDimensions(); addTypes(); // 파라미터에 공식 적용하기 addFormulas(); // 만들어진 모델에 재질 적용하기 addMaterials(pSolid); return Result.Succeeded; } // 메소드 구문: 기둥패밀리 작업을 시작할수있는 문서인지 확인하기 bool isRightTemplate(BuiltInCategory targetCategory) { if (!_doc.IsFamilyDocument) { Util.ErrorMsg("This command works only in the family editor."); return false; } Category cat = _doc.Settings.Categories.get_Item(targetCategory); if (_doc.OwnerFamily == null) { Util.ErrorMsg("This command only works in the family context."); return false; } if (!cat.Id.Equals(_doc.OwnerFamily.FamilyCategory.Id)) { Util.ErrorMsg("Category of this family document does not match the context required by this command."); return false; } return true; } // 메소드 구문: L자형에 해당하는 참조면 2개 만들기 void addReferencePlanes() { double tw = mmToFeet(150.0); // thickness added for Lab2. Hard-coding for simplicity. double td = mmToFeet(150.0); View pViewPlan = findElement(typeof(ViewPlan), "Lower Ref. Level") as View; ReferencePlane refFront = findElement(typeof(ReferencePlane), "Front") as ReferencePlane; XYZ p1 = refFront.BubbleEnd; XYZ p2 = refFront.FreeEnd; XYZ pBubbleEnd = new XYZ(p1.X, p1.Y + td, p1.Z); XYZ pFreeEnd = new XYZ(p2.X, p2.Y + td, p2.Z); ReferencePlane refPlane = _doc.FamilyCreate.NewReferencePlane(pBubbleEnd, pFreeEnd, XYZ.BasisZ, pViewPlan); refPlane.Name = "OffsetH"; ReferencePlane refLeft = findElement(typeof(ReferencePlane), "Left") as ReferencePlane; p1 = refLeft.BubbleEnd; p2 = refLeft.FreeEnd; pBubbleEnd = new XYZ(p1.X + tw, p1.Y, p1.Z); pFreeEnd = new XYZ(p2.X + tw, p2.Y, p2.Z); refPlane = _doc.FamilyCreate.NewReferencePlane(pBubbleEnd, pFreeEnd, XYZ.BasisZ, pViewPlan); refPlane.Name = "OffsetV"; } // 메소드 구문: L자형 기둥에 해당하는 솔리드 모델 만들기 Extrusion createSolid() { CurveArrArray pProfile = createProfileLShape(); ReferencePlane pRefPlane = findElement(typeof(ReferencePlane), "Reference Plane") as ReferencePlane; SketchPlane pSketchPlane = SketchPlane.Create(_doc, pRefPlane.Plane); double dHeight = mmToFeet(4000.0); bool bIsSolid = true; return _doc.FamilyCreate.NewExtrusion(bIsSolid, pProfile, pSketchPlane, dHeight); } // 메소드 구문: L자형의 프로파일 만들기 CurveArrArray createProfileLShape() { double w = mmToFeet(600.0); double d = mmToFeet(600.0); double tw = mmToFeet(150.0); double td = mmToFeet(150.0); const int nVerts = 6; XYZ[] pts = new XYZ[] { new XYZ(-w / 2.0, -d / 2.0, 0.0), new XYZ(w / 2.0, -d / 2.0, 0.0), new XYZ(w / 2.0, (-d / 2.0) + td, 0.0), new XYZ((-w / 2.0) + tw, (-d / 2.0) + td, 0.0), new XYZ((-w / 2.0) + tw, d / 2.0, 0.0), new XYZ(-w / 2.0, d / 2.0, 0.0), new XYZ(-w / 2.0, -d / 2.0, 0.0) }; CurveArray pLoop = _app.Create.NewCurveArray(); for (int i = 0; i < nVerts; ++i) { Line line = Line.CreateBound(pts[i], pts[i + 1]); pLoop.Append(line); } CurveArrArray pProfile = _app.Create.NewCurveArrArray(); pProfile.Append(pLoop); return pProfile; } // 메소드 구문: 미적용: 직사각형 프로파일 만들기 CurveArrArray createProfileRectangle() { double w = mmToFeet(600.0); double d = mmToFeet(600.0); const int nVerts = 4; XYZ[] pts = new XYZ[] { new XYZ(-w / 2.0, -d / 2.0, 0.0), new XYZ(w / 2.0, -d / 2.0, 0.0), new XYZ(w / 2.0, d / 2.0, 0.0), new XYZ(-w / 2.0, d / 2.0, 0.0), new XYZ(-w / 2.0, -d / 2.0, 0.0) }; CurveArray pLoop = _app.Create.NewCurveArray(); for (int i = 0; i < nVerts; ++i) { Line line = Line.CreateBound(pts[i], pts[i + 1]); pLoop.Append(line); } CurveArrArray pProfile = _app.Create.NewCurveArrArray(); pProfile.Append(pLoop); return pProfile; } // 메소드 구문: 생성된 솔리드의 면을 참조면에 맟추어서 정렬 void addAlignments(Extrusion pBox) { View pView = findElement(typeof(View), "Front") as View; Level upperLevel = findElement(typeof(Level), "Upper Ref Level") as Level; Reference ref1 = upperLevel.PlaneReference; PlanarFace upperFace = findFace(pBox, new XYZ(0.0, 0.0, 1.0)); Reference ref2 = upperFace.Reference; _doc.FamilyCreate.NewAlignment(pView, ref1, ref2); Level lowerLevel = findElement(typeof(Level), "Lower Ref. Level") as Level; Reference ref3 = lowerLevel.PlaneReference; PlanarFace lowerFace = findFace(pBox, new XYZ(0.0, 0.0, -1.0)); Reference ref4 = lowerFace.Reference; _doc.FamilyCreate.NewAlignment(pView, ref3, ref4); View pViewPlan = findElement(typeof(ViewPlan), "Lower Ref. Level") as View; ReferencePlane refRight = findElement(typeof(ReferencePlane), "Right") as ReferencePlane; ReferencePlane refLeft = findElement(typeof(ReferencePlane), "Left") as ReferencePlane; ReferencePlane refFront = findElement(typeof(ReferencePlane), "Front") as ReferencePlane; ReferencePlane refBack = findElement(typeof(ReferencePlane), "Back") as ReferencePlane; ReferencePlane refOffsetV = findElement(typeof(ReferencePlane), "OffsetV") as ReferencePlane; ReferencePlane refOffsetH = findElement(typeof(ReferencePlane), "OffsetH") as ReferencePlane; PlanarFace faceRight = findFace(pBox, new XYZ(1.0, 0.0, 0.0), refRight); PlanarFace faceLeft = findFace(pBox, new XYZ(-1.0, 0.0, 0.0)); PlanarFace faceFront = findFace(pBox, new XYZ(0.0, -1.0, 0.0)); PlanarFace faceBack = findFace(pBox, new XYZ(0.0, 1.0, 0.0), refBack); PlanarFace faceOffsetV = findFace(pBox, new XYZ(1.0, 0.0, 0.0), refOffsetV); PlanarFace faceOffsetH = findFace(pBox, new XYZ(0.0, 1.0, 0.0), refOffsetH); _doc.FamilyCreate.NewAlignment(pViewPlan, refRight.Reference, faceRight.Reference); _doc.FamilyCreate.NewAlignment(pViewPlan, refLeft.Reference, faceLeft.Reference); _doc.FamilyCreate.NewAlignment(pViewPlan, refFront.Reference, faceFront.Reference); _doc.FamilyCreate.NewAlignment(pViewPlan, refBack.Reference, faceBack.Reference); _doc.FamilyCreate.NewAlignment(pViewPlan, refOffsetV.Reference, faceOffsetV.Reference); _doc.FamilyCreate.NewAlignment(pViewPlan, refOffsetH.Reference, faceOffsetH.Reference); } // 메소드 구문: 두께에 해당하는 파라미터 생성 void addParameters() { FamilyManager mgr = _doc.FamilyManager; FamilyParameter paramTw = mgr.AddParameter("Tw", BuiltInParameterGroup.PG_GEOMETRY,ParameterType.Length, false); FamilyParameter paramTd = mgr.AddParameter("Td", BuiltInParameterGroup.PG_GEOMETRY,ParameterType.Length, false); double tw = mmToFeet(150.0); double td = mmToFeet(150.0); mgr.Set(paramTw, tw); mgr.Set(paramTd, td); } // 메소드 구문: 두께에 해당하는 치수를 작성하고 생선된 파라미터 적용하기 void addDimensions() { View pViewPlan = findElement(typeof(ViewPlan), "Lower Ref. Level") as View; ReferencePlane refLeft = findElement(typeof(ReferencePlane), "Left") as ReferencePlane; ReferencePlane refFront = findElement(typeof(ReferencePlane), "Front") as ReferencePlane; ReferencePlane refOffsetV = findElement(typeof(ReferencePlane), "OffsetV") as ReferencePlane; // OffsetV is added for L-shape ReferencePlane refOffsetH = findElement(typeof(ReferencePlane), "OffsetH") as ReferencePlane; // OffsetH is added for L-shape XYZ p0 = refLeft.FreeEnd; XYZ p1 = refOffsetV.FreeEnd; Line pLine = Line.CreateBound(p0, p1); ReferenceArray pRefArray = new ReferenceArray(); pRefArray.Append(refLeft.Reference); pRefArray.Append(refOffsetV.Reference); Dimension pDimTw = _doc.FamilyCreate.NewDimension(pViewPlan, pLine, pRefArray); FamilyParameter paramTw = _doc.FamilyManager.get_Parameter("Tw"); pDimTw.FamilyLabel = paramTw; p0 = refFront.FreeEnd; p1 = refOffsetH.FreeEnd; pLine = Line.CreateBound(p0, p1); pRefArray = new ReferenceArray(); pRefArray.Append(refFront.Reference); pRefArray.Append(refOffsetH.Reference); Dimension pDimTd = _doc.FamilyCreate.NewDimension(pViewPlan, pLine, pRefArray); FamilyParameter paramTd = _doc.FamilyManager.get_Parameter("Td"); pDimTd.FamilyLabel = paramTd; } // 메소드 구문: 기둥의 크기에 대한 유형을 입력하기 void addTypes() { addType("600x900", 600.0, 900.0, 150.0, 225.0); addType("1000x300", 1000.0, 300.0, 250.0, 75.0); addType("600x600", 600.0, 600.0, 150.0, 150.0); } // 메소드 구문: 유형이름, 폭, 너비, 두께를 입력받아 새로운 유형을 만들기- Version 2 void addType(string name, double w, double d, double tw, double td) { FamilyManager pFamilyMgr = _doc.FamilyManager; FamilyType type1 = pFamilyMgr.NewType(name); FamilyParameter paramW = pFamilyMgr.get_Parameter("Width"); double valW = mmToFeet(w); if (paramW != null) { pFamilyMgr.Set(paramW, valW); } FamilyParameter paramD = pFamilyMgr.get_Parameter("Depth"); double valD = mmToFeet(d); if (paramD != null) { pFamilyMgr.Set(paramD, valD); } FamilyParameter paramTw = pFamilyMgr.get_Parameter("Tw"); double valTw = mmToFeet(tw); if (paramTw != null) { pFamilyMgr.Set(paramTw, valTw); } FamilyParameter paramTd = pFamilyMgr.get_Parameter("Td"); double valTd = mmToFeet(td); if (paramTd != null) { pFamilyMgr.Set(paramTd, valTd); } } // 메소드 구문: 유형이름, 폭, 너비를 입력받아 새로운 유형을 만들기- Version 1 void addType(string name, double w, double d) { FamilyManager pFamilyMgr = _doc.FamilyManager; FamilyType type1 = pFamilyMgr.NewType(name); FamilyParameter paramW = pFamilyMgr.get_Parameter("Width"); double valW = mmToFeet(w); if (paramW != null) { pFamilyMgr.Set(paramW, valW); } FamilyParameter paramD = pFamilyMgr.get_Parameter("Depth"); double valD = mmToFeet(d); if (paramD != null) { pFamilyMgr.Set(paramD, valD); } } // 메소드 구문: 파라미터에 공식을 적용하기 public void addFormulas() { // Tw = Width / 4.0 , Td = Depth / 4.0 // 현재문서에서 FamilyManager 가져오기 FamilyManager pFamilyMgr = _doc.FamilyManager; // Tw, Td 파리미터 가져오기 FamilyParameter paramTw = pFamilyMgr.get_Parameter("Tw"); FamilyParameter paramTd = pFamilyMgr.get_Parameter("Td"); // 파라미터에 공식 적용하기 pFamilyMgr.SetFormula(paramTw, "Width / 4.0"); pFamilyMgr.SetFormula(paramTd, "Depth / 4.0"); } // 메소드 구문: 미적용: 생성된 모델에 재질 적용하기 public void addMaterialsToSolid(Extrusion pSolid) { Material pMat = findElement(typeof(Material), "Glass") as Material; if (pMat != null) { // 주어진 이름을 가진 재질이 없습니다. ElementId idMat = pMat.Id; pSolid.get_Parameter("Material").Set(idMat); } } // 메소드 구문: 생성된 모델에 재질 적용하기 public void addMaterials(Extrusion pSolid) { // 자료 유형에 "유리" 재질이 있는 것으로 추정된다. // "Metric Column.rft" 탬플릿은 "Glass"재질을 포함하며, 이는 실제로 효과를 볼 수있는 흥미로운 사실이다. // 실제로 당신은 탬플릿에 포함할 것이다. // 정보: UI에 더 적합한 것을 만들고 그것을 여기 이름을 사용합니다. // 유리 재질 ID가져오기 Material pMat = findElement(typeof(Material), "Glass") as Material; if (pMat != null) { ElementId idMat = pMat.Id; // 재질 마감에 대한 매개변수 추가하기 // 이 시간 우리는 인스턴스 레벨에서 변경이 될수 있도록 인스턴스 매개변수를 사용할것입니다. FamilyManager pFamilyMgr = _doc.FamilyManager; FamilyParameter famParamFinish = pFamilyMgr.AddParameter("ColumnFinish", BuiltInParameterGroup.PG_MATERIALS, ParameterType.Material, true); // 방금 추가한 패밀리 매개변수를 재질 매개변수에 연결한다 Parameter paramMat = pSolid.get_Parameter("Material"); pFamilyMgr.AssociateElementParameterToFamilyParameter(paramMat, famParamFinish); // 유리타입을 추가로 설정하고 유리재질 적용하기 addType("Glass", 600.0, 600.0); pFamilyMgr.Set(famParamFinish, idMat); } } // 메소드 구문: 도움함수: 참조면에서 객체의 기준좌표와 일치하는 면을 찾기 PlanarFace findFace(Extrusion pBox, XYZ normal, ReferencePlane refPlane) { Options op = new Options(); op.ComputeReferences = true; GeometryElement geomElem = pBox.get_Geometry(op); foreach (GeometryObject geomObj in geomElem) { if (geomObj is Solid) { Solid pSolid = geomObj as Solid; FaceArray faces = pSolid.Faces; foreach (Face pFace in faces) { PlanarFace pPlanarFace = pFace as PlanarFace; if ((pPlanarFace != null) && pPlanarFace.Normal.IsAlmostEqualTo(normal)) { XYZ p0 = refPlane.BubbleEnd; XYZ p1 = refPlane.FreeEnd; Line pCurve = Line.CreateBound(p0, p1); if (pPlanarFace.Intersect(pCurve) == SetComparisonResult.Subset) { return pPlanarFace; } } } } } return null; } // 메소드 구문: 도움함수: 객체의 기준좌표와 일치하는 면을 찾기 PlanarFace findFace(Extrusion pBox, XYZ normal) { Options op = new Options(); op.ComputeReferences = true; GeometryElement geomElem = pBox.get_Geometry(op); foreach (GeometryObject geomObj in geomElem) { if (geomObj is Solid) { Solid pSolid = geomObj as Solid; FaceArray faces = pSolid.Faces; foreach (Face pFace in faces) { PlanarFace pPlanarFace = pFace as PlanarFace; if ((pPlanarFace != null) && pPlanarFace.Normal.IsAlmostEqualTo(normal)) { return pPlanarFace; } } } } return null; } // 메소드 구문: 도움함수: 해당되는 타입의 뷰이름과 일치하는 요소를 찾기 Element findElement(Type targetType, string targetName) { FilteredElementCollector collector = new FilteredElementCollector(_doc); collector.WherePasses(new ElementClassFilter(targetType)); var targetElems = from element in collector where element.Name.Equals(targetName) select element; Listelems = targetElems.ToList (); if (elems.Count > 0) { return elems[0]; } return null; } // 메소드 구문: 도움함수: mm단위로 입력된 값을 피트단위로 변경 double mmToFeet(double mmVal) { return (mmVal / 304.8); } } }
'Revit > Revit API' 카테고리의 다른 글
CreateDimensions (0) | 2014.01.24 |
---|---|
[레빗 API 시작하기] Revit Family Lab4 - Add Visibility Control_CS (0) | 2014.01.08 |
[레빗 API 시작하기] Revit Family Lab2 - Create L-Shape Column_CS (0) | 2014.01.08 |
[레빗 API 시작하기] Revit Family Lab1 - Create Rectangular Column_CS (0) | 2014.01.08 |
[레빗 API 시작하기] Revit Ui Lab4 - Event (0) | 2014.01.08 |