OpenToonz 1.7.1
Если вам нравится компьютерная анимация, вы знаете, чтобы создавать свои проекты требуется дорогое ПО, бывают и бесплатные анимационные приложения, но чаще они сложно ориентироваться или просто они не функциональные. Перед вами OpenToonz, бесплатный инструмент для 2D-анимации, выпущенный разработчиком программного обеспечения Dwango, данный софт призван решить эту проблему, его авторы предлагают вам ПО, которое не только удобно в работе, но и имеет множество функций.
OpenToonz позволяет создавать 2-мерные анимации разными способами, включая сканирование или цифровые рисунки. Вы можете сканировать 4 способами: черно-белое, цветное с бинаризацией или без бинаризации. В качестве бонуса нет необходимости вручную настраивать параметры сканирования, поскольку программа сохраняет эти настройки, а также умеет реплицировать процессы во время повторного сканирования разрезов.
У OpenToonz есть прикольная фишка, меню эффектов изображения, которые варьируются от способности влиять на падающий свет и создавать волнистые искажения до полного изменения стилей изображения. Если вам нравится изменять исходный код и настраивать программы, вы особенно оцените, что приложение поставляется с открытым исходным кодом. Программа совместима со стандартом TWAIN и работает с версиями Windows 7 SP1, 8.1 и 10.
OpenToonz базируется на ПО Toonz, которое было создано итальянской компанией Digital Video SPA и японской Studio Ghibli. Из этого получаем, что две компании работают вместе с Dwango над запуском OpenToonz, поэтому и такая отличная программа в итоге получается. Авторы утверждают, что данная разработка может конкурировать с платными продуктам.
К сожалению, пока OpenToonz Portable версии нет, если у вас имеется другая информация, обязательно поделиться ей в комментариях, тоже самое касается версии на Русском языке, скачать ее не получится, изначально программа поддерживает 4 языка, среди которых, привычно нам с вами, нет, если кто хочет понять как пользоваться OpenToonz, можете поискать уроки, их набралось уже достаточное количество в Интернете, конечно сравнивать с платными аналогами не стоит, но все же научиться основным моментам вполне реально.
Размер: 54 MB
ОС: Windows 7+
Скачать OpenToonz 1.7.1 бесплатно
Обзор интерфейса¶
Интерфейс OpenToonz организован в комнаты, также известные как рабочие пространства: каждая комната представляет собой различную коллекцию окон, которые расположены в определенных местах на экране.
Использование комнат¶
Доступные комнаты перечислены в дальнем правом углу строки меню. Каждая из них всегда отображает содержимое текущей сцены.
Комнаты могут быть названы и их порядок может быть изменен. Новые комнаты могут быть добавлены, а существующие комнаты могут быть удалены. Когда комната добавлена, она пуста; для её настройки можно добавлять панели по одной (см. ниже).
Чтобы войти в комнату:
Нажмите на соответствующую вкладку в правой части строки меню.
Чтобы назвать комнату:
Дважды щелкните вкладку и введите имя, которое вы хотите присвоить комнате.
Чтобы заказать номерные вкладки:
Нажмите и перетащите вкладку на новую позицию.
Чтобы добавить новую комнату:
Щелкните правой кнопкой мыши в области вкладок комнаты и выберите «Новая комната» в открывшемся меню.
Чтобы удалить комнату:
Щелкните правой кнопкой мыши вкладку комнаты и выберите Удалить комнату «» в открывшемся меню. Текущая комната не может быть удалена.
To return to the set of rooms provided with OpenToonz:
Choose Windows → Workspace → Reset to Default Rooms.
Настройка комнат¶
Комнаты можно изменить, установив разные размеры для разных панелей и добавив или удалив панели. Чтобы предотвратить случайное добавление или удаление панелей, конфигурация комнат может быть заблокирована.
Большинство панелей можно развернуть, чтобы заполнить весь интерфейс, и их можно добавить в виде плавающих окон с помощью меню Окна.
Чтобы изменить размер панели в комнате:
Щелкните любой вертикальный или горизонтальный разделитель и перетащите его в новое положение.
Некоторые панели, такие как панель инструментов и полоса уровня, имеют фиксированный размер, поэтому их нельзя изменить.
Чтобы открыть панель как плавающее окно:
Выберите в меню Окна панель, которую вы хотите открыть.
Чтобы изменить размер плавающего окна:
Нажмите и перетащите границу или угол окна.
Чтобы закрыть плавающее окно или диалог:
Нажмите кнопку закрытия справа от строки заголовка.
Чтобы добавить панель в комнату:
- Используйте меню Окна, чтобы открыть панель как плавающее окно.
- Нажмите и перетащите строку заголовка, чтобы переместить ее и отпустите, чтобы закрепить ее в соответствии с выделенной точкой вставки.
Попытка пристыковать панель к крайней левой / правой части интерфейса может завершиться неудачей, если в этот момент главное окно OpenToonz развернуто. Чтобы преодолеть это, вы можете восстановить размер основного окна, закрепить нужную панель, а затем развернуть ее обратно.
Чтобы удалить панель из комнаты:
- Нажмите и перетащите строку заголовка панели, которую хотите удалить, чтобы отсоединить ее от комнаты.
- Закройте плавающее окно.
Чтобы развернуть или свернуть развернутую панель:
Дважды щелкните строку заголовка.
Некоторые панели, такие как панель инструментов и полоса уровня, имеют фиксированный размер, поэтому их нельзя развернуть.
Для блокировки/разблокировки конфигурации комнат:
Activate/deactivate the Windows → Workspace → Lock Room Panes option.
Панели комнаты¶
Ниже приведен список панелей (в том же порядке, в котором они появляются в меню Окна), которые можно использовать для создания комнат и которые можно открывать как плавающие окна.
Пакетные серверы¶
Окно «Пакетные серверы» позволяет обрабатывать пакетный список с помощью рендер-фермы и содержит информацию о списке узлов сервера (рендеринга), определенных для фермы.
Настройки очистки¶
Панель «Настройки очистки» позволяет вам определить параметры процесса очистки отсканированных растровых изображений, чтобы преобразовать их в растровые изображения Toonz, готовые для рисования в OpenToonz.
Цветовая модель¶
Средство просмотра цветовой модели отображает изображение или уровень анимации, которые вы загрузили в качестве эталона для рисования текущего уровня анимации.
Браузер файлов¶
Браузер файлов позволяет загружать и сохранять файлы и получать доступ к проектам.
Слева находится дерево файлов с некоторыми основными папками, содержащими материалы, хранящиеся на вашем компьютере: My Computer, Network, My Documents, History, Library and Projects. Вы можете открывать папки и подпапки для получения файлов, которые отображаются в области справа.
Flipbook¶
Flipbook может отображать уровни анимации, клипы или последовательности изображений. Его можно использовать для проверки уровней, например, перед их загрузкой, или для управления визуализированной последовательностью.
Редактор функций¶
Редактор функций сопоставляет объекты и преобразования FX со значениями ключа и соответствующими интерполяциями с использованием электронной таблицы или графического редактора. Он разделен на два раздела: слева есть область, где отображается электронная таблица или редактор графиков, справа вверху — область, где отображается интерполяция текущего сегмента преобразования, а справа внизу — объекты / FX дерево.
Level Strip¶
Level strip отображает последовательность рисунков, принадлежащих уровню, выбранному в настоящий момент в таблице Xsheet.
Это помогает вам редактировать последовательность рисунков и видеть все рисунки текущего уровня, даже если эти рисунки не отображаются в Xsheet.
Палитра¶
Она отображает стили, определенные для текущего уровня, или, если он неактивен, стили, определенные для ранее выбранного уровня.
Состав сцены¶
Состав сцены позволяет вам управлять файлами, загруженными в сцену, сохранять их и загружать новые. Это может быть организовано в папках и подпапках.
Схема¶
Схема может альтернативно отображать информацию о стадии или специальном использовании FX.
Схема сцены отображает в виде узлов все объекты, определенные в сцене, то есть столбцы, вешалки, камеры, таблицы и траектории движения, и позволяет вам управлять способом, которым они связаны друг с другом.
Схема FX позволяет применять FX к содержимому столбцов Xsheet и управлять их применением. Все столбцы и FX отображаются как узлы, которые можно подключить, чтобы установить, как FX влияет на содержимое сцены.
Палитра Studio¶
Палитра Studio позволяет хранить неограниченное количество палитр уровней. Отсюда любая палитра может быть извлечена и назначена текущему уровню для его рисования, без необходимости определять одни и те же стили снова и снова. Он также включает в себя средство просмотра, отображающее стили текущей выбранной палитры.
Редактор стилей¶
Редактор стилей позволяет изменять стили палитры. Вы можете выбрать тип стиля: цвет, текстура, вектор и растр. Также есть вкладка настроек, где вы можете выбрать некоторые параметры для стиля.
Задания¶
Окно Задания содержит дерево задач со всеми задачами, отправленными на пакетную обработку, и сведения о задаче, выбранной в данный момент в дереве. Из дерева задач вы можете запустить или остановить выполнение задачи или удалить ее.
Центр сообщений¶
The message center displays in a list the messages OpenToonz is sending to the user. You can set filters on the messages showed in the window using the appropriate radio buttons, or you can clear the list completely by pressing the Clear button.
Панель инструментов¶
Панель инструментов содержит инструменты для рисования, выбора и редактирования рисунков, а также для анимации таких объектов, как камера, столбцы и вешалки. Инструменты на панели инструментов могут использоваться только в главном окне просмотра.
сли панель инструментов слишком короткая для отображения всех инструментов, ее можно прокручивать с помощью кнопок со стрелками, имеющихся на ее концах.
Инструмент анимирования изменяет положение, вращение и размер текущих объектов (см. Анимирование объектов ).
Инструмент выделения выполняет выделение и преобразует его (см. Использование инструмента выделения ).
Кисть рисует в рабочей области в режиме рукописного ввода (см. Рисование с помощью инструмента Кисть ).
Геометрический инструмент рисует геометрические фигуры (см. Рисование с помощью геометрического инструмента ).
Инструмент шрифта добавляет текст, устанавливая шрифт и размер (см. Добавление текста ).
Заливка заполняет области рисования текущим стилем (см. Покраска областей ).
Инструмент покраски рисует линии и области в растровых рисунках Toonz в режиме рукописного ввода. (см. Покраска областей ).
Ластик удаляет векторы на векторных рисунках, а также закрашенные области и линии на растровых рисунках (см. Инструменты рисования ).
Скотч объединяет два открытых конца одного или двух векторов в векторных рисунках или закрывает пропуски в растровых рисунках (см. Соединение и разделение ).
Пипетка выбирает стиль из текущего чертежа, который становится текущим стилем в палитре и в редакторе стилей.
Инструмент RGB пипетка выбирает красные, зеленые и синие значения из содержимого средства просмотра и применяет их к текущему стилю (см. Простые цвета ).
Редактор контрольных точек изменяет векторную форму, редактируя ее контрольные точки (см. Редактирование векторных контрольных точек ).
Щипок изменяет векторную форму, щелкая и перетаскивая в любом месте вектора (см. Изменение изгиба векторов ).
Насос локально изменяет толщину вектора, нажимая на участок, на который вы хотите повлиять, а затем перетаскивая его вверх или вниз (см. Использование других инструментов модификатора ).
Магнит деформирует несколько векторов одновременно, щелкая область, на которую вы хотите повлиять, и перетаскивая ее (см. Использование других инструментов модификатора ).
Клещи изгибает векторы в векторных рисунках (см. Использование других инструментов модификатора ).
Утюг удаляет складки из векторов, перемещая курсор на вектор, который вы хотите сгладить (см. Использование других инструментов модификатора ).
Нож разбивает вектор на две части при нажатии на него (см. Соединение и разделение ).
Скелет определяет модели персонажей и анимирует их, как в анимации вырезов (см. Использование инструмента Скелет ).
Крюк определяет контрольные точки, которые будут использоваться в схеме этапа для перемещения объекта или связывания одного объекта с другим (см. Использование крюков ).
Трекер отслеживает определенные области в последовательности изображений (см. Трекинг-точки ).
Plastic tool создает сетку, которая позволяет деформировать и анимировать персонажа или его часть (см. Использование Plastic tool ).
Лупа увеличивает и уменьшает содержание зрителя; после щелчка можно перетащить вверх, чтобы увеличить рабочую область, или перетащить, чтобы уменьшить масштаб.
Рука панорамирует контент зрителя; если активирован 3D-вид, инструмент «Рука» также позволяет перемещаться по 3D-виду.
Поворот вращает содержимое просмотра; Если 3D-вид активирован, инструмент Повернуть позволяет изменить точку обзора.
Панель параметров инструмента¶
Панель параметров инструмента отображает настройки для текущего инструмента, если он есть.
Например, он позволяет установить толщину и другие свойства инструмента «Кисть».
Если панель параметров инструмента слишком короткая для отображения всех параметров инструмента, ее можно прокручивать с помощью кнопок со стрелками, имеющихся на ее концах.
Панель команд¶
Панель команд — это место, где пользователь может отображать любимые инструменты и команды OpenToonz, чтобы они были легко доступны.
Панель командной панели может быть закреплена в любой части интерфейса OpenToonz.
Если панель команд слишком короткая для отображения всех командных кнопок, справа от нее появится символ двойной стрелки, позволяющий отобразить раскрывающееся меню с остальными.
Для отображения панели команд:
Чтобы настроить кнопки панели команд:
- Choose Windows → Command Bar to open the Command Bar.
- Щелкните правой кнопкой мыши по нему и выберите Настройка панели команд в открывшемся меню. Откроется окно «Настройка панели команд».
- Чтобы добавить команду: найдите команду в списке Элементы панели инструментов (справа) и перетащите ее в список Панель команд (слева).
- Чтобы добавить разделитель: в конце списка Элементы панели инструментов (справа) перетащите элемент —-Разделитель—- в список Панель команд (слева).
- Чтобы удалить команду: найдите команду в списке Панель команд (слева), щелкните ее правой кнопкой мыши и выберите Удалить в открывшемся меню.
- Нажмите OK, чтобы принять изменения или Отмена, чтобы отменить их.
Просмотрщик¶
Просмотрщик — это рабочая область, в которой вы можете рисовать изображения и одновременно видеть результат композитинга. Это бесконечно, и вы можете прокручивать, увеличивать, уменьшать и поворачивать его так, как вы предпочитаете.
Он имеет различные режимы визуализации, среди которых вы можете выбрать наиболее подходящий для выполняемой вами операции.
ComboViewer¶
Comboviewer объединяет в одной панели средство просмотра, горизонтальную панель инструментов и панель параметров инструмента.Это и альтернативная рабочая область, где вы можете рисовать изображения и одновременно видеть результат вашего композитинга. Это бесконечно, и вы можете прокручивать, увеличивать, уменьшать и по
Он имеет различные режимы визуализации, среди которых вы можете выбрать наиболее подходящий для выполняемой вами операции.
Xsheet¶
Xsheet позволяет вам управлять содержимым сцены так же, как и временной шкалой. Он организован в столбцы, а столбцы разделены на ячейки, представляющие содержимое этого столбца в данном конкретном кадре. В столбцы можно загружать уровни анимации, клипы, изображения, аудиофайлы или другие таблицы Xsheets.
Каждый столбец имеет свой собственный заголовок, содержащий информацию о его содержании. В крайнем левом столбце отображается номер кадра с курсором на текущем кадре. Область заголовков и столбец фрейма всегда видны даже при прокрутке области Xsheet; таким образом легче понять, как строится сцена.
Кадры отображаются с чтением изображений слева направо в каждой строке ячейки.
Таймлайн¶
Таймлайн позволяет вам управлять содержимым сцены так же, как Xsheet. Он организован в горизонтальных слоях, и слои разделены на ячейки, представляющие содержимое этого слоя в этом конкретном кадре. В слоях вы можете загружать уровни анимации, клипы, изображения, аудиофайлы или другие временные шкалы.
В самой левой части каждый слой имеет свой собственный заголовок, содержащий информацию о его содержимом. В верхней части временной шкалы есть линейка времени, которая отображает номер кадра с курсором на текущем кадре. Область заголовков и линейка времени всегда видны, даже при прокрутке области шкалы времени; таким образом легче понять, как строится сцена.
Кадры отображаются с чтением изображений снизу вверх в каждом столбце ячейки.
История¶
Панель истории, позволяет проверять и отменять/повторять историю последних действий, выполненных в текущей сцене OpenToonz.
Запись аудио¶
Окно записи аудио, позволяет записывать источник звука в реальном времени, прослушивать его и вставлять в новый аудио-столбец таблицы Xsheet.Точка вставки будет расположена справа от выбранного столбца ячейки и начинается с выбранного кадра ячейки.
В настоящее время это окно нельзя закрепить, чтобы образовать часть комнаты, как и другие в меню Окна. Вместо этого оно должно быть открыто как плавающее окно, когда это необходимо.
Настройка внешнего вида интерфейса¶
Внешний вид интерфейса OpenToonz можно настроить в соответствии с любой производственной потребностью, выбрав требуемый язык и тему интерфейса.
OpenToonz позволяет пользователям выбирать определенный язык для интерфейса программного обеспечения, включая меню, команды, всплывающие подсказки и сообщения на экране. В настоящее время доступны следующие языки: английский, немецкий, испанский, французский, итальянский, русский, японский и китайский.
There are also several included themes to choose from: Default, Blue, Dark, Light and Neutral.
The OpenToonz interface theme set to Default and to Light.
Темы интерфейса определяются с помощью файла QSS, концепции, терминология и синтаксис которого основаны на файлах CSS (HTML Cascading Style Sheets). Файлы QSS также относятся к набору изображений PNG, которые используются для создания виджетов интерфейса.
Эти файлы хранятся в папке, называемой файлом QSS, и находятся в папке C:\OpenToonz stuff\config\qss для Windows и OpenToonz stuff\config\qss для macOS.
Файл QSS для Macintosh назван с суффиксом _mac.
Файл QSS можно редактировать с помощью любого программного обеспечения для текстового редактора, например, Блокнот или TextEdit; PNG изображения с любым программным обеспечением для редактирования изображений. Редактирование файла QSS требует определенных навыков в языке CSS, но некоторые изменения, такие как цвета элементов панели, можно легко сделать, выразив их в красных, зеленых и синих значениях.
Файлы QSS, определяющие цвета и изображения, используемые в интерфейсе OpenToonz, должны быть записаны в соответствии с определенным синтаксисом, иначе интерфейс OpenToonz не будет отображаться должным образом. Если вы решите отредактировать файл QSS, сначала сделайте резервную копию на тот случай, если вам потребуется вернуть файл к исходной версии.
Чтобы выбрать язык интерфейса:
- Choose File → Preferences… → Interface.
- В меню опций Language* выберите язык, который вы хотите использовать в интерфейсе.
- Перезапустите OpenToonz, чтобы открыть интерфейс на выбранном языке.
Для выбора темы интерфейса:
- Choose File → Preferences… → Interface.
- В меню параметров темы выберите стиль, который будет применяться к интерфейсу.
Для создания новой темы:
- Перейдите в папку C:\OpenToonz stuff\config\qss для Windows или OpenToonz stuff\config\qss для macOS.
- Дублируйте одну из уже существующих папок стилей.
- Переименуйте папку и файлы QSS внутри нее, указав имя, которое вы хотите присвоить теме.
- Отредактируйте файл QSS и изображения PNG, содержащиеся в новой папке.
Новый стиль будет доступен в диалоге настроек при следующем запуске OpenToonz.
Для редактирования файла стиля QSS:
Откройте и отредактируйте с помощью программного обеспечения текстового редактора (например, «Блокнот» или «TextEdit») файлы QSS, доступные в папке стилей.
Чтобы редактировать изображения в стиле:
Откройте и отредактируйте с помощью программного обеспечения для редактирования изображений файлы PNG, доступные в папке стилей.
© Copyright : This page is licensed under a CC-BY-NC 4.0 Int. License Revision a03b0c24 .
Built with Sphinx using a theme provided by Read the Docs.
Read the Docs v: latest
Versions latest Downloads pdf html epub On Read the Docs Project Home Builds Free document hosting provided by Read the Docs.
OpenToonz: снаружи и внутри
Прошло уже почти четыре года с тех пор, как PVS-Studio поверял исходный код OpenToonz. Этот проект является очень мощным инструментом для создания двухмерной анимации. За время с последней проверки с его помощью были созданы такие мультипликационные произведения, как Мэри и Ведьмин цветок, Бэтмэн-Нинзя, Промаре и другие. Раз большие студии продолжают пользоваться Toonz, то почему бы не проверить качество исходного кода еще раз?
С предыдущим разбором ошибок можно познакомиться в статье «Плохой код пакета для создания 2D-анимаций Toonz». В целом не похоже, что качество кода сильно повысилось, так что общее впечатление лучше не стало. К тому же, было обнаружено множество тех же ошибок, что и в предыдущей статье. Повторно мы их рассматривать не будем, благо выбрать новые есть из чего.
Впрочем, надо понимать, что наличие ошибок вовсе не обязательно мешает активно и продуктивно использовать программный продукт. Скорее всего, найденные ошибки живут в редко используемых или вовсе в неиспользуемых участках кода, иначе они были бы выявлены в процессе использования приложения и исправлены. Однако, это не значит, что статический анализ избыточен. Просто смысл статического анализа не в поиске старых и неактуальных ошибок, а в удешевлении процесса разработки. Многие ошибки при написании кода могут быть выявлены сразу, а не в процессе эксплуатации ПО. Соответственно, при регулярном использовании статического анализатора, ошибки исправляются на самом раннем этапе. Это экономит и время разработчиков, и деньги компании, и улучшает восприятие продукта пользователями. Согласитесь, неприятно постоянно отписывать разработчикам, что не работает то одно, то другое.
Фрагмент N1
V610 Undefined behavior. Check the shift operator ‘
decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) < int p1, m1; p1 = 1 Al; m1 = (-1) Al; . >
Не совсем ясно, чего автор кода хотел добиться здесь. Использование операторов сдвига с отрицательными числами приводит к неопределенному поведению. То, как поведение операторов сдвига описывается в стандарте, выглядит на первый взгляд немного запутанным, но все-таки сверимся с ним:
1. The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.
Итак, поведение не определено, если правый или левый операнд имеет отрицательное значение. Если операнд имеет знаковый тип, неотрицательное значение и вмещается в результирующий тип, то поведение будет нормальным.
Фрагмент N2
V517 The use of ‘if (A) <. >else if (A) <. >‘ pattern was detected. There is a probability of logical error presence. Check lines: 156, 160. cameracapturelevelcontrol.cpp 156
void CameraCaptureLevelHistogram::mousePressEvent(QMouseEvent* event) < if (event->button() != Qt::LeftButton) return; if (m_currentItem == Histogram) < m_histogramCue = true; return; >if (m_currentItem == None) return; QPoint pos = event->pos(); if (m_currentItem == BlackSlider) //Тут переменной m_offset присваиваются различные значения в зависимости от значения m_currentItem. Однако дублирование проверки на BlackSlider бессмысленно, и из тела условия можно увидеть, что в вычислении участвует переменная m_white. Заглянем в возможные значения для m_currentItem.
LevelControlItem m_currentItem; enum LevelControlItem < None = 0, BlackSlider, WhiteSlider, GammaSlider, ThresholdSlider, Histogram, NumItems >;
Оказывается, что возможно еще и значение WhiteSlider, на которое проверка как раз и не производится. Таким образом, вполне возможно, что какой-то из сценариев поведения был потерян из-за ошибки копипасты.
Фрагмент N3
V517 The use of 'if (A) <. >else if (A) <. >' pattern was detected. There is a probability of logical error presence. Check lines: 784, 867. tpalette.cpp 784
void TPalette::loadData(TIStream &is) < . std::string tagName; while (is.openChild(tagName)) < if (tagName == "version") < . >else if (tagName == "stylepages") < // . is.closeChild(); > > else if (tagName == "refImgPath") < . >else if (tagName == "animation") < . >else if (tagName == "stylepages") < // > . > >
Еще одна похожая ошибка. Здесь также у одинаковых условий разные тела, но сделать вывод о возможных вариантах значения tagName уже нельзя. Скорее всего, просто какой-то вариант был упущен, и в итоге мы имеем код, который никогда не будет выполнен.
Фрагмент N4
V547 Expression 'chancount == 2' is always true. psd.cpp 720
void TPSDReader::readImageData(. int chancount) < . if (depth == 1 && chancount == 1) < // else if (depth == 8 && chancount > 1) < . for (. ) < if (chancount >= 3) < . if (chancount == 4) . else . >else if (chancount . > . > else if (m_headerInfo.depth == 8 && chancount == 1)В эти проверки закралась небольшая логическая ошибка. В проверке под номером один chancount сравнивается с 1, а проверке номер 2 проверяется, что эта переменная меньше или равна 2. В итоге, к условию под номером три единственным возможным значением chancount является 2. К неправильной работе программы такая ошибка может и не приведет, но она усложняет чтение и понимание кода. Например, непонятно, зачем тогда else-ветка…
В целом рассматриваемая в этом фрагменте функция занимает чуть больше 300 строк кода и состоит из таких вот нагромождений условий и циклов.
Фрагмент N5
V614 Uninitialized variable 'precSegmentIndex' used. Consider checking the fifth actual argument of the 'insertBoxCorners' function. rasterselection.cpp 803
TStroke getIntersectedStroke(TStroke &stroke, TRectD bbox) < . int precSegmentIndex, currentSegmentIndex, startSegmentIndex, precChunkIndex = -1; . if (. ) < insertBoxCorners(bbox, points, outPoints, currentSegmentIndex, precSegmentIndex); . >> void insertBoxCorners(. int currentSegmentIndex, int precSegmentIndex)Возможно, здесь ошибка была допущена еще при инициализации переменных precSegmentIndex, currentSegmentIndex, startSegmentIndex, precChunkIndex. Разработчик мог рассчитывать, что инициализация последнего элемента -1 инициализирует тем же значением, что и другие переменные, объявленные в той же строке.
Фрагмент N6
V590 Consider inspecting the 's != "" && s == «color»' expression. The expression is excessive or contains a misprint. cleanupparameters.cpp 416
void CleanupParameters::loadData(TIStream &is, bool globalParams) < . std::string s = is.getTagAttribute("sharpness"); . if (. ) < . >else if (tagName == "lineProcessing") . if (s != "" && isDouble(s)) . if (s != "" && isDouble(s)) . if (s != "" && s == "color") // else if (tagName == "despeckling") < . >. >
Эта ошибка, даже скорее недочет, сама по себе приводит лишь к лишнему сравнению. Однако если мы взглянем на код в целом, станет ясно, что лишнее сравнение появилось в результате копипасты из предыдущих условий.
Такая лапша, занимающая десятки и более строк кода, вполне может хранить в себе еще какие-либо ошибки логики, и их поиск при таком форматировании может обернуться мучениями.
Фрагмент N7
V772 Calling a 'delete' operator for a void pointer will cause undefined behavior. pluginhost.cpp 1327
static void release_interface(void *interf)Тут само сообщение анализатора уже достаточно исчерпывающее: вызов оператора delete для указателя на тип void приводит к неопределенному поведению. Если была необходима универсальная функция для удаления интерфейсов, возможно её стоило сделать шаблонной.
template static void release_interface(T *interf)Фрагмент N8
V568 It's odd that 'sizeof()' operator evaluates the size of a pointer to a class, but not the size of the 'm_xshHandle' class object. tstageobjectcmd.cpp 455
class DVAPI TStageObjectParams < . >; class RemovePegbarNodeUndo final : public TUndo < . TXsheetHandle *m_xshHandle; public: int getSize() const override < return sizeof *this + sizeof(TStageObjectParams) + sizeof(m_xshHandle); >. >
Достаточно часто встречающаяся ошибка, которая может произойти как по невнимательности, так и по незнанию. Тут, скорее всего, было дело в невнимательности, поскольку в первом слагаемом this все-таки был разыменован. Если нужен размер объекта, то всегда нужно помнить, что указатель объекта нужно обязательно разыменовать. Иначе мы просто получаем размер самого указателя.
return sizeof *this + sizeof(TStageObjectParams) + sizeof(*m_xshHandle);
Фрагмент N9
V568 It's odd that 'sizeof()' operator evaluates the size of a pointer to a class, but not the size of the 'this' class object. shaderfx.cpp 107
struct RectF < GLfloat m_val[4]; . bool operator==(const RectF &rect) const < return (memcmp(m_val, rect.m_val, sizeof(this)) == 0); >>;
А тут, очевидно, забыли разыменовать указатель this. В итоге получаем не размер объекта, а размер указателя. Как результат, сравниваются только первые 4 или 8 байт (в зависимости от разрядности). Верный вариант кода:
return (memcmp(m_val, rect.m_val, sizeof(*this)) == 0);
Фрагмент N10
V554 Incorrect use of unique_ptr. The memory allocated with 'new []' will be cleaned using 'delete'. screensavermaker.cpp 29
void makeScreenSaver(TFilePath scrFn, TFilePath swfFn, std::string screenSaverName) < struct _stat results; . int swfSize = results.st_size; std::unique_ptrswf(new char[swfSize]); . >
Часто забывают, что от типа, которым инстанцируется unique_ptr, зависит будет использоваться delete или delete[]. В итоге, если инстанцировать указатель как в рассматриваемом фрагменте, при этом выделяя память через new[], может возникнуть неопределенное поведение, так как освобождение будет происходить через delete. Чтобы этого избежать, нужно добавить к типу указателя квадратные скобки: std::unique_ptr
. Фрагмент N11
V521 Such expressions using the ',' operator are dangerous. Make sure the expression 'm_to, m_from = it->first.getNumber()' is correct. flipbook.cpp 509
class LoadImagesPopup final : public FileBrowserPopup < . int m_from, m_to, . ; . >void LoadImagesPopup::onFilePathClicked(. ) < TLevel::Iterator it; . it = level->begin(); m_to, m_from = it->first.getNumber(); // end(); ++it) m_to = it->first.getNumber(); if (m_from == -2 && m_to == -2) m_from = m_to = 1; m_minFrame = m_from; m_maxFrame = m_to; . >
Возможно, программист ожидал, что можно присвоить одно значение нескольким переменным, просто выписав их через запятую. Однако оператор "," в С++ работает иным образом. В нем первый операнд выполняется, и результат «сбрасывается», далее вычисляется второй операнд. И, хотя переменная m_to инициализируется в последующем цикле, если что-то пойдет не так или кто-то неаккуратно произведет рефакторинг, возможно, что m_to так и не получит значения. И вообще, в любом случае этот код выглядит странно.
Фрагмент N12
V532 Consider inspecting the statement of '*pointer++' pattern. Probably meant: '(*pointer)++'. trop.cpp 140
template void doGammaCorrect(TRasterPT raster, double gamma) < Gamma_Lutlut(. ); int j; for (j = 0; j < raster->getLy(); j++) < T *pix = raster->pixels(j); T *endPix = pix + raster->getLx(); while (pix < endPix) < pix->r = lut.m_table[pix->r]; pix->b = lut.m_table[pix->b]; pix->g = lut.m_table[pix->g]; *pix++; // > >
Маленький недочет, который может дополнительно путать человека, читающего код. Инкремент, как и задумывалось, смещает указатель. Однако после этого происходит бессмысленное разыменование. Лучше просто написать pix++.
Фрагмент N13
V773 The function was exited without releasing the 'autoCloseUndo' pointer. A memory leak is possible. vectortapetool.cpp 575
void joinLineToLine(. ) < . UndoAutoclose *autoCloseUndo = 0; . autoCloseUndo = new UndoAutoclose(. ); . if (pos < 0) return; . TUndoManager::manager()->add(autoCloseUndo); >
Подобных предупреждений было больше 20. Зачастую где-то в конце функции производится освобождение памяти, но для более ранних return этот необходимый шаг оказывается пропущен. Так и здесь. В конце указатель передается TUndoManager::manager()->add(), который берет на себя удаление указателя, однако выше присутствует return для которого этот метод забыли позвать. Так что всегда стоит помнить о своих указателях при любом выходе из функции, а не просто вписывать удаление куда-то в конец блока или перед последним return.
Однако, если для сокращенной версии кода, эта ошибка выглядит очевидной, то в реальном более запутанном коде, отследить такую проблему может быть затруднительно. Тут и поможет никогда неустающий статический анализатор.
Фрагмент N14
V522 Dereferencing of the null pointer 'region' might take place. palettecmd.cpp 94
bool isStyleUsed(const TVectorImageP vi, int styleId) < . int regionCount = vi->getRegionCount(); for (i = 0; i < regionCount; i++) < TRegion *region = vi->getRegion(i); if (region || region->getStyle() != styleId) return true; > . >
Тут можно предположить, что разработчик перепутал правила short-circuit evaluation и подумал, что если первая проверка указателя вернет false, то далее разыменования такого нулевого указателя не произойдёт. Однако для оператора "||" все совсем наоборот.
Фрагмент N15
V561 It's probably better to assign value to 'ca' variable than to declare it anew. Previous declaration: xshcellmover.cpp, line 319. xshcellmover.cpp 323
V561 It's probably better to assign value to 'cb' variable than to declare it anew. Previous declaration: xshcellmover.cpp, line 320. xshcellmover.cpp 324xshcellmover.cpp 323
void redo() const override < int ca = m_cellsMover.getStartPos().x; int cb = m_cellsMover.getPos().x; . if (!m_cellsMover.getOrientation()->isVerticalTimeline()) < int ca = m_cellsMover.getStartPos().y; int cb = m_cellsMover.getPos().y; >. if (ca != cb) < . >. >
Возможно еще одна копипаста, но с не совсем обычной сутью ошибки. Обращение к x было заменено на y, но вот тип переменной в начале строки, из-за которого и происходит локальная передекларация, убрать забыли. В итоге, вместо смены ориентации позиций для исходных ca и cb, создаются новые локальные ca и cb, с которыми далее ничего не происходит. А вот внешние ca и cb продолжают свое существование со значениями для x.
Заключение N1
В процессе написания статьи мне стало интересно потыкать и попробовать что-нибудь сделать в этой программе. Может мне повезло, но странное поведение не заставило себя ждать: зависание, отображение моих манипуляций с планшетом после отвисания и странный квадрат после нажатия Ctrl+Z. К сожалению, повторить это поведение у меня не вышло.
Но на самом деле, несмотря на такое поведение и привитие привычки регулярно нажимать Ctrl+S, OpenToonz впечатляет своим масштабом и функционалом. Все-таки не зря им пользуются и крупные студии.
И мое художество как бонус:
Заключение N2
В случае OpenToonz очевидно, что пытаться исправить сразу все обнаруженные анализатором ошибки станет большой задачей, которая застопорит процесс разработки. Для таких случаев существует подход «Массового подавления», когда технический долг заносится в suppress-базу анализатора и дальнейшая работа с анализатором проводится уже на основе свежих срабатываний. Ну а если появляется время, то можно и поразбирать технический долг.
P.S. Напоминаю, что разработчики открытых проектов могут использовать бесплатный вариант лицензирования PVS-Studio.
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Victoria Khanieva. OpenToonz.
- Блог компании PVS-Studio
- Open source
- C++
- Компьютерная анимация
Руководство пользователя OpenToonz¶
Это руководство для OpenToonz, полнофункционального программного обеспечения для создания 2D-анимации с открытым исходным кодом.
This manual is an ongoing project, which aims to provide the first and most complete reference for OpenToonz features, and as such there will always be room for improvements and updates. Collaboration is welcome!
Чтобы внести свой вклад в документацию OpenToonz, пожалуйста, посетите хранилище документации OpenToonz.
- Установка OpenToonz
- Скачивание OpenToonz
- Установка на Windows
- Установка на OS X
- Установка на Linux
- Installing on FreeBSD
- Installing on DragonFly BSD
- Что такое FFmpeg?
- Установка FFmpeg для Windows
- Установка FFmpeg для Mac
- Установка FFmpeg для Linux
- v1.6
- Previous Versions of OpenToonz
- Рабочий процесс производства
- Традиционный рабочий процесс
- Безбумажный рабочий процесс
- Использование комнат
- Панели комнаты
- Настройка внешнего вида интерфейса
- Настройка Projectroot
- Настройка проектов
- Папки проекта по умолчанию
- Использование браузера проекта
- Настройки сцены и настройки проекта по умолчанию
- Выбор рабочей единицы
- Установка частоты кадров
- Определение настроек камеры
- Color Calibration using Look-up Tables
- Назначение памяти для операций отмены
- Оптимизация использования памяти
- Supported Scanners
- Scanning Modes
- Scanning Guidelines for Autocentering
- Defining Animation Levels to Scan
- Scanning Drawings
- Настройки очистки
- Проверка процесса очистки
- Очистка рисунков
- Рисование в OpenToonz
- Изменение размера холста
- Редактирование рисунка
- Техники анимации
- Применение кальки
- Использование Shift и Trace
- Использование Level Strip
- Объединение уровней анимации
- Обработка уровней
- Сохранение уровней
- Экспорт уровней
- Редактор палитры
- Применение Studio Palette
- Анимационные палитры
- Редактирование стилей
- Инструменты покраски
- Заливка областей
- Линии покраски
- Использование цветовой модели
- Использование Окна просмотра
- Использование браузера файлов
- Размещение уровней
- Изменение настроек уровня
- Панель инструментов Xsheet
- Работа со столбцами/слоями
- Работа с ячейками
- Глобальная работа с кадрами
- Использование Sub-Xsheet
- Создание звуковой дорожки
- Lip Syncing
- Использование заметок
- Сохранение и загрузка сцен
- Импорт и экспорт сцен
- Печать Xsheet
- Использование Схемы сцены
- Связывание объектов
- Анимация объектов
- Использование ключей в столбцах/слоях
- Работа в трехмерной среде
- Использование редактора функций
- Определение ключевых кадров
- Настройка сегментных интерполяций
- Управление несколькими функциональными кривыми одновременно
- Примеры выражений
- Использование Инструмента Скелет
- Построение скелета
- Создание базовых моделей
- Создание моделей с помощью крюков
- Анимирование моделей
- Использование обратной кинематики
- Применение Plastic Tool
- Построение полисетки используя Plastic Tool
- Модификация Plastic полисетки
- Изменение полисетки
- Построение скелета
- Использование нескольких скелетов на уровне полисетки
- Модификация скелета
- Анимирование Plastic элементов
- Определение жесткости для полисетки
- Отображение элементов и свойств
- Родительские Plastic уровни с применением вершин и крюков
- Представление данных Plastic в редакторе функций
- Используйте математические выражения в анимации Plastic
- Plastic и Sub-Xsheets
- Использование FX Schematic
- Изменение настроек эффектов
- Создание предустановок
- Создание Macro FX
- Список эффектов
- Defining Particle Images
- Defining Control Images
- Source
- Birth Parameters
- Environment
- Animation
- Colors
- Previewing the Animation
- Rendering the Animation
- Installing the Toonz Farm on Windows
- Installing the Toonz Farm on Macintosh
- Configuring the Toonz Farm
- Using the Toonz Farm
- Установка системы контроля версий
- Использование системы контроля версий
- File management
- Using the Script Console
- ToonzScript specifications
- Code examples
- Configuring Shortcuts
- Predefined Keyboard Shortcuts
- Layer Blending
Особая благодарность¶
Эта документация основана на Руководстве пользователя Toonz Harlequin 7.1, первоначально созданном Digital Video S.p.A., Рим, Италия.
© Copyright : This page is licensed under a CC-BY-NC 4.0 Int. License Revision a03b0c24 .
Built with Sphinx using a theme provided by Read the Docs.
Read the Docs v: latestVersions latest Downloads pdf html epub On Read the Docs Project Home Builds Free document hosting provided by Read the Docs.