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

คำสั่งพัฒนาโปรแกรม DDD ใน Revit

คำสั่ง พัฒนาโปรแกรม Rapid SDK ใน Revit
Download Here
copy ไปที่  c:\
และ แตกไฟล์ จะได้ Folder Turbostruct
และ ต้อง ลง Addin manager
และทำการ Load
การเรียกคำสั่งให้เรียกที่ External command หรือ รูป Icon DDD

ตัวอย่าง Code สำหร้บ Revit 2014

ตัวอย่าง Code สำหรับ Revit 2015

เรื่องของ Create

ในโปรแกรจะเป็น การ CreateColumn
จะมี Sub Method หรือโปรแกรมย่อย 4 โปรแกรม
1. FindElement ใว้สำหรับ ค้น Element ช่น เสา คานพื้น ชั้น ห้อง ที่อยู่ ใน Revit Project
2. getAllType เป็นการ นำ FamilySymbol ที่กำลังใช้งานอยู่ ใน Project เช่น เสาทั้งหมด มาใส่ Array ที่เป็น List
3.BatchCreateColumns เป็นการสร้าง Instant หรือวาง วัตถุ ลงไป ใน view โดยต้องกำหนด จุด XYZ
   สำหรับ transaction จะควบคุมที่ CreateColumn

สำหรับ การ Edit หรือ แก้ไข
ตัวอย่าง ในการ เลือกและ Move
ตัวอย่าง

สำหรับการเลือก และดึงข้อมูลโดยใช้การเลือก ก่อนแล้วเรียกคำสั่ง
ตัวอย่าง

สำหรับ Revit 2015 
Addin ไม่สามารถ Load ได้ ให้วางตรงๆ ใน Folder
C:\Users\<user>\AppData\Roaming\Autodesk\Revit\Addins\2015
file Addin ชอง DDD
และ Api จะเปลี่ยน หลายตัวโดยเฉพาะ Create ต่างๆ ที่เคยเป็น Method ใต้ Document จะเปลี่ยนไป
อยู่ใน Symbol นั้นๆ เช่น doc.newCreateLine เปลี่ยนเป็น Line.Create แทน ลองเดาดู หรือดูจาก SDK ของ Revit 2015  แต่จะเป็นระบบ และง่ายขึ้น



สำหรับ หัวของไฟล์ ใน c#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System.Windows.Forms;
using Autodesk.Revit.Creation;
using Autodesk.Revit.DB.Structure;

ข้อสำคัญอีกอย่าง คือ Revit ตำแหน่ง XYZ จะเป็นหน่วย ฟุต ไม่ใช่ เมตร ถ้าต้องเปลี่ยน ให้ หารด้วย
0.3048
public static double f2m(double f)
{
   return f*0.3048;
}
public static double m2f(double m)
{
   return f/0.3048;
}

// text file ของ ExternalTool1.addin

<?xml version="1.0" encoding="utf-8"?>
<RevitAddIns>
  <AddIn Type="Application">
    <Name>External Tool</Name>
    <Assembly>C:\turboStruct\DDDRevit.dll</Assembly>
    <ClientId>3beb63b3-38f8-464b-a301-c30d239a69f6</ClientId>
    <FullClassName>PowerAEC.PPToolbar</FullClassName>
    <VendorId>ADSK</VendorId>
    <VendorDescription>Autodesk, www.autodesk.com</VendorDescription>
  </AddIn>
  <AddIn Type="Command">
    <Assembly>C:\turboStruct\DDDRevit.dll</Assembly>
    <ClientId>54538ab4-83a1-4a5b-b172-1ffaa776b777</ClientId>
    <FullClassName>PowerAEC.Command</FullClassName>
    <Text>Command</Text>
    <Description>""</Description>
    <VisibilityMode>AlwaysVisible</VisibilityMode>
    <VendorId>ADSK</VendorId>
    <VendorDescription>Autodesk, www.autodesk.com</VendorDescription>
  </AddIn>
  <AddIn Type="Command">
    <Assembly>C:\turboStruct\DDDRevit.dll</Assembly>
    <ClientId>fb306864-2f47-427d-997f-68a17d625d06</ClientId>
    <FullClassName>PowerAEC.showBook</FullClassName>
    <Text>showBook</Text>
    <Description>""</Description>
    <VisibilityMode>AlwaysVisible</VisibilityMode>
    <VendorId>ADSK</VendorId>
    <VendorDescription>Autodesk, www.autodesk.com</VendorDescription>
  </AddIn>
</RevitAddIns>

วันเสาร์ที่ 30 สิงหาคม พ.ศ. 2557

ชุดคำสั่ง PowerAEC,DDD สำหรับ Nanocad


สำหรับผู้ที่เข้าอบรมพัฒนาโปรแกรม CAD บน NanoCAD5โดยสามารถ Download ชุดพัฒนา Rapid SDKได้ที่
http://goo.gl/TS5gDw


เมื่อลงแล้วเปิด Nanocad ต้อง Custom menu->Reset All ก่อน ถ้าเป็น Window 7 ต้อง Edit Permission ให้ User ->Read,Write  ใน โฟล์เดอร์ ของ Nanocad

สำหรับ Editor ใช้ ShapeDevelop 3
SharpDevelop

1. Reference ใน Project และใส่ using ด้วย
hostmgd.dll
hostdbmgd.dll
ppcad.dll  
ppgeninput.dll

2. Method ที่เรียก จะขึ้นด้วย public static void ชื่อโปรแกรม()


วันพฤหัสบดีที่ 27 มีนาคม พ.ศ. 2557

วิธีปิดรายการ Auto-complete ขึ้นคำสั่งใน Autocad 2014-2015

การขึ้น คำสั่ง หรือ Auto complete ใน Autocad 2014-2015 เป็นตัวช่วย ในการทำงาน หาคำสั่งที่อาจจะเขียนผิด ให้ถูกต้อง

 แต่สำหรับผู้ที่ใช้งานเป็นประจำ จะน่ารำคาญ มาก วิธีการปิด เป็นดังนี้
ให้กด Mouse ขวาไปที่ Command Line จะขึ้น เมนู ให้ปิด ที่ Input ให้หมดโดยเอาเครื่องหมายถูกออก

Autocad ก็จะไม่ Search และขึ้นรายการอีกต่อไป

วันพุธที่ 2 มกราคม พ.ศ. 2556

การ Sort จุดพิกัด ของ วัตถุ ในCAD ด้วย C#

จุดพิกัดของ วัตถุใน CAD มักจะเป็น จุดที่ประกอบด้วย Array ของ double (เลขทศนิยม) จำนวน 3 ตัว ที่จะทดแทนด้วย X,Y,Z เช่น
Point3d pt = new Point(10,20,0);
หมายถึง จุดพิกัด ที่มี ค่า X= 10 ค่า Y = 20 และค่า Z=0 เป็นต้น
แต่การใช้งานในหลาย กรณีเราอาจจะมีจุดเป็น ร้อยเป็นพัน การ ทำการ Sort ตามค่าเช่น ค่า X หรือ ค่า Y ก็จะเป็นเรื่องยุ่งยากพอสมควร ในกรณีนี้ ผมจะแนะนำการใช้ List ใน C# ซึ่งน่าจะง่ายกว่าวิธีการอื่นๆ

จาก Code
pts เป็น Array ของ จุดที่อาจจะมีเท่าไรก็ได้ เราจะใข้ xarr มาเป็นตัว Sort สำหรับค่า X
วิธีการก็คือว่า ใน List จะมีเครื่องมือ Sort ที่ใส่ Comparator ได้เอง


List<Point3d> xarr = new List<Point3d>();
//Dictionary<double, double> xarr = new Dictionary<double, double>();
for (int i = 0; i < pts.Count; i++)
{
xarr.Add(pts[i]);
}
Comparison<Point3d> cmpPt3 = delegate(Point3d p1, Point3d p2)
{ return (p1.X.CompareTo(p2.X)); };
xarr.Sort(cmpPt3);

เราก็จะสร้าง cmpPt3 เป็น comparator โดยที่จะเป็น delegate Function (function ที่เกิดเฉพาะงาน)
ด้วยวิธีการนี้ก็จะสามารถ Sort จุดพิกัดตามค่า X ได้อย่างไม่ยาก

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

สร้างเสาเป็น Element แรกใน Revit

เพื่อเป็นกำลังใจในการเริ่มเขียนโปรแกรมใน Revit
ก็จะเริ่มจากการเขียน เสา ไปใน Revit โดยง่ายที่สุด (แต่ก็เอาเรื่องเหมือนกัน)
วิธีการ จะต้องเข้าใจก่อนว่า เราต้องมี Family ก็ไปทำการ Load Family จาก Library ของ Revit ใน Project มาก่อน จากนั้น ใน โปรแกรม ก็จะคิดว่าเราได้ นำ Family ต่างๆ และกำหนด Type ต่างๆ มาแล้ว

เริ่มจาก 
1. เริ่มเปิด Document ก่อน และต้องเปิด Trasaction (เป็นระบบเดียวกับ ฐานข้อมูลที่เราสามารถยกเลิกได้ โดยไม่ทำให้โปรแกรม หรือข้อมูลเสียหาย)

Autodesk.Revit.DB.Document document = commandData.Application.ActiveUIDocument.Document;


FilteredElementCollector collector = new FilteredElementCollector(document);
 Transaction tr = new Transaction(CachedDoc);

          if (TransactionStatus.Started == tr.Start("Create Columns"))
          {.. ที่ต้องการทำ ..

          tr.Commit();  // ปิด transaction และ update revit
       }



2. ใส่ส่วน "ที่ต้องการทำ" ทำการ กรองเฉพาะ Family ที่ต้องการโดยเลือกจากCatalog -> Structure Columns


Collection<Element> fmList = collector.OfClass(typeof(FamilySymbol)).ToElements();
 var query = from fm1 in fmList where ((FamilySymbol)fm1).Category.Name == "Structural Columns" select (FamilySymbol)fm1;
    List<FamilySymbol> oFmList = query.ToList<FamilySymbol>();

จะเห็นได้ว่ามีความแตกต่างจาก บทความก่อนหน้านี้นะครับ ผมใช้ Linq ในการกรองข้อมูลซึ่งเท่ากับ การใช้ Foreach เกือบ 10 บรรทัด โดยกรองเฉพาะ "Structural Columns" ใส่ใน oFmList

ตอนนี้เราจะมี Family ที่เป็น Array เพื่อเลือกใช้งาน แล้ว

3.ทำการวาด ได้แก่ การกำหนด ElementSet และ กำหนด ตำแหน่ง แล้วสร้าง Instance หรือวาง
สำหรับการสร้าง จะมีการกำหนดเมื่อมีการสร้าง Element ว่าต้องเป็น StructuralType.Column ส่วนนี้บังคับ จะต้องมีหมวด ตาม Revit กำหนดซึ่งมาจาก IFC Standard(ระบบมาตรฐานของ Bim) 

ElementSet elementSet = null;
for (int i = 1; i < 7; i++)
            {
            int k = i % oFmList.Count;
            FamilySymbol sFm = oFmList[k];

                  XYZ location = new XYZ(i * 10, 100, 0);
                  FamilyInstanceCreationData fiCreationData = new FamilyInstanceCreationData(location, sFm, level,
                              Autodesk.Revit.DB.Structure.StructuralType.Column);
                  if (null != fiCreationData)
                  {
                        fiCreationDatas.Add(fiCreationData);
                  }
            }
           
if (fiCreationDatas.Count > 0)
  {     
   elementSet = document.Create.NewFamilyInstances(fiCreationDatas);
  }

เมื่อ Compile แล้วทดสอบ ก็จะวาง เสาตาม Family และ Type ต่างๆตามในรูป









หา RevitApi และ Revit Sdk ได้ที่ใหน

บังเอิญว่ามีอาจาร์ยที่รู้จักกันสนใจต้องการแนะนำเริ่มเขียน C# บน Revit  อยากทราบว่า จะไปหา SDK ตัวอย่างได้ที่ใหน ผมก็ลืมใส่ใว้ใน Post ก่อนหน้า
ไปที่นี่ครับ

http://usa.autodesk.com/adsk/servlet/index?siteID=123112&id=2484975

หรือ ใช้ Google search "revitsdk download"
ก็จะ Link มาที่นี้เช่นกัน
สำหรับข้อเขียนของตัวอย่างที่ Advance หน่อยก็ไปที่

http://thebuildingcoder.typepad.com


สำหรับการ ลง จะเป็นการแตกไฟล์ ที่ Pack มา ก็จะสร้างเป็น Folder

โดยตัวอย่างจะอยู่ใน Sample และที่สำคัญต้องลง Add-In Manager ที่อยู่ใน Folder ดังรูปก่อน จึงจะ ทำการ Load Add-in ตามตัวอย่างได้ สำหรับ Compiler ใช้ Visual Studio 2010 Professional ขึ้นไปหรือ Express (Free) ก็ได้ ไปที่

 http://www.microsoft.com/visualstudio/eng/downloads

โปรแกรมที่ Compile แล้วจะได้เป็น <โปรแกรม>.dll จะนำมาใช้งาน จะใช้ Load และแสดงเป็นคำสั่ง

ถ้าต้องการทดสอบโปรแกรมก็ให้กด Run

เทคนิคอยู่นิดหนึ่งคือเมื่อสั่ง Save ใน Dialog Add-in แล้ว ต้องออกจาก Revit แล้วมาเข้าไหม่จะมี เมนูใน Add-in ปรากฏขึ้น เมื่อเข้าใหม่


การจัดการของ Family ใน Revit


การจัดการของ Family ใน Revit
อ.ธนะพันธ์ อินทรเกสร
ระบบ Family ใน Revit เป็นส่วนสำคัญมาก ที่ทำให้ Revit ใช้งานง่าย ใน การจัดการ ของ Revit จะมี โครงสร้าง  3 ส่วน ได้แก่
1. Category     จะบอกว่าเป็นหมวดของงานอะไร เช่น เป็นงานหลังคาก็ได้แก่ Roofs หรือ โครงสร้างเช่น Structural Beam Systems เป็นต้น
2. Family  ได้แก่ สัญญลักษณ์ 3 มิติ หรือ 2 มิติ รูปของวัตถุนั้นเช่น เสา Concrete หรือ เสา I beam เป็นต้น
3. Family Type เป็นการตั้งค่า ของ Family ให้มีชื่อและขนาดตาม Parameter ตามต้องการ


เพื่อสร้างโปรแกรมในการทำงาน อัตโนมัติ จะต้องนำ Family มาใช้ ต้องเข้าใจว่าใน แบบหรือ project ที่ทำงานของ Revit จะเรียกว่า Document ที่จะบรรจุ Family เป็น Element (แบบเดียวกัน กับ Block ใน Autocad และทุกอย่างใน Revit จะเรียกว่า Element) การมาใช้งาน จะสร้าง Instance (แบบเดียวกับ BlockRefence ใน Autocad)
การขั้นแรก Scan ทั้ง Document ใส่ใน Array

Autodesk.Revit.DB.Document document = commandData.Application.ActiveUIDocument.Document;

FilteredElementCollector collector = new FilteredElementCollector(document);


Collector จะมี ทุก Element ใน Project ปัจจุบัน ทั้ง Element ที่มองเห็น ทั้ง View ทุกอย่าง เพื่อให้เหลือเฉพาะส่วนที่ต้องการการ เราจะต้องทำการ filter หรือกรอง เฉพาะ Family โดยจะเรียกว่า FamilySymbol
      ICollection<Element> collection = collector.OfClass(typeof(FamilySymbol)).ToElements();

ตอนนี้เราจะได้ Family มาทั้งหมดแล้วใน collection ถ้าเราต้องการเฉพาะ
Category ใน Code จะเป็น
collection[i].Category.Name
ลองเขียนเป็นโปรแกรม
foreach (Element e in collection)
    {
        familySymbol = e as FamilySymbol;

        MessageBox.Show(familySymbol.Category.Name);
        Family fm = familySymbol.Family;
                   MessageBox.Show (fm.Name);

        ElementType et = e as ElementType;

        if (null != familySymbol.Category)
        {
            if ("Structural Columns" == familySymbol.Category.Name)
            {
 MessageBox.Show (et.Name);

                break;
            }
        }
    }

สำหรับการแสดงชื่อของ Family จะใช้
Family fm = familySymbol.Family;
                   MessageBox.Show (fm.Name);
โดยที่  familySymbol จะเก็บทัง Category และ Family
แต่ การที่จะเข้าไปใน Type จำเป็นต้องใช้ ElementType ในการ Cast Element เพื่อที่จะนำค่า
ElementType มาใช้งาน
 ถ้าต้องการ Type ก็ใช้
ElementType et = e as ElementType;
  MessageBox.Show (et.Name);

Revit ใช้การเขียนโปรแกรมในระบบที่ทันสมัยมาก ได้ใช้ Linq ทำให้การเขียนโปรแกรมสั้นลงไปอย่างมาก
ผมจะแนะนำในตอนหน้า