วันอาทิตย์ที่ 1 ตุลาคม พ.ศ. 2560

หาพิกัดของDuct หรือ ท่อ

Duct และ ท่อ เป็น Element ใน MEP การหาจุดเริ่มต้นและสิ้นสุด ต้องทำให้เป็น Curve ก่อน

  public static void getDuctPoint(ExternalCommandData commandData)
        {
                UIApplication uiapp = commandData.Application;
                UIDocument uidoc = uiapp.ActiveUIDocument;
                Document doc = uidoc.Document;
                string dbg = "";
                FilteredElementCollector allDuct
                  = new FilteredElementCollector(doc)
                    .OfClass(typeof(Duct));

                int nDucts = 0;
                int nCurves = 0;

                foreach (Duct aDuct in allDuct)
                {
                    ++nDucts;

                    LocationCurve lc = aDuct.Location as LocationCurve;

                    if(null == lc) dbg= "No Duct!";

                    if (null != lc)
                    {
                        ++nCurves;

                        Curve c = lc.Curve;

                       dbg+=string.Format("Duct {0} from {1} to {2}",
                          aDuct.Id.IntegerValue,
                          c.GetEndPoint(0).ToString(),
                          c.GetEndPoint(1).ToString());
                    }
                }
                TaskDialog.Show("??", dbg);
                //return Result.Succeeded;

         }

วันเสาร์ที่ 30 กันยายน พ.ศ. 2560

ระยะสั้นที่สุด ระหว่าง Line

เป็น การคำนวน ด้วยวิธี Vector หาระยะสั้นที่สุดระหว่าง Line

 public static double dist3D_Line_to_Line(Line L1, Line L2)
        {
            XYZ u = L1.GetEndPoint(1) - L1.GetEndPoint(0);
            XYZ v = L2.GetEndPoint(1) - L2.GetEndPoint(0);
            XYZ w = L1.GetEndPoint(0) - L2.GetEndPoint(0);
           
            double a = u.DotProduct( u);         // always >= 0
            double b = u.DotProduct(v);
            double c = v.DotProduct( v);         // always >= 0
            double d = u.DotProduct( w);
            double e = v.DotProduct( w);
            double D = a * c - b * b;        // always >= 0
            double sc=0;
           double tc=0;
            double SMALL_NUM = 0.000001;
            // compute the line parameters of the two closest points
            if (D < SMALL_NUM)
            {          // the lines are almost parallel
                sc = 0.0;
                tc = (b > c ? d / b : e / c);    // use the largest denominator
            }
            else
            {
                sc = (b * e - c * d) / D;
                tc = (a * e - b * d) / D;
            }

            // get the difference of the two closest points
            XYZ dP = w + (sc * u) - (tc * v);  // =  L1(sc) - L2(tc)

            return dP.GetLength();   // return the closest distance

        }

สร้าง Sheet ด้วย List ใน Revit

สร้าง Sheet ใน Revit ด้วย List ดูใน datas


  public static void createSheetList(ExternalCommandData cmd)
        {
            UIApplication uiapp = cmd.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
            Autodesk.Revit.DB.Document doc = uidoc.Document;
            string[] datas = {"1,sheet1","2,sheet2","3,sheet3" };
            
            
                FilteredElementCollector collector = new FilteredElementCollector(doc);
                collector.OfCategory(BuiltInCategory.OST_TitleBlocks);
                collector.WhereElementIsElementType();
                //Get ElementId of first title block type.
                ElementId titleBlockId = collector.FirstElementId();
              using(  Transaction t = new Transaction(doc, "Create Sheets"))
              {
                t.Start();
                foreach(string csvLine in datas)
                {
                    char[] separator = new char[] { ',' };
                    string[] values = csvLine.Split(separator, StringSplitOptions.None);
                    // Make sure both values are valid
                    if (values[0] != null && values[0].Length > 0 && values[1] != null && values[1].Length > 0)
                    {
                        ViewSheet sheet = ViewSheet.Create(doc, titleBlockId);
                        sheet.Name = values[1];
                        sheet.SheetNumber = values[0];
                    }
                }
                t.Commit();
              }

         }

วันอังคารที่ 26 กันยายน พ.ศ. 2560

อ่าน Paint Material จาก Wall

อ่านค่า Paint ที่ระบายบนกำแพง


  public static string getPaintWallFaces(ElementId wallId,Document doc)
        {
            Element wall = doc.GetElement(wallId);
            GeometryElement geometryElement = wall.get_Geometry(new Options());
            string str= "";
            foreach (GeometryObject geometryObject in geometryElement)
            {
                if (geometryObject is Solid)
                {
                    Solid solid = geometryObject as Solid;
                    foreach (Face face in solid.Faces)
                    {
                        if (doc.IsPainted(wallId, face))
                        {
                            ElementId mid = doc.GetPaintedMaterial(wallId, face); 
                           Material mel = doc.GetElement(mid) as Material;
                            str+=mel.Name+"\n";
                        }
                    }
                }
            }
            return str;
        }

Debug โปรแกรม C# เมื่อ Run ด้วย DDD

การเรียกโปรแกรม ทำงาน ด้วย DDD ทำได้เป็น Pre-Compiled Mode ทำได้ ทันที โดยไม่ต้อง Load หรือเข้าโปรแกรม Revit ใหม่ ก็สามารถใช้ TaskDialog เพื่อการแสดงค่า ที่ไม่ทราบได้ แต่บางครั้ง จำเป็นต้อง ให้ ทำการ แสดงค่า Watch ระหว่างทำงาน สามารถใช้ Visual Studio ที่กำลังเขียน Code อยู่ Debug ได้
วิธีการ

เลือกที่ Debug และ เลือก Attach To Process -

เลือก Revit.Exe
และ ไปที่ Source code ทดลอง Click ที่หน้าบรรทัด จะเป็น จุดสีแดง หมายถึง Break line 



กลับไป Run คำสั่ง ใน หน้า Revit ->Addins->DDD และเรียกคำสั่งที่ต้องการ Debug จะเห็นว่าโปรแกรมจะหยุดที่บรรทัดนี้ เอา Mouse ไปวางที่ตัวแปร ก็จะแสดงค่า ตัวแปรออกมา ถ้าต้องการไ ปต่อ ก็กดที่ Continue (F5) ถ้าต้องการไปบรรทัดต่อไป ก็กด (Step Over F11)


หาวัตถุที่ ตัดกันโดยใช้ BoundingBox ใน Revit

การหาวัตถุที่ตัดกันใน Revit แบบเร็วๆ ใช้ Bounding Box หรือ ขนาดกล่องที่ใส่วัตถุ นั้นเช่นกำแพง เสา และเช็คว่าตัดกับ วัตถุอะไร แบบประมาณการ เมื่อได้แล้วค่อยไปเช็กอีกที่ว่าตัดกันจริงหรือไม่

// check intersection by box
        public static void chkInterBound(  ExternalCommandData commandData)
        {
            UIApplication uiApp = commandData.Application;
            UIDocument uiDoc = uiApp.ActiveUIDocument;
            var app = uiApp.Application;
            Document doc = uiDoc.Document;

            // Select something to use as base bounding box.

            Reference r = uiDoc.Selection.PickObject( Autodesk.Revit.UI.Selection.ObjectType.Element);

            // Find the bounding box from the selected 
            // object and convert to outline.
            Element Er = doc.GetElement(r.ElementId);
            BoundingBoxXYZ bb = Er.get_BoundingBox( doc.ActiveView);

            Outline outline = new Outline(bb.Min, bb.Max);

            // Create a BoundingBoxIntersectsFilter to 
            // find everything intersecting the bounding 
            // box of the selected element.

            BoundingBoxIntersectsFilter bbfilter
              = new BoundingBoxIntersectsFilter(outline);

            // Use a view to construct the filter so we 
            // get only visible elements. For example, 
            // the analytical model will be found otherwise.

            FilteredElementCollector collector
              = new FilteredElementCollector(
                doc, doc.ActiveView.Id);

            // Lets also exclude the view itself (which 
            // often will have an intersecting bounding box), 
            // and also the element selected.

            ICollection<ElementId> idsExclude
              = new List<ElementId>();

            idsExclude.Add(r.ElementId);

            // No need for this, BoundingBoxIntersectsFilter 
            // excludes all objects derived from View, as 
            // pointed out by Jim Jia below:
            //
            //idsExclude.Add( doc.ActiveView.Id );

            // Get the set of elements that pass the 
            // criteria. Note both filters are quick, 
            // so order is not so important.

            collector.Excluding(idsExclude)
              .WherePasses(bbfilter);

            // Generate a report to display in the dialog.

            int nCount = 0;
            string report = string.Empty;
            foreach (Element e in collector)
            {
                string name = e.Name;

                report += "\nName = " + name
                  + " Element Id: " + e.Id.ToString();

                nCount++;
            }

            TaskDialog.Show(
              "Bounding Box + View + Exclusion Filter",
              "Found " + nCount.ToString()
              + " elements whose bounding box intersects\n"+
              report);

           
        }

วันจันทร์ที่ 25 กันยายน พ.ศ. 2560

เขียน Model Line ใน Revit

Model Line จำเป็นต้องใช้ในบางงาน ที่ต้องการบอก เป็นเส้น เช้น Boundary หรือ Wire ที่ไม่มี Model

Source

// about line in revit
        public static void drawMline(ExternalCommandData commandData)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
            Autodesk.Revit.DB.Document doc = uidoc.Document;
            XYZ p1 = new XYZ();
            XYZ p2= p1.Add(new XYZ(5,5,0));
            using (Transaction tr = new Transaction(doc, "MLINE"))
            {
                tr.Start();
                CreateModelLine(doc, p1, p2);
                tr.Commit();
            }
        }

      public static void CreateModelLine( Autodesk.Revit.DB.Document doc,XYZ p, XYZ q)
        {
            if (p.Equals(q))
            {
                throw new ArgumentException(
                  "Expected two different points.");
            }
            Line line = Line.CreateBound(p, q);     //_app.NewLine(p, q, true);
            if (null == line)
            {
                throw new Exception(
                  "Geometry line creation failed.");
            }

            doc.Create.NewModelCurve(line,NewSketchPlanePassLine(doc,line));
        }
      public static SketchPlane NewSketchPlanePassLine(Autodesk.Revit.DB.Document doc, Line line)
      {
          XYZ p = line.GetEndPoint(0);
          XYZ q = line.GetEndPoint(1);
          XYZ norm;
          if (p.X == q.X)
          {
              norm = XYZ.BasisX;
          }
          else if (p.Y == q.Y)
          {
              norm = XYZ.BasisY;
          }
          else
          {
              norm = XYZ.BasisZ;
          }
          Plane plane = doc.Application.Create.NewPlane(norm, p);

          return SketchPlane.Create(doc, plane);

      }