2014-03-05 5 views
0

Revit Macro를 사용하여 파트 (바닥 파트)의 중심점을 가져와 공간 또는 공간에 있는지 확인합니다. BoundingBox 개체의 일부를 나에게 제공 할 수 없어서 Geometry 요소의 내부면을 사용하여 메쉬 정점을 얻으려고했지만 중간 점 계산에 어려움이 있습니다. 아래의 스 니펫에 나와있는 다소 단순한 알고리즘을 사용하고 있지만 초기 기본값 인 최소/최대 변수의 영향을받는 것으로 보이므로 잘못된 결과가 나타납니다. 제안 사항이 있으십니까?Revit에서 Face 또는 PlanarFace 요소의 중심점을 얻는 방법

추신 : DebugTools는 내 자신의 맞춤 도우미 클래스입니다.

public void ZoneDetect() 
{ 
    Document doc = this.ActiveUIDocument.Document; 

    using (Transaction t = new Transaction(doc,"Set Rooms By Region")) 
    { 
     t.Start(); 

     FilteredElementCollector fec = 
      new FilteredElementCollector(doc) 
       .OfClass(typeof(Part)) 
       .OfCategory(BuiltInCategory.OST_Parts) 
       .Cast<Part>(); 

     foreach (Part p in fec) 
     { 


      Options op = new Options(); 
      op.View=doc.ActiveView; 
      op.ComputeReferences=true; 

      GeometryElement gm=p.get_Geometry(op); 
      Solid so = gm.First() as Solid; 
      PlanarFace fc=so.Faces.get_Item(0) as PlanarFace; 

      foreach (PlanarFace f in so.Faces) 
      { 
       if (f.Normal == new XYZ(0,0,-1)) fc=f; 
      } 
      XYZ max = new XYZ(); 
      XYZ min = new XYZ(); 

      int no = 0; 
      foreach (XYZ vx in fc.Triangulate().Vertices) 
      { 
       // Just for debugging 
       DebugTools.DrawModelTick(vx,doc,"Max"); 
       doc.Regenerate(); 
       TaskDialog.Show("Point:"+no.ToString(),vx.ToString()); 
       no++; 

       //Comparing points 
       if (vx.X>max.X) max=new XYZ (vx.X,max.Y,0); 
       if (vx.Y>max.Y) max=new XYZ (max.X,vx.Y,0); 
       if (vx.X<min.X) min=new XYZ (vx.X,min.Y,0); 
       if (vx.Y<min.Y) min=new XYZ (min.X,vx.Y,0); 
      } 

      XYZ mid = new XYZ(max.X-min.X,max.Y-min.Y,0); 

      DebugTools.DrawModelTick(mid,doc,"Mid"); 
      DebugTools.DrawModelTick(max,doc,"Max"); 
      DebugTools.DrawModelTick(min,doc,"Min"); 
     } 

     t.Commit(); 
    } 
} 

답변

0

다각형의 중심을 찾는 것처럼 보입니다. 그 알고리즘은 다음에서 찾을 수 있습니다 : Center of gravity of a polygon

일단 객체가 있으면 Face 객체를 가지면 그 가장자리를 열거하여 정점 목록을 수신 할 수 있습니다. 얼굴에서 가장 긴 것을 EdgeLoops 사용하십시오. 모든 점을 모으고 그들이 올바른 순서로되어 있는지 확인하십시오 (모서리의 시작과 끝 점이 바뀌어야 할 수도 있음).

+1

그렇다면 여전히 무게 중심이 바닥 자체에 있지 않은 가상의 경우가있을 것입니다. 경우에 따라 포인트 그리드를 사용하여 얼굴 안쪽에 포인트가 있는지 여부를 판단하는 것이 좋습니다. – Matt

0

다렌 & 답장을 보내 주셔서 감사합니다. 다소 단순한 모양 (주로 직사각형)을 다루고 있기 때문에 중심에 가깝게 위치하여 시험실 내부에 있는지 확인해야합니다. 내가 사용하고 있던 순진한 알고리즘이 잘못된 것으로 판명되었습니다. 다음과 같이 내가 수정 :

XYZ midSum = Max + Min; 
XYZ mid = new XYZ(midSum.X/2 , midSum.Y/2,0); 

나는 당신이 제공 한 링크를 사용하여 정제로 볼 것이다, 그러나 지금 나는 손에 내 작업을 마무리로 얻을 것이다.

많은 감사합니다.