1i7 (1i7) wrote,
1i7
1i7

Category:

Реечная передача и плагины для Инкскейпа

В прошлый раз я сказал, что инструмент для отрисовки шестерёнок в Инкскейпе «Расширения > Отрисовка > Зубчатое колесо...» в качестве единицы измерения использует только абстрактные пиксели и не позволяет выбрать физические меры длины, которые лучше подойдут для нужд реального цифрового производства, например миллиметры.

К нашей удаче, Inkscape является свободным программным обеспечением, а это значит, что любой можеть исправить в нем найденные недочеты или добавить недостающие функции не дожидаясь, пока это решат сделать обладатели проприетарной кодовой базы.

В случае с расширениями для отрисовки объектов в Inkscape всё еще проще - они представляют собой скрипты на языке Python и конфигурационные файлы в формате XML, которые можно добавлять и редактировать в любом текстовом редакторе и запускать на любом компьютере с установленным Inkscape (все приложение целиком собирать из исходников не нужно).

В диалог с параметрами шестерёнки добавил новый параметр "Единица измерения" (англ. Unit), который определяет единицу измерения для параметра "Шаг колеса" (на картинке с русским переводом он превратился в английскую версию Circular pitch, т.к. из строки с именем параметра я убрал уточнение по пиксели и из-за этого поплыли файлы с переводом, которые я не исправлял). К параметрам "Количество зубцов" и "Угол зацепления" он не относится.

inkscape-gears-04.png

Чтобы установить исправленное расширение у себя в системе, нужно скачать два файла:
inkscape/extensions/gears1.inx (файл XML с настройками расширения)
inkscape/extensions/gears1.py (код расширения на языке Пайтон)

и скопировать их в каталог ~/.config/inkscape/extensions в Linux или в C:\Users\user\AppData\Roaming\inkscape\extensions в Windows. После этого перезапустить Inkscape, исправленный диалог для отрисовки шестеренки появится в меню «Расширения > Отрисовка > Gear1...» (я исправил имя на временное Gear1, чтобы не вносить путаницу со старым расширением; при желании можно также просто исправить расширение «Зубчатое колесо» из стандартной поставки Инкскейпа, для этого нужно заменить содержимое файлов gears.inx и gears.py в каталоге C:\Program Files (x86)\Inkscape\share\extensions в Windows на содержимое файлов, приведённых выше).

Реечная передача

Также в текущей версии Inkscape вообще отсутствовала возможность нарисовать плоскую дощечку с зубами от шестерёнки (реечная передача, англ. rack and pinion). Такая штука может оказаться полезной для того, чтобы превращать вращательное движение с моторчиков и сервомоторчиков в поступательное движение рейки; пригодится при проектировании каких-нибудь подвижных узлов для роботизированных механизмов, которые можно будет вырезать лазером.

Вообще говоря, нарисовать правильную форму зубца для шестерёнки не так просто, как кажется на первый взгляд. При её расчете используется большое количество (ну может и не очень большое, но в них все равно нужно вникать) разных параметров и формул, вот несколько случайных ссылок:
https://ru.wikipedia.org/wiki/Реечная_передача
https://ru.wikipedia.org/wiki/Зубчатая_передача
http://en.wikipedia.org/wiki/Rack_and_pinion
http://en.wikipedia.org/wiki/Gear
http://www.prikladmeh.ru/lect4.htm
http://expertmeet.org/topic/17156-передачи-движения/
http://allrefs.net/c12/3uly5/p14/?full

Разбираться во всех этих теориях и формулах мне не очень хотелось, поэтому для отрисовки реечной передачи я взял за основу код для отрисовки шестеренки из предыдущего расширения и просто сделал так, чтобы нужное количество зубов размножалось по прямой линии, а не по окружности.

Файлы для расширения:
inkscape/extensions/rack_and_pinion.inx (файл XML с настройками расширения)
inkscape/extensions/rack_and_pinion.py (код расширения на языке Пайтон)

Их нужно точно также скопировать в каталог ~/.config/inkscape/extensions в Linux или в C:\Users\user\AppData\Roaming\inkscape\extensions в Windows, перезапустить Inkscape, новый диалог для отрисовки реечной передачи появится в меню «Расширения > Отрисовка > Rack and pinion...»

inkscape-gears-03.png


Чтобы нарисовать совместимые между собой зубчатое колесо и реечную передачу, нужно при их создании задать одинаковые значения параметров "Шаг колеса" (Circular pitch) и Угол зацепления (Pressure angle); количество зубцов в обоих случаях может быть любым.

inkscape-gears-06.png

Я также отправил ссылки на эти исправления в багтрекер Inkscape и в процессе выяснил, что, во-первых, в репозитории с исходным кодом уже есть новое расширение для отрисовки реечной передачи (вероятно, оно может появиться уже в следующем релизе), во-вторых, в работе есть еще одна улучшенная версия расширения для отрисовки зубчатого колеса с большим количеством дополнительных параметров.



Собственное расширение для Inkscape: код на Пайтон рисует прямоугольник

Ну и напоследок посмотрим, как можно легко добавлять собственные расширения в Inkscape. Как я уже сказал выше, с механизмом расширений двумерные векторные объекты на рабочей области Inkscape можно рисовать при помощи программы на языке Python. Это довольно мощная возможность, т.к. с её помощью для рисования объектов можно использовать какие-нибудь интересные математические формулы или же просто генерировать сложные структуры из множества узлов, имея под рукой все возможности процедурного языка типа сложных условий, циклов и подпрограмм.

Попробуем добавить к Inkscape расширение, которое будет рисовать прямоугольник с заданной шириной и высотой (функция не самая полезная, т.к. прямоугольники гораздо удобнее рисовать при помощи специального инструмента мышкой, но для быстрого знакомства самое то). В диалоге отрисовки прямоугольника будет 3 параметра: ширина (Width), высота (Height) и единица измерения (Unit) для этих значений:

inkscape-gears-07.png

Сначала создаём и правим файл XML demo_rectangle.inx, который содержит базовую информацию о расширении: имя, уникальный идентификатор, список скриптов Пайтон, которые необходимы для его работы, список параметров для скрипта (диалог генерируется автоматически на основе этого списка), адрес в главном меню программы, ссылка на исполняемый скрипт на языке Пайтон (demo_rectangle.py).

inkscape/extensions/demo_rectangle.inx

<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension xmlns="http://www.inkscape.org/namespace/inkscape/extension">
    <_name>Demo rectangle</_name>
    <id>org.ekips.filter.demo_rectangle</id>
    
    <dependency type="executable" location="extensions">demo_rectangle.py</dependency>
    <dependency type="executable" location="extensions">inkex.py</dependency>
    
    <param name="width"    type="float" min="0.0"  max="1000.0"    _gui-text="Width">62.0</param>
    <param name="height"   type="float" min="0.0"  max="1000.0"    _gui-text="Height">38.0</param>
    <param name="unit"     type="optiongroup" appearance="minimal" _gui-text="Unit">
      <option value="cm">cm</option>
      <option value="ft">ft</option>
      <option value="in">in</option>
      <option value="m">m</option>
      <option value="mm">mm</option>
      <option value="pc">pc</option>
      <option value="pt">pt</option>
      <option value="px">px</option>
    </param>
    
    <effect>
      <object-type>all</object-type>
      <effects-menu>
        <submenu _name="Render"/>
      </effects-menu>            
    </effect>
    
    <script>
      <command reldir="extensions" interpreter="python">demo_rectangle.py</command>
    </script>
</inkscape-extension>


Второй и последний файл - скрипт на языке Python, которые будет генерировать наш прямоугольник с заданными параметрами.

Здесь мы видим некоторое количество вспомогательного кода: добавление параметров в объект self.OptionParser (они должны быть все те же, что перечислены в файл demo_rectangle.inx), чтение параметров с нужной размерностью, запуск расширения с e.affect().

Сам прямоугольник создаётся в одной единственной строке - координаты вершин на плоскости помещаются в массив points. В этой части будет больше интересного кода в том случае, если расширение будет рисовать что-то более полезное, чем простой прямоугольник.

Далее из точек в массиве points просто генерируется правильный код SVG для добавления на рабочую область, я не сильно вникал в то, что именно он делает, просто взял из кода подвернувшегося под руку соседнего расширения.

inkscape/extensions/demo_rectangle.py

#! /usr/bin/env python
'''
Simple Inkscape plugin demo - draw rectangle with given width and height.
'''

import inkex
import simplestyle, sys

def points_to_svgd(p):
    f = p[0]
    p = p[1:]
    svgd = 'M%.3f,%.3f' % f
    for x in p:
        svgd += 'L%.3f,%.3f' % x
    svgd += 'z'
    return svgd

class Rectangle(inkex.Effect):
    def __init__(self):
        inkex.Effect.__init__(self)
        self.OptionParser.add_option("-w", "--width",
                        action="store", type="float",
                        dest="width", default=62.0,
                        help="Rectangle width")
        self.OptionParser.add_option("-H", "--height",
                        action="store", type="float",
                        dest="height", default=38.0,
                        help="Rectangle height")
        self.OptionParser.add_option("-u", "--unit",
                        action="store", type="string",
                        dest="unit", default="px",
                        help="The unit of dimensions")
    def effect(self):

        width  = self.unittouu( str(self.options.width) + self.options.unit )
        height = self.unittouu( str(self.options.height) + self.options.unit )

        # Debug messages
        #inkex.debug( "Width=" + str(width) + ", height=" + str(height) )

        # Generate rectangle points
        points = [ (0, 0), (width, 0), (width, height), (0, height) ]

        # Convert points to svg path
        path = points_to_svgd( points )

        # Embed rectangle in group to make animation easier:
        # Translate group, Rotate path.
        t = 'translate(' + str( self.view_center[0] ) + ',' + str( self.view_center[1] ) + ')'
        g_attribs = {inkex.addNS('label','inkscape'):'Demo rectangle', 'transform':t }
        g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs)

        # Create SVG Path for demo rectangle
        style = { 'stroke': '#000000', 'fill': 'none' }
        rectangle_attribs = {'style':simplestyle.formatStyle(style), 'd':path}
        rectangle = inkex.etree.SubElement(g, inkex.addNS('path','svg'), rectangle_attribs )

if __name__ == '__main__':
    e = Rectangle()
    e.affect()


# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99


Копируем оба файла в каталог ~/.config/inkscape/extensions в Linux или в C:\Users\user\AppData\Roaming\inkscape\extensions в Windows, перезапускаем Inkscape, наблюдаем новый диалог для отрисовки собственной фигуры в меню «Расширения > Отрисовка > Demo rectangle...». Inkscape нужно перезапускать только в том случае, если изменился файл demo_rectangle.inx. После правки скрипта Пайтон в файле demo_rectangle.py Inkscape перезапускать не обязательно, можно даже не закрывать диалог с параметрами расширения, просто после сохранения файла со скриптом в текстовом редакторе, в диалоге расширения нажать еще раз кнопку "Применить".

Перевод строк названиями параметров, которые отображаются в диалоге с настройками расширения, - это отдельная история, пока можно просто использовать латиницу; при особом желании инструкции по переводу можно поискать на сайте inkscape.org.

Более подробное руководство: Write an Inkscape extension: create multiple duplicates



исходники занятия, подсветка синтаксиса
Tags: 2д-моделирование, inkscape, типовые задачи, шестеренки
Subscribe

  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 4 comments