Выбор и редактирование пользовательских примитивов в MultiCAD.NET



    В одной из прошлых статей мы рассказывали о том, как можно создавать пользовательские примитивы с помощью MultiCAD.NET API, взяв за основу пример CustomObjects из SDK. В этой статье мы уделим внимание процедуре поиска и выбора пользовательских объектов и расширим имеющийся пример, добавив возможность выбора одного или нескольких примитивов с помощью инструментария MultiCAD.NET для последующего редактирования. Подробности — под катом.

    Итак, мы имеем пользовательский примитив, представляющий собой прямоугольную рамку с текстовой строкой внутри. Давайте рассмотрим задачу выбора нескольких объектов на чертеже и поменяем текст в каждом из выбранных примитивов.



    Для выбора одного объекта на чертеже в MultiCAD.NET используется метод менеджера объектов SelectObject():

    public static McObjectId SelectObject(string sPromt);
    public static McObjectId SelectObject(string sPromt, ref Point3d pnt);
    

    Оба варианта позволяют пользователю выбрать объект, выводя при этом подсказку в командную строку. Второй метод, кроме строки подсказки, содержит также параметр — точку, в которой был произведен клик.

    Для выбора нескольких объектов используется метод SelectObjects():

    public static List SelectObjects(ObjectFilter filter);
    public static McObjectId[] SelectObjects(string sPromt);
    

    Первый вариант используется для выбора объектов чертежа по заданному фильтру, второй — выводит подсказку в консоль и позволяет пользователю самому выбирать объекты.

    В качестве фильтра выступает объект класса ObjectFilter, который определяет критерии выбора объектов: документы, слои, листы, на которых будет производиться поиск объектов заданного типа. Например, в следующем примере по команде SelectCircles будет получен список объектов типа «окружность», которые находятся на текущем листе и пересекают заданную прямоугольную область:

    [CommandMethod("SelectCircles", CommandFlags.NoCheck | CommandFlags.NoPrefix)]
    static public void SelectCirclesCmd()
    {
      ObjectFilter filter = ObjectFilter.Create(true).AddType(DbCircle.TypeID);
      filter.Bound = new BoundBlock(Point3d.Origin, 
                                    new Vector3d(10, 0, 0), 
                                    new Vector3d(0, 10, 0), 
                                    new Vector3d(0, 0, 10));
      List<McObjectId> ids = filter.GetObjects();
    }
    


    Для выбора всех окружностей на чертеже (не только на текущем листе) следует добавить документ чертежа в качестве области поиска:

    ObjectFilter filter = ObjectFilter.Create(false).SetCurentDocument().AddType(DbCircle.TypeID);
    


    Зарегистрируем новую команду TextInBoxEdit и добавим возможность пользовательского выбора объектов. Затем из всего набора выбранных объектов выделим только пользовательские примитивы типа TextInBox:

    [CommandMethod("TextInBoxEdit", CommandFlags.NoCheck | CommandFlags.NoPrefix)]
    static public void TextInBoxEditCmd()
    {
      McObjectId[] idSelecteds = McObjectManager.SelectObjects("Select TextInBox primitives to edit");
      McObjectId[] idSelectedTextinBox = Array.FindAll(idSelecteds, (s => (s.GetObject()) is TextInBox));
    }
    




    В случае, если хотя бы один из примитивов был выбран, для каждого из них зададим новое значение свойству Text:

    if (idSelectedTextinBox == null || idSelectedTextinBox.Length == 0)
    {
      MessageBox.Show("No TextInBox primitives selected!");
      return;
    }
                		
    foreach (McObjectId currID in idSelectedTextinBox)
    {
      (currID.GetObject() as TextInBox).Text = "Changed text";
    }
    


    Таким образом, текст будет заменен во всех выбранных примитивах.



    Обсуждение статьи доступно также и на нашем форуме: forum.nanocad.ru/index.php?showtopic=6514.

    Английская версия статьи: Selecting and editing custom entities in MultiCAD.NET.
    Нанософт
    92.92
    Компания
    Share post

    Comments 5

      0
      Спасибо за статью! Познавательно.
      Очень интересно выполнен фильтр для SelectObjects, в родном Акадовском АПИ его, кстати, не хватало (а именно выбор по рамке).

      Если позволите, вопрос: для работы SelectObjects нужно чтобы выбранные объекты были в видимой области активного ViewPort? Или не обязательно? Просто когда ковырялся на через Net API автокада, очень долго не мог понять почему в результате работы родного автокадовского метода не все объекты попадают в конечный результат.
      Чтобы понятно проиллюстрирую на примере: видимая область находится в координатах (0,0) — (10,10). Будет ли выделен объект с координатами (-1,-1) если назначить прямоугольную область выделения (-5,-5) — (10,10)?
      PS. Извиняюсь за сумбурность, с утра не очень голова работает :)
        +1
        Будет, фильтрация по ObjectFilter не зависит от видимой области.
          0
          Хм. А менеджер объектов (McObjectManager который) как я понимаю работает с активным документом? Или он работает с текущей базой?
            0
            Он сам по себе, это сервис.
            Документ для поиска задается в ObjectFilter, листы и блоки также рассматриваются как документы.
            Т.е. можно искать в блоке, или в листе, или во всем чертеже. Можно даже не в текущем.

            в принципе McObjectManager даже не нужен, можно написать вот так:
            List objects = ObjectFilter.Create(false).SetCurentDocument().AddType(DbCircle.TypeID).GetObjects();
              0
              Хм. Вот чего так не хватало в автокаде. Очень мощная штука! Отличное решение, в свободное время попробую.

      Only users with full accounts can post comments. Log in, please.