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

สร้าง Node เอง ด้วย C# ใน Dynamo

การ Custom Node มีประโยชน์​คือ ทำงานบางอย่างที่ Dynamo ไม่ได้ มีให้ หรือ งานหลายงาน อาจจะมีการเก็บ Code เก่าใว้ จะได้นำมาใช้ได้ 

Custom Node ใน Dynamo มีตัวอย่างมาก ที่เป็น ภาษาPython  หรือ การ Custom Node โดยใช้ Graphic ก็มีจำนวนมาก ให้ Searh google key word "Dynamo Custom Node" แต่ที่จะอธิบาย เป็นการนำ C# มาทำ custom node เพราะ มี Code จำนวนมาก(ของตัวเอง) เขียนใว้แล้ว  
ในเอกสาร ของ Dynamo จะมี Link ที่อธิบาย ในการสร้าง Code ที่เรียกว่า ZeroTouch 
ใน Link

ให้ Download Souce และ compile ในการ Compile Dll ที่ได้ ให้ Copy ลงใน Folder ของ Dynamo
ใน Revit เปิด Dynamo
และ ทำการเลือก Import Library

เลือก File ZeroTouchEssentials.dll จะเพิ่ม Menu ขึ้นมา
สำหรับ Code ที่เป็นตัวทำงานในแต่ละ Node ให้ดูใน Source

เช่น Double Length ก็จะแสดงง่ายใน Code แบบนี้

   public static double DoubleLength(Autodesk.DesignScript.Geometry.Curve curve)
        {
            return curve.Length * 2.0;
        }


ใน Dynamo จะแสดงแบบนี้


ง่ายอะไรจะปานนั้น



ใช้ Dynamo ในการ Query ขนาดพื้นใน Revit และส่งไป Excel

เป็นตัวอย่างของการใช้ Query ขนาดพื้น


 ใน Revit และส่ง ไป Excel โดยเอาชื่อ Floor ที่อยู่ ใน Mark ไปด้วย
ในการทำงานนี้ ต้องตั้งค่า Mode ในการ Run เป็น Manual

ผลจะไปเปิด Excel และใส่ค่า




เคล็ดลับ อยู่ที่ Element.GetParameterValueByName สามารถรับเป็น Array ได้ และจะทำทุกตัว แล้วจากนั้น ไปทำการ List.Create ใม่ ให้เป็น 2 แถว(อย่าลืมกด+) จึงไปใส่ใน Data ของ ExcelWriteToFile ช่องสี่เหลี่ยม เล็กในแต่ละ Block จะเป็นการ Debug ค่า ในการ run


วันศุกร์ที่ 11 ธันวาคม พ.ศ. 2558

ใช้ Dynamo วาด กำแพงใน Revit

เป็นมั่ว อย่างมีหลักการ โดยเริ่มจาก Objective ก่อนว่าต้องการ กำแพง แล้วก็เอา กำแพงมาวาง
แล้วดูว่า ต้องการอะไรอีก เช่น Curve (แต่อันนี้ ต้องมีความรู้ก่อนว่า Line , Arc ก็คือ Curve เหมือนกัน)
ต้องการ Level ก็เอามาวาง  ต้องการ Height ก็มาวาง ถ้าขึ้น เหลือง ก็แสดงว่าไม่ได้ ก็ใช้ ช่อง Search ลองไปเรื่อย
แล้วก็ได้กำแพงที่ปรับค่าได้


.ในการใช้ Slider ต้องตั้ง Limit ใหม่ โดยการกดที่ลูกศรลง เพื่อให้พอกับขนาดกำแพง


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

เข้าใจเขียนโปรแกรมด้วยDynamo ใน Revit เบื้องต้น

เมื่อเริ่มต้น การใช้ Dynamo ต้องลงโปรแกรมก่อน (www.dynamobim.org)เมื่อลงแล้วจะมี Icon อยู่ใน หน้าAddin

ตัวอย่างนี้เป็นต้วอย่าง เข้าใจในหลักการง่ายๆของ Dynamo มีหลักว่า ทุกอย่างจะเห็นบนจอ
Dynamo จะเป็นตัวสร้างและคำนวน Revit จะเป็นต้วแสดงผล จะสะดวกมากถ้าเครื่องคอมมี 2 จอ
จะเป็นการสร้างจุด และควบคุมจุดจาก Input ใน Dynamo

เริ่มสร้างโครงการใน Revit เลือก New Conceptual Mass

ใน หน้า Addin เลือก Dynamo

เลือก New
ทีเมนูด้านข้าง เลือก Revit->Element->Reference->Reference Point->By Point

เลือกจะแสดง Object ใน Workspace
ขณะเดียวกัน  Revit ยังไม่แสดงจุดเนื่องจากยังไม่มี Input

ตอนนี้เราก็จะได้ Element ใน การจัดการแล้ว

ไปที่ Geometry->Point->By Coordinate(X Y Z)
แล้วกดที่ Point ลาก เชื่อมไปที่ pt ของ ReferencePoint

ใน Revit จะแสดงจุดแล้ว
ใส่ Input

เลือก  Core->Input->Number Slider  3 ครั้ง
แล้ว เชื่อม แต่ละอัน เข้า X,Y,Z ของ Point

ทดลอง ปรับ ค่า X, Y , Z จาก Slider ดู จะเห็นจุดเลื่อนตำแหน่งไปมา เป็นอันสำเร็จ


 แล้ว Save โปรแกรมเก็บใว้

สรุปการควบคุมจุดจะมาจาก โปรแกรม และค่าจาก Dynamo Object




การเขียนโปรแกรม ด้วย การวาด โปรแกรม Dynamo

Dynamo พัฒนาโดยบริษัท Autodesk inc. เพื่อใช้กับ โปรแกรม Revit เป็นโปรแกรมที่ทำให้ผู้ที่ไม่ได้เรียนมาใน สาขาคอมพิวเตอร์ ทำการเขียนโปรแกรมเพื่อสร้างแบบ 3 มิติ ได้อย่างที่ต้องการโดยใช้ การกำหนด เป็น Diagram ของแนวความคิด โดยย่อก ารทำงานเป็นจุด เรียกว่า Node เมื่อต้องการทำงานอะไร ก็ให้ไปหา Node ที่ต้องการมาในการสร้างโปรแกรม และในแต่ละ Node ก็จะบอก Input และ Output เป็นรูปภาพ(ตัวอย่างจาก Tutorial Dynamo)


โดยโปรแกรมมีตัวอย่าง มากดูได้จาก Web site
http://www.dynamobim.org

ความน่าสนใจไม่ได้อยู่ที่เขียนโปรแกรม แต่ทำให้การออกแบบสถาปัตย์ ที่มีรูปแบบ Freeform หรือ Wave เป็นไปได้ใน คอมพิวเตอร์ ซึ่งแบบในลักษณะดังกล่าวยากที่สร้างเป็น Model ขึ้นมา


วันพฤหัสบดีที่ 12 พฤศจิกายน พ.ศ. 2558

Revit API 2016 กับ การเลือก Selection Object และ อ่าน Parameter

Revit API 16 มีการเปลี่ยน 2 จุดที่มีผลกระทบกับโปรแกรมเก่าๆ
ส่วนแรกคือการ Select Object ตอนนี้ จะไม่สามารถ ได้ Element โดยตรง ต้องเป็น ElementId (อันนี้ดี จะได้เป็น ระบบหน่อย)

การเลือกในปัจจุบัน


   ICollection<ElementId> collectionIds = uidoc.Selection.GetElementIds();
    List<Element> founds = new List<Element>();
                foreach (ElementId eid2 in collectionIds)
                {
                    try
                    {
                        Element e2 = doc.GetElement(eid2);
                        founds.Add(e2);
                    }
                    catch { }
                }


founds จะเป็น Array ของ Element อีกที

กรณี ต้องการ แสดง ตัวที่เลือกบนจอ เพื่อให้ Properties ทำงาน แสดงค่า Element นั้น
ต้องใช้เป็น SetElementIds( ..)

   ICollection<ElementId> sIds = uidoc.Selection.GetElementIds();
            sIds.Clear();
           sIds.Add(showElement.Id);
            uidoc.Selection.SetElementIds(sIds);


สำหรับ Parameter การอ่านค่าจะอณุญาติ ให้ 1 Parameter มี มากกว่า 1 ค่า 

  IList    <Parameter>  l4s = (Parameter)e1.GetParameters("Base Level");
ถ้ามีตัวเดียว ให้เลือก l4s.First();


กรณีเลือกทั้งหมด ใช้วิธี Filter
   FilteredElementCollector collector
              = new FilteredElementCollector(doc)
                .WhereElementIsNotElementType();

            foreach (Element e in collector)

            {
     // do something
            }



วันศุกร์ที่ 6 พฤศจิกายน พ.ศ. 2558

เครื่องมือ Database SQLite กับ C#

เป็นTool สำเร็จรูปสำหรับ การ ทำงานกับ SQLite

https://www.dropbox.com/s/dm7y1t3pthj0et5/PPSqlLite.dll.7z?dl=0

ตัวอย่างวิธีใช้
/*
 * Created by SharpDevelop.
 * User: mcad
 * Date: 11/7/2015
 * Time: 1:16 PM
 *
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using PPSqlLite;

namespace db1
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form
{
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();

//
// TODO: Add constructor code after the InitializeComponent() call.
//
}
void Button1Click(object sender, EventArgs e)
{ // การอ่าน Data
PPSQLLite mysql = new PPSQLLite();
mysql.setSqlDataFile(@"c:\CAADDB\data.db");
ArrayList list1 =mysql.getAColSql("select name from customer");
listBox1.Items.Clear();
foreach(string astr in list1)
{
listBox1.Items.Add(astr);
}

}
void ListBox1SelectedIndexChanged(object sender, EventArgs e)
{
PPSQLLite mysql = new PPSQLLite();
mysql.setSqlDataFile(@"c:\CAADDB\data.db");
ArrayList list1 =mysql.getAColSql("select phone from customer where name='"
                                 +listBox1.SelectedItem.ToString()+"'");
if(list1!=null && list1.Count>0)
{
MessageBox.Show(list1[0].ToString());
}
}
void Button2Click(object sender, EventArgs e)
{ // การ Insert ใหม่ และ เช็คข้อมูลเก่า
PPSQLLite mysql = new PPSQLLite();
mysql.setSqlDataFile(@"c:\CAADDB\data.db");
ArrayList list1 =mysql.getAColSql("select max(id)+1 from customer");

if(list1!=null && list1.Count>0)
{
label1.Text=list1[0].ToString();
   }
string sqlIns="insert into customer values ("+
// insert field here
label1.Text +","+  // id
"'"+textBox1.Text +"',"+ // name
"'"+textBox2.Text +"',"+ // surname
textBox3.Text+","+ // age
"'"+textBox4.Text +"',"+ // phone
textBox5.Text // salary
+")";

// protect double click
ArrayList list2 = mysql.getAColSql("select name from customer where name='"+textBox1.Text+"'");
 if(list2!=null && list2.Count>0)
{
  MessageBox.Show("Already Exist");
 }
 else{
mysql.ExecuteQuery(sqlIns);
 }
 }
}
}

วันศุกร์ที่ 9 ตุลาคม พ.ศ. 2558

Autocad dotnet เวลา GetPoint ใน UCS ที่ไม่ใช่ World ตำแหน่งผิด

ในการ GetPoint ของ Autocad จะต่างกับ Nanocad นิดหนึ่ง คือ ของ Autocad จะได้พิกัดของ UCS นั้นๆ
การให้ เป็น WCS (World) ให้ทำได้โดยการ เอา Matrix ของ UCS นั้น คูณเข้าไป Nano จะได้ World เสมอ

Editor ed = appCad.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;

PromptPointResult ppr = ed.GetPoint("\nSpecify base point: ");
if (ppr.Status != PromptStatus.OK)
    return;

Point3d curPt = ppr.Value.TransformBy(ed.CurrentUserCoordinateSystem);
  

วันพฤหัสบดีที่ 17 กันยายน พ.ศ. 2558

การอ่านค่า Parameter จาก Object และ Type

Parameter ใน Revit มี 2 แบบ แบบที่อยู่ใน Family เรียกว่า ใน Type ยกตัวอย่างเช่นคาน จะมีความกว้าง(b) ลึก (h) เป็นต้น แต่ จะมี Parameter ที่เป็นเฉพาะของ คาน เช่น ความยาว หรือ Length
การอ่านค่า จะต้องแยก กัน

การอ่านค่า ของ Element หรือ Object

 // เริ่ม transaction
            trans.Start();
            // open entity
            Element ent = CachedDoc.GetElement(elementId);

            foreach (Parameter param in ent.Parameters)
            {
                   sParam += param.Definition.Name + "=" + param.AsString() + ",";
            }

            trans.Commit(); // Ok

สำหรับการอ่านค่า Parameter ของ Family (type) ต้อง อ่าน Type มาจาก Element
ent.GetTypeId()

 // เริ่ม transaction
            trans.Start();
            // open entity
            Element ent = CachedDoc.GetElement(elementId);
            Element eltype = CachedDoc.GetElement(ent.GetTypeId());
            foreach (Parameter param in eltype.Parameters)
            {
                     string valueStr =  param.AsString() ;
                    sParam += param.Definition.Name + "=" + valueStr + "\n";
             }
            trans.Commit(); // Ok

สำหรับใช้ Linq จะเหลือบรรทัดเดียว


         Element e = doc.GetElement( r );
          Parameter par1 = e.Parameters.Cast<Parameter>().Where(o => o.Definition.Name == "PE_CODE").First();


ในกรณีของ Family type Parameter ก็คือ Type
  Element eltype = doc.GetElement(el.GetTypeId());
        IList<Parameter> pparam = eltype.GetParameters("abcd); // ใช้ Search ตามชื่อ

            // ถ้ามีตัวเดียว ใช้ pparam[0];

                foreach (Parameter param in eltype.Parameters)
                { // ดูทุกตัว
                ..
            }
 



วันพุธที่ 16 กันยายน พ.ศ. 2558

วันศุกร์ที่ 28 สิงหาคม พ.ศ. 2558

การใช้ Revit Project Parameter สำหรับTrack Object ใน โครงการ

ในการทำงาน โครงการ ในหลายกรณี จำเป็นต้องมีการใส่ Track ลงในวัตถุ ของ Revit  เพื่อ ใช้ในการประมาณราคา การ Track time-line ก่อสร้าง เช่น เสา คาน พื้นเป็นต้น
การสร้าง Parameter ทำได้ไม่ยาก ไปที่

Manage->Project Parameters


โดยที่ Parameter จะมี2 ชนิด คือ Project Parameter กับ Share Parameter  , Project Param. จะอยู่เฉพาะ โครงการ, Share Param. จะ Save และส่งไปยังโครงการหรือ เครื่องอื่นได้
Parameter จะแสดง ใน 2 แบบ คือ Type กับ Instance , Type จะแสดงที่ตัว Family เอง เช่นเลือก เสา จะมี Parameter แสดงที่ Family นั้นๆ ทุกตัวที่ Family นี้วางไปมีค่า common เดียวกัน, Instance จะเป็นค่าที่เฉพาะตัวแต่ละ Element ที่วางไป จะแสดงใน Property

ในภาพแสดง Data ที่เป็น Project Parameter แบบ instance ที่จะใส่ได้ตาม แต่ละ Element เช่น ในเสา
ในบทความต่อไปจะเป็น การนำมาใช้งาน ในโดยการเรียกค่า Param  ในแต่ละ Element มาแสดงผล


การเปิด Element ใน Revit 2016 Api เปลี่ยนแปลง จาก 2014

ใน Revit2016 Api มีการเปลี่ยน การ access ไปยัง Element โดยจะไม่มีการให้การ Access ไปยัง Element ใด โดยตรง เช่น จาก Document จะเรียก Level ก็จะไม่ได้ แต่จะได้ Level element id แทน และ การ Pick Object ก็จะได้ Element Id จากเดิม สามารถเรียก Element ได้โดยตรง
โดย API เดิม ยกเลิก โดยสมบูรณ์ ใน 2016  ข้อดีคือ เขียนโปรแกรมเป็นระบบเดียวกันทั้งหมด
การ ปิด Element จึงต้องเปิดจาก Element Id

     Reference pickedObj = commandData.Application.ActiveUIDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "Please select an element to move.");


     using (Transaction trans = new Transaction(doc, "ERead"))
            {
                // เริ่ม transaction
                trans.Start();
               // open entity
                Element ent = doc.GetElement(pickedObj.ElementId);
        // code here        
              
                trans.Commit(); // Ok
            }

กรณีที่เป็น Level  หรือ อื่นๆ จะใช้ Cast  (as  xxx) เพื่อเปลี่ยนเป็น Class Object ที่ต้องการ



 Level emlv =  doc.GetElement(e1.LevelId) as Level;


วันพุธที่ 3 มิถุนายน พ.ศ. 2558

การตัดกำแพง wall เพื่อการแบ่งแผ่น Precast concrete

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

ตัวอย่างการสร้างกำแพง 
http://spiderinnet.typepad.com/blog/2013/04/revit-net-creation-apis-create-straight-and-curved-walls.html

ในบทต่อไป จะเป็นเรื่อง API ของการเจาะร่องเพื่อยาปูน สำหรับต่อแผ่น Precast



วันอาทิตย์ที่ 31 พฤษภาคม พ.ศ. 2558

ปิด Quick Properites และ Selection Cycling ใน Autocad

เป็นเรื่องน่ารำคาญ สำหรับผู้ใช้งานที่ชำนาญ เวลากด Mouse ที่เส้น แล้ว Autocad ใหม่ จะขึ้น ตัวเลือก แยะไปหมด คือ Quick Properties และ Selection Cycling ว่าจะเลือกเส้นใหน

ให้เรียกคำสั่ง DSettings และ หรือเลือก Mouse ขวาที่ Osnap ด้านล่างของจอก็ได้

แล้ว เลือก ที่ Quick Properties และ Selection Cycling


การออกแบบ Precast Concrete กับ Revit Program

การออกแบบก่อสร้าง ด้วยระบบ Precast Concrete เป็นที่นิยมมากต่อเนื่องมา 10 ปี และ หลายบริษัท ชั้นนำในประเทศไทย ก็นำระบบนี้มาใช้งาน ประสพความสำเร็จเป็นส่วนมาก เนื่องจาก เป็นระบบที่ให้ความแข็งแรง และ ราคาต้นทุนถูกเมื่อเที่ยบกับการก่อสร้างหน้างาน แบบเดิม โดยประมาณ ค่าก่อสร้าง จะลดลงไปถึง 50% และเวลาในการก่อสร้าง ก็เร็วขึ้น ในระบบก่อสร้างที่เป็นรูปแบบโรงงาน สามารถ ผลิตบ้าน นำไปประกอบได้ วันละ 1 หลัง เป็นเรื่องปรกติ

การก่อสร้าง อาคารด้วย Precast มี 6 ขั้นตอน ได้แก่ การ ออกแบบ อาคารให้เหมาะกับ Precast , การแบ่ง ชิ้นงาน ให้เหมาะสมกับการก่อสร้าง, การทำแบบหล่อ และ หล่อชิ้นงาน, เตรียมพื้นที่ฐานราก, การขนส่งและติดตั้ง และ สุดท้ายการตกแต่งให้สวยงาม


การออกแบบ Precast เป็นเรื่องที่ใช้หลักการไม่ซับซ้อน แต่ต้องอาศัย Engineering Sense และความปราณีต ในการออกแบบ ทำแบบหล่อ  และความเป็นไปได้ในการประกอบที่หน้างานด้วย โดยเฉพาะ ขนาดและน้ำหนักของ เครน  งานรายละเอียดของเหล็กเสริมใน ชิ้นงาน Precast ปัจจุบัน บริษัทรับช่วงการผลิต ต่างมีความสามารถ ทำตามความต้องการได้และมีคุณภาพสูง(ปูนซิเมนต์ไทยลงมาทำโรงงานรับหล่อด้วยเทคโนโลยี่สูง ราคาไม่แพงเพราะวัสดุเขาเอง)

กลับมาการออกแบบจึงเป็นเรื่องสำคัญ เนื่องจากถ้า Detail ครบ ปัญหาจะน้อยลง ในการแก้ปัญหาหน้างาน เช่นการเจาะผนัง หรือ ตัดพื้น เป็นเรื่องยากมาก เนื่องจาก ซีเมนต์ที่ใช้ทำ Precast มีความแข็งมาก ( ปรกติ หล่อหน้างาน ประมาณ 180, ถ้าเป็น Precast ประมาณ 300) ทำด้วยเครื่องมือปรกติไม่ได้ ความถูกต้องในการติดตั้ง ชิ้นส่วนต่างๆจึงต้องพอดี

จุดประสงค์ เพื่อการสร้างโปรแกรมจากแบบสถาปัตย์ ไปเป็น แบบ ที่ส่งต่อไปทำ Precast ที่โรงงาน
โปรแกรม Revit เป็นโปรแกรมยอดนิยมในการออกแบบอาคาร 3มิติ และ มี API ในการเขียนโปรแกรมเพิ่มเติม ด้วย ภาษาชั้นสูง เช่น C#  โดยเมื่อพิจารณาจาก โครงสร้างโปรแกรม จะพบว่า มี 3 ส่วน ได้แก่ Modeler สำหรับขึ้นรูป Mass  , Assembly เป็นการวาง Object รวมเป็นอาคาร และ Family สำหรับ Object ที่จะกลายเป็น Precast ต่อไป
ในบทความต่อไป จะเป็นเรื่อง Component ต่างๆของโปรแกรม

Reference
มาตราฐานระบบPrecast Hongkong ปี 2003

วันอังคารที่ 19 พฤษภาคม พ.ศ. 2558

เชื่อม Geometry ชอง NanoCAD(Autocad Clone) กับ Alibre (Geomagic) 3D Cad

เป็นปัญหามานาน ระหว่าง 3D Parametric CAD เช่น Alibre (พวกเดียวกับ Inventor,solidwork) ในการนำเข้า รูปที่ส่งมาเป็น 2 มิติ จาก Autocad ในนี้ ให้พัฒนาโปรแกรมบน Dotnet และ ทำการเชื่อม Automation ไปที่Alibre โดยให้สร้างSketch จาก พิกัด 2D Cad ที่น่ามึนก็คือ เรื่องโค้ง Bulge ของ Polyline ซึ่งต้องกลับไปอ่านสมการ


ของ Bulge ต้องขอบคุณ Website
http://www.afralisp.net/archive/lisp/Bulges1.htm

Bulge = tan(Q/4)
จุด P3 = (VecP2->P1+Vecฉากของ VecP2->P1)/2*bulge