Revit Family Lab4 - Add Visibility Control_CS
Family Lab4 - Add Visibility Control_CS_번역.docx
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)
// Detail Level: Coares 에서 표시될 모델라인 작성하기
addLineObjects()
// 가시성 조정하기
changeVisibility(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)] class RvtCmd_FamilyCreateColumnVisibility : IExternalCommand { // member variables for top level access to the Revit database // Application _app; Document _doc; // command main // public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { // objects for the top level access // _app = commandData.Application.Application; _doc = commandData.Application.ActiveUIDocument.Document; // (0) This command works in the context of family editor only. // We also check if the template is for an appropriate category if needed. // Here we use a Column(i.e., Metric Column.rft) template. // Although there is no specific checking about metric or imperial, our lab only works in metric for now. // if (!isRightTemplate(BuiltInCategory.OST_Columns)) { Util.ErrorMsg("Please open Metric Column.rft"); return Result.Failed; } // (1.1) add reference planes addReferencePlanes(); // (1.2) create a simple extrusion. We create a L-shape extrusion. Extrusion pSolid = createSolid(); _doc.Regenerate(); // (2) add alignment addAlignments(pSolid); // (3.1) add parameters addParameters(); // (3.2) add dimensions addDimensions(); // (3.3) add types addTypes(); // (4.1) add formulas addFormulas(); // (4.2) add materials addMaterials(pSolid); // 가시성 설정하기 addLineObjects(); changeVisibility(pSolid); // finally return return Result.Succeeded; } // ============================================ // (0) check if we have a correct template // ============================================ bool isRightTemplate(BuiltInCategory targetCategory) { // This command works in the context of family editor only. // if (!_doc.IsFamilyDocument) { Util.ErrorMsg("This command works only in the family editor."); return false; } // Check the template for an appropriate category here if needed. // 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; } // if we come here, we should have a right one. return true; } // ============================== // (1.1) add reference planes // ============================== void addReferencePlanes() { // // we are defining a simple L-shape profile like the following: // // 5 tw 4 // +-+ // | | 3 h = height // d | +---+ 2 // +-----+ td // 0 1 // 6 w // // // we want to add ref planes along (1) 2-3 and (2)3-4. // Name them "OffsetH" and "OffsetV" respectively. (H for horizontal, V for vertical). // double tw = mmToFeet(150.0); // thickness added for Lab2. Hard-coding for simplicity. double td = mmToFeet(150.0); // // (1) add a horizonal ref plane 2-3. // // get a plan view View pViewPlan = (View)findElement(typeof(ViewPlan), "Lower Ref. Level"); // we have predefined ref plane: Left/Right/Front/Back // get the ref plane at Front, which is aligned to line 2-3 ReferencePlane refFront = (ReferencePlane)findElement(typeof(ReferencePlane), "Front"); // get the bubble and free ends from front ref plane and offset by td. // 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); // create a new one reference plane and name it "OffsetH" // ReferencePlane refPlane = _doc.FamilyCreate.NewReferencePlane(pBubbleEnd, pFreeEnd, XYZ.BasisZ, pViewPlan); refPlane.Name = "OffsetH"; // // (2) do the same to add a vertical reference plane. // // find the ref plane at left, which is aligned to line 3-4 ReferencePlane refLeft = (ReferencePlane)findElement(typeof(ReferencePlane), "Left"); // get the bubble and free ends from front ref plane and offset by td. // 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); // create a new reference plane and name it "OffsetV" // refPlane = _doc.FamilyCreate.NewReferencePlane(pBubbleEnd, pFreeEnd, XYZ.BasisZ, pViewPlan); refPlane.Name = "OffsetV"; } // ================================================================= // (1.2) create a simple solid by extrusion with L-shape profile // ================================================================= Extrusion createSolid() { // // (1) define a simple L-shape profile // CurveArrArray pProfile = createProfileLShape(); // // (2) create a sketch plane // // we need to know the template. If you look at the template (Metric Column.rft) and "Front" view, // you will see "Reference Plane" at "Lower Ref. Level". We are going to create an extrusion there. // findElement() is a helper function that find an element of the given type and name. see below. // ReferencePlane pRefPlane = findElement(typeof(ReferencePlane), "Reference Plane") as ReferencePlane; // need to know from the template //SketchPlane pSketchPlane = _doc.FamilyCreate.NewSketchPlane(pRefPlane.Plane); // Revit 2013 SketchPlane pSketchPlane = SketchPlane.Create(_doc, pRefPlane.Plane); // Revit 2014 // (3) height of the extrusion // // same as profile, you will need to know your template. unlike UI, the alightment will not adjust the geometry. // You will need to have the exact location in order to set alignment. // Here we hard code for simplicity. 4000 is the distance between Lower and Upper Ref. Level. // as an exercise, try changing those values and see how it behaves. // double dHeight = mmToFeet(4000.0); // (4) create an extrusion here. at this point. just an box, nothing else. // bool bIsSolid = true; // as oppose to void. return _doc.FamilyCreate.NewExtrusion(bIsSolid, pProfile, pSketchPlane, dHeight); } // =========================================== // (1.2a) create a simple L-shaped profile // =========================================== CurveArrArray createProfileLShape() { // // define a simple L-shape profile // // 5 tw 4 // +-+ // | | 3 h = height // d | +---+ 2 // +-----+ td // 0 1 // 6 w // // sizes (hard coded for simplicity) // note: these need to match reference plane. otherwise, alignment won't work. // as an exercise, try changing those values and see how it behaves. // double w = mmToFeet(600.0); // those are hard coded for simplicity here. in practice, you may want to find out from the references) double d = mmToFeet(600.0); double tw = mmToFeet(150.0); // thickness added for Lab2 double td = mmToFeet(150.0); // define vertices // const int nVerts = 6; // the number of vertices 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) }; // the last one is to make the loop simple // define a loop. define individual edges and put them in a curveArray // CurveArray pLoop = _app.Create.NewCurveArray(); for (int i = 0; i < nVerts; ++i) { //Line line = _app.Create.NewLineBound(pts[i], pts[i + 1]); // Revit 2013 Line line = Line.CreateBound(pts[i], pts[i + 1]); // Revit 2014 pLoop.Append(line); } // then, put the loop in the curveArrArray as a profile // CurveArrArray pProfile = _app.Create.NewCurveArrArray(); pProfile.Append(pLoop); // if we come here, we have a profile now. return pProfile; } // ============================================== // (1.2b) create a simple rectangular profile // ============================================== CurveArrArray createProfileRectangle() { // // define a simple rectangular profile // // 3 2 // +---+ // | | d h = height // +---+ // 0 1 // 4 w // // sizes (hard coded for simplicity) // note: these need to match reference plane. otherwise, alignment won't work. // as an exercise, try changing those values and see how it behaves. // double w = mmToFeet(600.0); double d = mmToFeet(600.0); // define vertices // const int nVerts = 4; // the number of vertices 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) }; // define a loop. define individual edges and put them in a curveArray // CurveArray pLoop = _app.Create.NewCurveArray(); for (int i = 0; i < nVerts; ++i) { //Line line = _app.Create.NewLineBound(pts[i], pts[i + 1]); // Revit 2013 Line line = Line.CreateBound(pts[i], pts[i + 1]); // Revit 2014 pLoop.Append(line); } // then, put the loop in the curveArrArray as a profile // CurveArrArray pProfile = _app.Create.NewCurveArrArray(); pProfile.Append(pLoop); // if we come here, we have a profile now. return pProfile; } // ====================================== // (2.1) add alignments // ====================================== void addAlignments(Extrusion pBox) { // // (1) we want to constrain the upper face of the column to the "Upper Ref Level" // // which direction are we looking at? // View pView = findElement(typeof(View), "Front") as View; // find the upper ref level // findElement() is a helper function. see below. // Level upperLevel = findElement(typeof(Level), "Upper Ref Level") as Level; Reference ref1 = upperLevel.PlaneReference; // find the face of the box // findFace() is a helper function. see below. // PlanarFace upperFace = findFace(pBox, new XYZ(0.0, 0.0, 1.0)); // find a face whose normal is z-up. Reference ref2 = upperFace.Reference; // create alignments // _doc.FamilyCreate.NewAlignment(pView, ref1, ref2); // // (2) do the same for the lower level // // find the lower ref level // findElement() is a helper function. see below. // Level lowerLevel = findElement(typeof(Level), "Lower Ref. Level") as Level; Reference ref3 = lowerLevel.PlaneReference; // find the face of the box // findFace() is a helper function. see below. PlanarFace lowerFace = findFace(pBox, new XYZ(0.0, 0.0, -1.0)); // find a face whose normal is z-down. Reference ref4 = lowerFace.Reference; // create alignments // _doc.FamilyCreate.NewAlignment(pView, ref3, ref4); // // (3) same idea for the Right/Left/Front/Back // // get the plan view // note: same name maybe used for different view types. either one should work. View pViewPlan = findElement(typeof(ViewPlan), "Lower Ref. Level") as View; // find reference planes 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; // added for L-shape ReferencePlane refOffsetH = findElement(typeof(ReferencePlane), "OffsetH") as ReferencePlane; // added for L-shape // find the face of the box // Note: findFace need to be enhanced for this as face normal is not enough to determine the face. // PlanarFace faceRight = findFace(pBox, new XYZ(1.0, 0.0, 0.0), refRight); // modified for L-shape 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); // modified for L-shape PlanarFace faceOffsetV = findFace(pBox, new XYZ(1.0, 0.0, 0.0), refOffsetV); // added for L-shape PlanarFace faceOffsetH = findFace(pBox, new XYZ(0.0, 1.0, 0.0), refOffsetH); // added for L-shape // create alignments // _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); // added for L-shape _doc.FamilyCreate.NewAlignment(pViewPlan, refOffsetH.Reference, faceOffsetH.Reference); // added for L-shape } // ====================================== // (3.1) add parameters // ====================================== void addParameters() { FamilyManager mgr = _doc.FamilyManager; // API parameter group for Dimension is PG_GEOMETRY: // FamilyParameter paramTw = mgr.AddParameter( "Tw", BuiltInParameterGroup.PG_GEOMETRY, ParameterType.Length, false); FamilyParameter paramTd = mgr.AddParameter( "Td", BuiltInParameterGroup.PG_GEOMETRY, ParameterType.Length, false); // set initial values: // double tw = mmToFeet(150.0); double td = mmToFeet(150.0); mgr.Set(paramTw, tw); mgr.Set(paramTd, td); // (2) add a parameter for material finish // we are adding material arameter in addMaterials function. // See addMaterials for the actual implementation. // } // ====================================== // (3.2) add dimensions // ====================================== void addDimensions() { // find the plan view // View pViewPlan = findElement(typeof(ViewPlan), "Lower Ref. Level") as View; // find reference planes // 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 // // (1) add dimension between the reference planes 'Left' and 'OffsetV', and label it as 'Tw' // // define a dimension line // XYZ p0 = refLeft.FreeEnd; XYZ p1 = refOffsetV.FreeEnd; //Line pLine = _app.Create.NewLineBound(p0, p1); // Revit 2013 Line pLine = Line.CreateBound(p0, p1); // define references // ReferenceArray pRefArray = new ReferenceArray(); pRefArray.Append(refLeft.Reference); pRefArray.Append(refOffsetV.Reference); // create a dimension // Dimension pDimTw = _doc.FamilyCreate.NewDimension(pViewPlan, pLine, pRefArray); // add label to the dimension // FamilyParameter paramTw = _doc.FamilyManager.get_Parameter("Tw"); //pDimTw.Label = paramTw; // Revit 2013 pDimTw.FamilyLabel = paramTw; // Revit 2014 // // (2) do the same for dimension between 'Front' and 'OffsetH', and lable it as 'Td' // // define a dimension line // p0 = refFront.FreeEnd; p1 = refOffsetH.FreeEnd; //pLine = _app.Create.NewLineBound(p0, p1); // Revit 2013 pLine =Line.CreateBound(p0, p1); // Revit 2014 // define references // pRefArray = new ReferenceArray(); pRefArray.Append(refFront.Reference); pRefArray.Append(refOffsetH.Reference); // create a dimension // Dimension pDimTd = _doc.FamilyCreate.NewDimension(pViewPlan, pLine, pRefArray); // add label to the dimension // FamilyParameter paramTd = _doc.FamilyManager.get_Parameter("Td"); //pDimTd.Label = paramTd; // Revit 2013 pDimTd.FamilyLabel = paramTd; } // ====================================== // (3.3) add types // ====================================== void addTypes() { // addType(name, Width, Depth) // //addType("600x900", 600.0, 900.0) //addType("1000x300", 1000.0, 300.0) //addType("600x600", 600.0, 600.0) // addType(name, Width, Depth, Tw, Td) // 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); } // add one type (version 2) // void addType(string name, double w, double d, double tw, double td) { // get the family manager from the current doc FamilyManager pFamilyMgr = _doc.FamilyManager; // add new types with the given name // FamilyType type1 = pFamilyMgr.NewType(name); // look for 'Width' and 'Depth' parameters and set them to the given value // // first 'Width' // FamilyParameter paramW = pFamilyMgr.get_Parameter("Width"); double valW = mmToFeet(w); if (paramW != null) { pFamilyMgr.Set(paramW, valW); } // same idea for 'Depth' // FamilyParameter paramD = pFamilyMgr.get_Parameter("Depth"); double valD = mmToFeet(d); if (paramD != null) { pFamilyMgr.Set(paramD, valD); } // let's set "Tw' and 'Td' // 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); } } // add one type (version 1) // void addType(string name, double w, double d) { // get the family manager from the current doc FamilyManager pFamilyMgr = _doc.FamilyManager; // add new types with the given name // FamilyType type1 = pFamilyMgr.NewType(name); // look for 'Width' and 'Depth' parameters and set them to the given value // // first 'Width' // FamilyParameter paramW = pFamilyMgr.get_Parameter("Width"); double valW = mmToFeet(w); if (paramW != null) { pFamilyMgr.Set(paramW, valW); } // same idea for 'Depth' // FamilyParameter paramD = pFamilyMgr.get_Parameter("Depth"); double valD = mmToFeet(d); if (paramD != null) { pFamilyMgr.Set(paramD, valD); } } // ====================================== // (4.1) add formula // ====================================== public void addFormulas() { // we will add the following fomulas // Tw = Width / 4.0 // Td = Depth / 4.0 // // first get the parameter FamilyManager pFamilyMgr = _doc.FamilyManager; FamilyParameter paramTw = pFamilyMgr.get_Parameter("Tw"); FamilyParameter paramTd = pFamilyMgr.get_Parameter("Td"); // set the formula pFamilyMgr.SetFormula(paramTw, "Width / 4.0"); pFamilyMgr.SetFormula(paramTd, "Depth / 4.0"); } // ====================================== // (4.2) add materials // ====================================== // // in Revit 2010, you cannot modify asset. // SPR# 155053 - WishList: Ability to access\modify properties in Render Appearance of Materials using API. // To Do in future: you can extend this functionality to create a new one in future. // // This function is only for reference. this is not used. If use this way, it is fixed at solid level. You cannot change it. // public void addMaterialsToSolid(Extrusion pSolid) { // We assume Material type "Glass" exists. Template "Metric Column.rft" include "Glass", // which in fact is the only interesting one to see the effect. // In practice, you will want to include in your template. // // To Do: For the exersize, create it with more appropriate ones in UI, then use the name here. // Material pMat = findElement(typeof(Material), "Glass") as Material; if (pMat != null) { // no material with the given name. ElementId idMat = pMat.Id; pSolid.get_Parameter("Material").Set(idMat); } } public void addMaterials(Extrusion pSolid) { // We assume Material type "Glass" exists. Template "Metric Column.rft" include "Glass", // which in fact is the only interesting one to see the effect. // In practice, you will want to include in your template. // // To Do: For the exersize, create it with more appropriate ones in UI, then use the name here. // // (1) get the materials id that we are intersted in (e.g., "Glass") // Material pMat = findElement(typeof(Material), "Glass") as Material; if (pMat != null) { ElementId idMat = pMat.Id; // (2a) this add a material to the solid base. but then, we cannot change it for each column. // //pSolid.Parameter("Material").Set(idMat) // (2b) add a parameter for material finish // // this time we use instance parameter so that we can change it at instance level. // FamilyManager pFamilyMgr = _doc.FamilyManager; FamilyParameter famParamFinish = pFamilyMgr.AddParameter("ColumnFinish", BuiltInParameterGroup.PG_MATERIALS, ParameterType.Material, true); // (2b.1) associate material parameter to the family parameter we just added // Parameter paramMat = pSolid.get_Parameter("Material"); pFamilyMgr.AssociateElementParameterToFamilyParameter(paramMat, famParamFinish); // (2b.2) for our convenience, let's add another type with Glass finish // addType("Glass", 600.0, 600.0); pFamilyMgr.Set(famParamFinish, idMat); } } // 메소드 구문: 상세수준에 따라서 표현될 간단한 선 객체 생성하기 public void addLineObjects() { // // define a simple L-shape detail line object // // 0 // + h = height // | (we also want to draw a vertical line here at point 1) // d | // +-----+ // 1 2 // w // // sizes double w = mmToFeet(600.0); // modified to match reference plane. otherwise, alignment won't work. double d = mmToFeet(600.0); double h = mmToFeet(4000.0); // distance between Lower and Upper Ref Level. double t = mmToFeet(50.0); // slight offset for visbility // define vertices // XYZ[] pts = new XYZ[] { new XYZ((-w / 2.0) + t, d / 2.0, 0.0), new XYZ((-w / 2.0) + t, (-d / 2.0) + t, 0.0), new XYZ(w / 2.0, (-d / 2.0) + t, 0.0) }; XYZ ptH = new XYZ((-w / 2.0) + t, (-d / 2.0) + t, h); // this is for vertical line. // // (2) create a sketch plane // // we need to know the template. If you look at the template (Metric Column.rft) and "Front" view, // you will see "Reference Plane" at "Lower Ref. Level". We are going to create a sketch plane there. // findElement() is a helper function that find an element of the given type and name. see below. // Note: we did the same in creating a profile. // ReferencePlane pRefPlane = findElement(typeof(ReferencePlane), "Reference Plane") as ReferencePlane; //SketchPlane pSketchPlane = _doc.FamilyCreate.NewSketchPlane(pRefPlane.Plane); // Revit 2013 SketchPlane pSketchPlane = SketchPlane.Create(_doc, pRefPlane.Plane); // Revit 2014 // for vertical line, we draw a straight vertical line at the point[1] XYZ normal = new XYZ(1.0, 0.0, 0.0); Plane pGeomPlaneH = _app.Create.NewPlane(normal, pts[1]); //SketchPlane pSketchPlaneH = _doc.FamilyCreate.NewSketchPlane(pGeomPlaneH); // Revit 2013 SketchPlane pSketchPlaneH = SketchPlane.Create(_doc, pGeomPlaneH); // Revit 2014 // (3) create line objects: two symbolic curves on a plan and one model curve representing a column like a vertical stick. // // Revit 2013 //Line geomLine1 = _app.Create.NewLine(pts[0], pts[1], true); //Line geomLine2 = _app.Create.NewLine(pts[1], pts[2], true); //Line geomLineH = _app.Create.NewLine(pts[1], ptH, true); // Revit 2014 Line geomLine1 = Line.CreateBound(pts[0], pts[1]); Line geomLine2 = Line.CreateBound(pts[1], pts[2]); //Line geomLineH = _app.Create.NewLine(pts[1], ptH, true); // Revit 2013 Line geomLineH = Line.CreateBound(pts[1], ptH); SymbolicCurve pLine1 = _doc.FamilyCreate.NewSymbolicCurve(geomLine1, pSketchPlane); SymbolicCurve pLine2 = _doc.FamilyCreate.NewSymbolicCurve(geomLine2, pSketchPlane); ModelCurve pLineH = _doc.FamilyCreate.NewModelCurve(geomLineH, pSketchPlaneH); // this is vertical line // set the visibilities of two lines to coarse only // FamilyElementVisibility pVis = new FamilyElementVisibility(FamilyElementVisibilityType.ViewSpecific); pVis.IsShownInFine = false; pVis.IsShownInMedium = false; pLine1.SetVisibility(pVis); pLine2.SetVisibility(pVis); FamilyElementVisibility pVisH = new FamilyElementVisibility(FamilyElementVisibilityType.Model); pVisH.IsShownInFine = false; pVisH.IsShownInMedium = false; pLineH.SetVisibility(pVisH); } // 메소드 구문: 상세수준에 따라서 솔리드 객체의 가시성 설정하기 public void changeVisibility(Extrusion pSolid) { // set the visibility of the model not to shown in coarse. // FamilyElementVisibility pVis = new FamilyElementVisibility(FamilyElementVisibilityType.Model); pVis.IsShownInCoarse = false; pSolid.SetVisibility(pVis); } #region Helper Functions // ============================================================================================= // helper function: given a solid, find a planar face with the given normal (version 2) // this is a slightly enhaced version of previous version and checks if the face is on the given reference plane. // ============================================================================================= PlanarFace findFace(Extrusion pBox, XYZ normal, ReferencePlane refPlane) { // get the geometry object of the given element // Options op = new Options(); op.ComputeReferences = true; GeometryElement geomElem = pBox.get_Geometry(op); // loop through the array and find a face with the given normal // foreach (GeometryObject geomObj in geomElem) { if (geomObj is Solid) // solid is what we are interested in. { Solid pSolid = geomObj as Solid; FaceArray faces = pSolid.Faces; foreach (Face pFace in faces) { PlanarFace pPlanarFace = pFace as PlanarFace; // check to see if they have same normal if ((pPlanarFace != null) && pPlanarFace.Normal.IsAlmostEqualTo(normal)) { // additionally, we want to check if the face is on the reference plane // XYZ p0 = refPlane.BubbleEnd; XYZ p1 = refPlane.FreeEnd; // Line pCurve = _app.Create.NewLineBound(p0, p1); // Revit 2013 Line pCurve = Line.CreateBound(p0, p1); // Revit 2014 if (pPlanarFace.Intersect(pCurve) == SetComparisonResult.Subset) { return pPlanarFace; // we found the face } } } } // will come back later as needed. // //else if (geomObj is Instance) //{ //} //else if (geomObj is Curve) //{ //} //else if (geomObj is Mesh) //{ //} } // if we come here, we did not find any. return null; } // ============================================================= // helper function: find a planar face with the given normal // ============================================================= PlanarFace findFace(Extrusion pBox, XYZ normal) { // get the geometry object of the given element // Options op = new Options(); op.ComputeReferences = true; GeometryElement geomElem = pBox.get_Geometry(op); // loop through the array and find a face with the given normal // foreach (GeometryObject geomObj in geomElem) { if (geomObj is Solid) // solid is what we are interested in. { Solid pSolid = (Solid)geomObj; FaceArray faces = pSolid.Faces; foreach (Face pFace in faces) { PlanarFace pPlanarFace = (PlanarFace)pFace; if ((pPlanarFace != null) && pPlanarFace.Normal.IsAlmostEqualTo(normal)) // we found the face { return pPlanarFace; } } } // will come back later as needed. // //else if (geomObj is Instance) //{ //} //else if (geomObj is Curve) //{ //} //else if (geomObj is Mesh) //{ //} } // if we come here, we did not find any. return null; } // ================================================================================== // helper function: find an element of the given type and the name. // You can use this, for example, to find Reference or Level with the given name. // ================================================================================== Element findElement(Type targetType, string targetName) { // get the elements of the given type // FilteredElementCollector collector = new FilteredElementCollector(_doc); collector.WherePasses(new ElementClassFilter(targetType)); // parse the collection for the given name // using LINQ query here. // var targetElems = from element in collector where element.Name.Equals(targetName) select element; Listelems = targetElems.ToList (); if (elems.Count > 0) { // we should have only one with the given name. return elems[0]; } // cannot find it. return null; } // =============================================== // helper function: convert millimeter to feet // =============================================== double mmToFeet(double mmVal) { return mmVal / 304.8; } #endregion // Helper Functions } }
'Revit > Revit API' 카테고리의 다른 글
CreateDimensions (0) | 2014.01.24 |
---|---|
[레빗 API 시작하기] Revit Family Lab3 - Add Formula and Material_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 |