วันเสาร์ที่ 20 ธันวาคม พ.ศ. 2557

สร้าง พื้น FLOOR ใน Revit

การสร้างพื้น จะซับซ้อน นิดหนึ่ง เนื่องจาก Floor เป็น System Family โดยที่ต้องมี Boundary จึงจะสร้าง ได้
ใน Code เป็นตัวอย่างการสร้าง พื้น8เหลี่ยม จะมีการสร้าง profile ก่อน  แล้วจึงเลือก พื้น

 public static void BatchCreateFloor(XYZ pt, Autodesk.Revit.DB.Document doc, Level level)
        { // ค้นเฉพาะพื้น
            List<FloorType> fl = listFloor(doc);
            int floorsides=8;// แปดเหลี่ยม
             CurveArray profile = new CurveArray();
            XYZ location=pt;
            double floorradius=m2f(5);// รัศมี 5 เมตร
        for (int i = 0; i < floorsides; i++)
        {
            double curAngle = i * Math.PI / floorsides * 2;
            double nextAngle = (i < floorsides - 1 ? i + 1 : 0) * Math.PI / floorsides * 2;

            XYZ curVertex = new XYZ(location.X + floorradius * Math.Cos(curAngle), location.Y + floorradius * Math.Sin(curAngle), location.Z);
            XYZ nextVertex = new XYZ(location.X + floorradius * Math.Cos(nextAngle), location.Y + floorradius * Math.Sin(nextAngle), location.Z);
            Line line =  Line.CreateBound(curVertex,nextVertex);
              
            profile.Append(line);
        }
            // เลือก
            Autodesk.Revit.Creation.Document creation_doc = doc.Create;
            // เอาตัวแรกมาวาด         
            creation_doc.NewFloor(profile, fl[0],level,true);
        }
        static List<FloorType> listFloor(Autodesk.Revit.DB.Document doc)
        {
            List<FloorType> m_FlTypeCollection = new List<FloorType>();

            FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
            filteredElementCollector.OfClass(typeof(FloorType));// กรองเฉพาะ พื้น
            m_FlTypeCollection = filteredElementCollector.Cast<FloorType>().ToList<FloorType>();

            return m_FlTypeCollection;
        }

        


วันจันทร์ที่ 8 ธันวาคม พ.ศ. 2557

การใช้ PickPoint ใน Revit

ในการเลือกจุด ใน Revit  มี 2 แบบ ได้แก่ การเลือก (pt) จากจุดใดๆ

XYZ pt = _uiDoc.Selection.PickPoint( "Pick a point" );

การเลือกจะ ให้เลือกบนจอ และมี Prompt แสดง
อีกแบบที่จะใช้ใน Application บ่อยๆ ได้แก่ การเลือกบน Object เช่น กำแพง

Reference r = _uiDoc.Selection.PickObject(
        ObjectType.PointOnElement,
        "Select a point on element" );

      Element e = _uiDoc.Document.GetElement( r );
      XYZ pt = r.GlobalPoint;

      

ตัวอย่างข้างล่างเป็นการ Moveวัตถุ โดยการเลือก และคำนวนการย้ายตำแหน่งจาก Object โดยใช้ BoundingBox(กล่องสี่เหลี่ยมครอบวัตถุ)

public static void SelectAndMoveElement(ExternalCommandData commandData)
{// เป็นการทดลองการแก้ไข ตำแหน่งของ Object
// เลือก Project ปัจจุบัน
Autodesk.Revit.DB.Document CachedDoc = commandData.Application.ActiveUIDocument.Document;
Autodesk.Revit.ApplicationServices.Application CachedApp = commandData.Application.Application;
// เลือก วัตถุ 1 ชิ้น
Reference pickedObj = commandData.Application.ActiveUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "Please select an element to move.");

if (pickedObj != null && pickedObj.ElementId != ElementId.InvalidElementId)
{
// element location
                Element e1 = CachedDoc.GetElement(pickedObj.ElementId);
                XYZ minPt1 = e1.get_BoundingBox(null).Min;
                XYZ minPt2 = e1.get_BoundingBox(null).Max;
                XYZ minPt = minPt1 + (minPt2 - minPt1) / 2;// หา จุดกึ่งกลางวัตถุ
                XYZ mPt = commandData.Application.ActiveUIDocument.Selection.PickPoint();
                XYZ vPt = mPt - minPt;// คำนวน Vector Move
                
                PPGenInput.PPSingleInput mydlg = new PPGenInput.PPSingleInput();
// เลือกระยะเป็น Vector
mydlg.setPrompt("Enter Move Vector:");
mydlg.text = vPt.ToString();//"10,10,0";
            
mydlg.ShowDialog();
string vectorStr = mydlg.text.Replace("(","").Replace(")",""); // นำค่าเข้ามาที่ ตัวแปร

string[] arr = vectorStr.Split(new char[] { ',' }); // แยกเป็นตัวๆ X,Y,Z
using (Transaction trans = new Transaction(CachedDoc, "SelectAndMoveElement"))
{
// เริ่ม transaction
trans.Start();
#if R14    
Line lineAsAxis = CachedApp.Create.NewLineBound(new XYZ(0, 0, 0), new XYZ(0, 0, 1));
#else
      //              Line lineAsAxis = CachedApp.Create.(new XYZ(0, 0, 0), new XYZ(0, 0, 1));

#endif
                   
                    // แปลงจาก arr เป็น vector จริง double_x,double_y,double_z
XYZ xyz = ptM2f(double.Parse(arr[0]), double.Parse(arr[1]), double.Parse(arr[2]));
// move
ElementTransformUtils.MoveElement(CachedDoc, pickedObj.ElementId, xyz);
                   
trans.Commit(); // Ok
}
}

}

วันอาทิตย์ที่ 7 ธันวาคม พ.ศ. 2557

การวาง Opening เช่นประตูหน้าต่าง ต้องบอก Host เช่นกำแพง

กรณีที่ต้องการวาง ช่องเปิด เช่นประตู หน้าต่างใน Revit ต้องบอก Host หรือ เจ้าของด้วย ที่เป็น Wall

ตัวอย่าง

public static void BatchCreateDoor(XYZ pt, Autodesk.Revit.DB.Document doc,Wall w1, Level level)
        { // ค้นประตู ต้องสร้างหลัง กำแพง
            List<FamilySymbol> fl = getAllType("Doors", doc);

        
            Autodesk.Revit.Creation.Document creation_doc = doc.Create;

            StructuralType st = StructuralType.NonStructural;
            // เอาตัวแรกมาวาด
          
            creation_doc.NewFamilyInstance(pt, fl[0],w1, st);

        }

การวาง Object ใน Revit ที่ไม่ใช่ Structure เช่น เฟอร์นิเจอร์

ต้องบอกว่า ไม่ใช่ Structure

StructureType.NonStructure

ตัวอย่าง code

 public static void BatchCreateFurniture(XYZ pt, Autodesk.Revit.DB.Document doc, Level level)
        { // ค้น Furniture
            List<FamilySymbol> fl = getAllType("Furniture", doc);

            // 
            Autodesk.Revit.Creation.Document creation_doc = doc.Create;

            StructuralType st = StructuralType.NonStructural;
           // ทดลอง เอาตัวแรก
           creation_doc.NewFamilyInstance(pt, fl[0], st);
        }

กรณีที่ต้องการหมุน
ให้เพิ่มที่ NewFamilyInstance(pt,fl[0],new XYZ(1,1,0),st);
จะหมุน ไป 45 องศา เพราะ XYZ ที่ใส่ไป คือ Vector ที่ไปทาง 45 องศา (x=1,y=1 วาดกราฟดู)

รูปแสดง ภาพวางโต็ะ หลังเสา