2012-12-26 4 views
2

Base이라는 속성으로 AutoCAD 도면에 객체가 있습니다. Base 속성을 사용하여 해당 도면의 모든 객체를 찾으려고 할 때 "Pipe"과 같은 특정 문자열 값이 있습니다.Autocad 도면의 특정 속성에 특정 값을 갖는 객체 찾기

도면에서 객체를 반복하고 모든 객체 ID를 얻을 수 있습니다. 그런 다음 해당 ID로 개체의 모든 속성을 가져오고 Base = "Pipe"이라는 속성이 있는지 확인합니다.

반복 성능이 충분하지 않습니다. Base = "Pipe"이라는 속성을 가진 개체 ID를 직접 가져올 수있는 방법이 있습니까? 여기

내가 모든 객체를 반복하는 방법입니다

List<ObjectId> ObjectIds = new List<ObjectId>(); 

    foreach (Document Document in Documents) 
    { 
     Database Database = Document.Database; 

     using (Transaction Transaction = Database.TransactionManager.StartTransaction()) 
     { 
      for (long i = Database.BlockTableId.Handle.Value; i < Database.Handseed.Value; i++) 
      { 
       ObjectId Id; 

       if (Database.TryGetObjectId(new Handle(i), out Id)) 
       { 
         ObjectIds.Add(Id); 
       } 
      } 

      Transaction.Commit(); 
     } 
    } 

을 그리고 여기 내 ObjectIds 컬렉션 개체의 모든 속성을 얻을 방법이다.

public static DataLinksManager DataLinks 
{ 
    get 
    { 
     if (null == _DataLinks) 
     { 
      StringCollection Coll = Autodesk.ProcessPower.DataLinks.DataLinksManager.GetLinkManagerNames(); 

      if (Coll.Count > 0) 
      { 
       if (Coll[0] != string.Empty) 
       { 
        _DataLinks = Autodesk.ProcessPower.DataLinks.DataLinksManager.GetManager(Coll[0]); 
       } 
      } 
     } 

     return _DataLinks; 
    } 
} 

private static DataLinksManager _DataLinks; 

foreach(var Id in ObjectIds) 
{ 
    List<KeyValuePair<string, string>> Properties = DataLinks.GetAllProperties(Id, true); 
    // I check existence of my property and if so its value. 
} 
+0

당신이 현재 가지고있는 코드를 게시하시기 바랍니다 있습니다. –

+0

'Base'속성 값이 'Pipe'인 모든 블록 참조를 찾으려고합니까? – vinayan

+0

예 @vayayan 그것이 내가 받아 들일 수있는 성능으로하려고하는 것입니다. – Demir

답변

1

누구나 필요한 경우, 여기 내 문제를 해결하는 코드가 있습니다. 트릭은 Iterate 메소드입니다. 이것은 Philippe Leefsma의 this article을 기반으로합니다. 이 메서드에 추가 할 내용은 ObjectId 인스턴스의 ObjectClass 속성 목록입니다. 샘플 도핑은 약 8500 ObjectIds입니다. 그러나 무엇 내가 관심이있는 것은 기본 클래스 acppassetacppdynamicasset과 같은 객체의 수와 객체입니다 (90)

using Autodesk.AutoCAD.ApplicationServices; 
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application; 

public static void GetObjects() 
{ 
    List<KeyValuePair<string, ObjectId>> ObjectIds = new List<KeyValuePair<string, ObjectId>>(); 

    List<string> Filter = new List<string>() { "acppasset", "acppdynamicasset" }; 

    foreach (Document Document in this.Documents) 
    { 
     ObjectIdCollection Ids = this.Iterate(Document, Filter); 
     if (null != Ids) foreach (var Id in Ids.OfType<ObjectId>()) ObjectIds.Add(new KeyValuePair<string, ObjectId>(System.IO.Path.GetFileNameWithoutExtension(Document.Name), Id)); 
    } 

    this.Results = new Dictionary<string, List<List<KeyValuePair<string, string>>>>(); 

    foreach (var Id in ObjectIds) 
    { 
     try 
     { 
      var Properties = this.GetObject(Id.Value); 
      if (null == Properties) continue; 

      var Base = Properties.Where(x => x.Key == "Base").FirstOrDefault(); 

      if (string.IsNullOrWhiteSpace(Base.Value)) continue; 

      if (!this.Results.ContainsKey(Base.Value)) this.Results.Add(Base.Value, new List<List<KeyValuePair<string, string>>>()); 

      this.Results[Base.Value].Add(Properties); 
     } catch { } 
    } 
} 

public ObservableCollection<Document> Documents { get; set; } 

public ObjectIdCollection Iterate(Document Document, List<string> Filter = null) 
     { 
      ads_name Instance = new ads_name(); 
      Database Database = Document.Database; 

      ObjectIdCollection ValidIds = new ObjectIdCollection(); 

      // Get the last handle in the Database 
      Handle Handseed = Database.Handseed; 

      // Copy the handseed total into an efficient raw datatype 
      long HandseedTotal = Handseed.Value; 

      for (long i = 1; i < HandseedTotal; ++i) 
      { 
       string Handle = Convert.ToString(i, 16); 

       int Result = acdbHandEnt(Handle, ref Instance); 
       if (Result != 5100) continue; // RTNORM 

       ObjectId Id = new ObjectId(Instance.a); 

       if (!Id.IsValid) continue; 

       try 
       { 
        if (null != Filter) 
        { 
         if (!Filter.Contains(Id.ObjectClass.Name.ToLower())) continue; 
        } 

        using (DBObject DBObject = Id.Open(OpenMode.ForRead, false)) 
        { 
         ValidIds.Add(Id); 
         DBObject.Dispose(); 
        } 
       } catch { } 
      } 

      return ValidIds; 
    } 

    public List<KeyValuePair<string, string>> GetObject(ObjectId Id) 
    { 
     if (Command.DataLinks != null) try { return Command.DataLinks.GetAllProperties(Id, true); } catch { return null; } 
     return null; 
    } 

public static DataLinksManager DataLinks 
{ 
    get 
    { 
     if (null == _DataLinks) 
     { 
      StringCollection Coll = Autodesk.ProcessPower.DataLinks.DataLinksManager.GetLinkManagerNames(); 

      if (Coll.Count > 0) 
      { 
       if (Coll[0] != string.Empty) 
       { 
        _DataLinks = Autodesk.ProcessPower.DataLinks.DataLinksManager.GetManager(Coll[0]); 
       } 
      } 
     } 

      return _DataLinks; 
     } 
    } 

private static DataLinksManager _DataLinks; 

public Dictionary<string, List<List<KeyValuePair<string, string>>>> Results { get; set; } 
1

성능이 저하되는 이유는 모든 개체를 읽고 속성이 포함되어 있는지 확인하기 때문입니다. 내가 아는 한, 속성은 블록 참조 (삽입)에만 존재합니다. 그러므로 selection filters을 사용하면 필터 기준에 따라 해당 레코드에만 직접 액세스 할 수 있습니다.

특정 이름의 모든 블록을 선택하는 선택 필터를 사용하여 매우 쉬운 예제 here을 발견했습니다.

해당 코드의 일부를 참조 용으로 복사 중입니다. 이렇게하면 블록 참조 만 선택됩니다. 여기에서 반복 할 수 있습니다.

TypedValue[] filterlist = new TypedValue[1]; 
filterlist[0] = new TypedValue(0, "INSERT"); 
SelectionFilter filter = new SelectionFilter(filterlist); 

PromptSelectionResult selRes = ed.SelectAll(filter); 

if (selRes.Value.Count != 0) 
{ 
    SelectionSet set = selRes.Value; 

    foreach (ObjectId id in set.GetObjectIds()) 
    { 
     BlockReference oEnt = (BlockReference)tr.GetObject(id, OpenMode.ForWrite); 
     //do something with oEnt..; 
    } 

} 

add complexities to your filter 수있는 경우 아주 작은 세트를 반복해야합니다.

+0

당신의 제안에 감사드립니다. 선택 필터를 사용하면 개체를 선택하면 작동합니다. 필자의 경우 객체를 선택하지 말고 도면 데이터베이스를 반복하면됩니다. – Demir

+0

@Demir - 너 스스로 잘 했어! 약간 수정하여 사용자 상호 작용을 피하십시오 :) – vinayan