28 июня 2013 в 14:11

Чертежи в SVG формате. Часть 1 — Черновик стандарта из песочницы

В интернете можно найти много разной информации о создании чертежей в формате SVG. Чаще предлагается какой-то редактор и экспорт из формата DXF в SVG. Просматривая код SVG сразу видно что там много лишнего. Созданный в одном редакторе файл SVG не всегда может корректно открыться в другом. Одно радует, что браузеры начали поддерживать SVG формат. Всюду пишут про недостатки использования SVG. А может надо придерживаться единых правил структуры файла для отображения чертежей?

Из экспериментов и тестов пришёл к таким правилам при создании чертёжа:
— использование объектной модели чертежа;
— используем только одну единицу измерения (та что по умолчанию в пикcелях);
— условно принимаем — один пиксель равен одному миллиметру (для браузера будет в пикселях, а для нас в мм);
— масштаб описания элементов всегда 1:1;
— для отображения объектов в другом масштабе используем вложенный svg рисунок;
— для уникальных объектов задаём ID а для характерных Class;
— …

Объектная модель чертежа.
Упрощенно чертёж можно описать в виде XML структуры.
<svg id="Detail1" ...>
    <defs id="defsCAD"> ... </defs>
    <svg id="Shtamp" ... >
        ...
    </svg>
    <svg id="View1" ... >
        <line class="atr1" ... />
        <line class="atr1" ... />
        <circle class="atr1" ... />
        <path class="atr1" ... />
        <rect class="atr1" ... />
        <line class="atr2" ... />
        <line class="atr2" ... />
        <g class="dimL">
            <line class="atr2" ... />
            <line class="atr2" ... />
            <line class="atr2" ... />
            <text ... >...</text> 
        </g>
        ...
    </svg>
    <svg id="View2" ... >
        <line class="atr1" ... />
        ...
    </svg>
    <svg id="View3" ... > ... </svg>
</svg>

<svg> — тег используется для описания самого чертежа и встроенных видов, штампа и техтребований. Если необходимо использовать масштаб отличный от 1:1, то реализуется с помощью свойств тега.
Например масштаб 1:4:
<svg id="View1" x="50" y="7" width="150" height="162" viewBox="-25 -200 600 648">

width=«150» height=«162» viewBox="…… 600 648" — соотношение величин задаёт масштаб отображения вида на листе.

Например масштаб 10:1:
<svg id="View1" x="50" y="7" width="150" height="162" viewBox="-0.6 -5 15 16.2">

<defs> — здесь описываем все примитивные повторяющиеся элементы. Замечена одна особенность при использовании SVG элемента Marker — на него не действуют параметры масштаба из тега <svg> что на много упрощает работу с масштабом. (В каком масштабе виды не рисовались, стрелки в размерах должны быть одинаковые). Но на линии в элемента Marker не действует параметр свойства vector-effect: non-scaling-stroke;.

<line class=«atr1» .../> — в файле CSS описываем стили линий для графических примитивов. Жаль что в Internet Explorer для каждого масштаба необходимо указывать свой стиль линии(толщина линии и интервал пунктиров). Как правило в чертеже одновременно не используются все возможные масштабы и достаточно задать только для используемых масштабов.
Пример описания стилей линий для элементов line, circle, path, rect и др.:
line, rect, circle, ellipse, path, text {
  vector-effect: non-scaling-stroke;
}
/* основная */
.lt1 { fill: none; stroke: blue; stroke-width: 2;
}
/* тонкая */
.lt2 { fill: none; stroke: black; stroke-width: .7;
}
/* осевая */
.lt3 { fill: none; stroke: red; stroke-width: .7; stroke-dasharray: 25, 4, 3, 4;
}
/* штриховая */
.lt4 { fill: none; stroke: black; stroke-width: .7; stroke-dasharray: 7, 4;
}
/* основная для масштаба 0.25 */
.lt1_025 { fill: none; stroke: blue; stroke-width: 8;
}
/* тонкая для масштаба 0.25 */
.lt2_025 { stroke: black; stroke-width: 2.8;
}

<g class=«dimL»>...</g> — элементы описывающие объекты как размер группируем.
Пример:
...
<defs id="defsCAD">
<!-- Рисование стрелок и засечек - DimPoint -->
    <marker id="DimPoint1" viewBox="-2 -12 29 24" markerWidth="44" markerHeight="36" orient="auto">
        <path class="lt2_025" stroke="black" d="M0,0 L20,-4 16,0 20,4 z M0,-10 L0,10 M0,0 L27,0"/>
    </marker>
    <marker id="DimPoint2" viewBox="-27 -12 29 24" markerWidth="44" markerHeight="36" orient="auto">
        <path class="lt2_025" stroke="black" d="M0,0 L-20,-4 -16,0 -20,4 z M0,-10 L0,10 M0,0 L-27,0"/>
    </marker>
</defs>
...
    <g class="DimL">
        <line class="lt2" x1="190" y1="180" x2="190" y2="230"/>
        <line class="lt2" x1="310" y1="180" x2="310" y2="230"/>
        <line id="dim1" class="lt2" x1="190" y1="230" x2="310" y2="230" marker-start="url(#DimPoint1)" marker-end="url(#DimPoint2)"/>
        <text x="265" y="222" font-size="28" text-anchor="middle">120</text> 
    </g>
...

Есть одна особенность отображения графики в SVG. Если мы задали область и хотим по краю её нарисовать контур, то должны отступить на пол толщины линии иначе линии будут на половину тоньше. Например кода чёрной рамочки края чертежа.
<svg id="Shtamp" type="1" x="0" y="0" width="420" height="297" viewBox="0 0 420 297">
    ...
    <rect class="lt2" x="1" y="1" width="418" height="295"/>
   ....
</svg>

Демонстрационный пример чертежа с внешним файлом CSS

Файл чертежа с расширением .svg для скачивания. Стили CSS находятся в файле чертежа.

Обновляемая версия статьи

Чертежи в SVG формате. Часть 2 — Черновик стандарта
Виталий @viklviv
карма
11,0
рейтинг 0,0
Самое читаемое Разработка

Комментарии (21)

  • +4
    1 пиксель = 1 миллиметр? Спорно.
    • 0
      Смотря с каким разрешением печатать.
      • +1
        в конце статьи откройте пример в браузере, дальше Файл/Печатать. Распечатайте и посмотрите. При печати укажите растягивание до границ бумаги. SVG формат при масштабировании не теряет качество. Может я не так понял комментарий?
        • 0
          Я имею в виду, что если поставить разрешение при печати 25.4dpi, получится на бумаге ожидаемый размер. Можно и просто растянуть.
    • 0
      условно принято, чтобы задавать единицу измерения в мм как в формате DXF.
      • +2
        Я заметил у Вас в примере следущее:
        <svg width="840" height="594" viewBox="0 0 420 297">
        

        Скажите, пожалуйста, почему Вы не использовали единицы измерения напрямую? В пункте 7.1 (http://www.w3.org/TR/SVG/coords.html) сказано, что очень желательно использовать единицы реального мира.
        <svg width="420mm" height="297mm" viewBox="0 0 420 297">
        


        А вообще, жду продолжения — очень интересно узнать про Ваши правила стилизации и использования текста на чертежах
        • –2
          цитируя стандарт — (очень желательно, но не обязательно)

          одна из причин желание минимизировать сам код чертежа

          • +2
            код чертежа будет меньше только на символы mm в размерах?
            Попробуйте нарисовать шестеренку от наручных часов в таком масштабе.
            Вообще, конечно, дело ваше. Но лучше делать максимально универсально.
            В целом мне очень понравилось, но подрихтовать некоторые моменты стоит.
            • 0
              пишите что подрихтовать, всё рассмотрю и обсудим
            • 0
              в примере для видов использовался масштаб 1:4

              <svg x="50" y="7" width="150" height="162" viewBox="-25 -200 600 648">

              width=«150» height=«162» viewBox="…… 600 648" — соотношение величин задаёт масштаб отображения вида на листе

              шестеренку от наручных часов можно нарисовать на том же формате листа, только к виду применить масштаб 20:1

              <svg x="50" y="7" width="150" height="162" viewBox="-0.3 -2.5 7.5 8.1">
        • 0
          если использовать миллиметры то необходимо всюду использовать одну единицу измерения. В свойстве viewBox тега svg использование миллиметров приводят к багу (рисунок не масштабируется в неодходимый размер на экране).
          Пример штампа чертежа с использованием единицы измерения мм
    • 0
      Ну если SVG позволяет дробные пиксели в размерах и позиции элементов ставить, то почему нет?
      • 0
        <path class="atr2" d="M140,101.34 C144.696,86.7859 152.303,75.3664 162.822,67.0820 C167.996,63.0066 174.363,58.9944 180.459,57.1320 C194.3626,52.8843 213.0561,57.1320 225.5589,67.0820 C232.5067,72.6114 241.8569,77.1221 250,77.9937 C263.3438,79.4220 275.9399,63.2633 290.0,60 C299.5142,57.7918 310.4253,54.6301 319.5409,57.1320 C325.7604,58.8390 332.0035,63.0066 337.1780,67.0820 C347.6966,75.3664 353.3294,89.2060 360,101.3405"/>

        код кривой из нижнего вида примера чертежа (вырез в детали тонкая чёрная волнистая линия)
  • 0
    Может, окажется полезным. В SVG есть vector-effect="non-scaling-stroke", если он выставлен, то толщина stroke (и stroke-dasharray) не зависит от масштаба.

    Демо: www.w3.org/TR/SVGTiny12/examples/non-scaling-stroke.svg
    • 0
      Протестировал, окажется полезным. В плагине jQuery SVG свойство vector-effect не предусмотрено. Спасибо за подсказку.
    • 0
      Это из черновика SVG2 (куда перешел тини), и потому не работает в IE.
      • 0
        тестирую только под Firefox и Chrome, возможно в будущем SVG заменит DXF для CAD систем.
        • 0
          У SVG нет такой задачи, несмотря на недавнее добавление штриховки в спеку SVG 2 :)
          • 0
            Кстати, ничто не мешает принять участие в обсуждении SVG 2, чтобы учесть и эти моменты.
            • 0
              Ну, мы-то (Inkscape) как раз участвуем. Больше того, Тав написал изрядную часть спек в 2.0 — от градиентных мешей до нового типа соединений в контурах.

              Почему этим не занимаются, скажем, авторы LibreCAD и FreeCAD, которым SVG интересен как промежуточный формат — отдельный вопрос :)
  • 0
    SVG вообще прекрасен, особенно с учетом возможности встраивания JS.
    Пример SVGшки для анимации пути


    Или вот карта с огромным количеством объектов на FullHD экран
    Смотрите с 30 секунды

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.