Mesh: Cache loose vertices #105567

Merged
Hans Goudey merged 29 commits from HooglyBoogly/blender:mesh-loose-vert-cache into main 2023-04-22 13:46:23 +02:00
70 changed files with 8937 additions and 1761 deletions
Showing only changes of commit 90ecb6a590 - Show all commits

View File

@ -8,6 +8,7 @@
#include "loader.hpp"
#include <cstdint>
#include <fstream>
#include <unordered_map>

View File

@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"\"POT-Creation-Date: 2019-02-25 20:41:30\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2016-04-23 22:41+0300\n"
"Last-Translator: Yousef Harfoush <bat3a@msn.com>\n"
"Language-Team: Yousef Harfoush, Amine Moussaoui <bat3a@msn.com>\n"

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: \n"
"Last-Translator: Martin Tabačan <tabycz@gmail.com>\n"
"Language-Team: Taby <tabycz@gmail.com>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: \n"
"Last-Translator: Martin Reininger <martinreininger@gmx.net>\n"
"Language-Team: German translation team\n"

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Ainhize & Miriam <agoenaga006@ikasle.ehu.eus>\n"
"Language-Team: Euskara <agoenaga006@ikasle.ehu.eus>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2012-10-31 17:00-0800\n"
"Last-Translator: Amin Babaeipanah <translate@leomoon.com>\n"
"Language-Team: LeoMoon Studios <blender@leomoon.com>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2017-12-25 14:01+0100\n"
"Last-Translator: UMAR HARUNA ABDULLAHI <umarbrowser20@gmail.com>\n"
"Language-Team: BlenderNigeria <pyc0der@outlook.com>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2012-10-07 13:56+0300\n"
"Last-Translator: Barak Itkin <lightningismyname@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2015-03-03 16:21+0530\n"
"Last-Translator: Roshan Lal Gumasta <roshan@anisecrets.com>\n"
"Language-Team: Hindi <www.anisecrets.com>\n"

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2021-12-25 23:57-0800\n"
"Last-Translator: Adriel Tristanputra <ultimexport@gmail.com>\n"
"Language-Team: Indonesian <>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2022-01-21 16:08+0100\n"
"Last-Translator: MT\n"
"Language-Team: blend-it <https://developer.blender.org/T42765>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2016-10-13 03:05+0900\n"
"Last-Translator: \n"
"Language-Team: Japanese Translation Team (https://sites.google.com/site/blugjp/blender-translators)\n"
@ -1145,6 +1145,14 @@ msgstr ""
"フィルタリングとアセット管理全般で使用されます"
msgid "Asset Representation"
msgstr "アセットの情報"
msgid "Information about an entity that makes it possible for the asset system to deal with the entity as asset"
msgstr "アセットシステムにてその要素がアセットとして処理できるようにする、要素についての情報"
msgid "Asset Tag"
msgstr "アセットタグ"
@ -19400,7 +19408,7 @@ msgstr "伝播ステップ"
msgid "Distance where boundary edge automasking is going to protect vertices from the fully masked edge"
msgstr "完全にマスクされた辺の頂点を守るため、境界の辺の自動マスキングが行われる距離"
msgstr "境界の辺の自動マスクを行う場合に、完全にマスク済みの辺の頂点を保護するための距離"
msgid "Blur Steps"
@ -28896,7 +28904,7 @@ msgstr "端の処理"
msgid "How the image is extrapolated past its original bounds"
msgstr "画像の範囲外の外挿方法"
msgstr "画像の範囲外の処理方法"
msgctxt "Image"
@ -33975,6 +33983,10 @@ msgid "Active Point"
msgstr "アクティブポイント"
msgid "Active point of masking layer"
msgstr "マスキングレイヤーのアクティブポイント"
msgid "Grease Pencil Color"
msgstr "グリースペンシルカラー"
@ -45182,6 +45194,10 @@ msgid "Is Face Planar"
msgstr "平面判定"
msgid "Retrieve whether all triangles in a face are on the same plane, i.e. whether they have the same normal"
msgstr "一つの面内の全三角形が同一平面上にあるかどうか(同じ法線かどうか)を取得します"
msgid "Face Neighbors"
msgstr "面情報"
@ -48863,7 +48879,7 @@ msgstr "キーフレームをコピー"
msgid "Copy selected keyframes to the copy/paste buffer"
msgstr "キーフレームをコピー・ペーストバッファーにコピーします"
msgstr "キーフレームをコピー/貼り付けバッファーにコピーします"
msgctxt "Operator"
@ -54460,6 +54476,16 @@ msgid "-Z Axis"
msgstr "-Z軸"
msgid "Prioritize Active Color"
msgstr "アクティブカラーを優先"
msgid "Make sure active color will be exported first. Could be important since some other software can discard other color attributes besides the first one"
msgstr ""
"アクティブカラーが最初にエクスポートされるようにします\n"
"(一部のソフトウェアでは最初のカラー属性以外は無視されるため)"
msgid "Secondary Bone Axis"
msgstr "セカンダリボーン軸"
@ -57019,7 +57045,7 @@ msgstr "シーケンスを補間"
msgid "Generate 'in-betweens' to smoothly interpolate between Grease Pencil frames"
msgstr "複数の「インビトウィーン(中割」を生成し、グリースペンシルフレーム間をスムーズに補間します"
msgstr "複数の「中割」を生成し、グリースペンシルフレーム間をスムーズに補間します"
msgctxt "GPencil"
@ -60572,7 +60598,7 @@ msgstr "フェザーウェイトのクリア"
msgid "Reset the feather weight to zero"
msgstr "フェザーウェイトを0にリセットします"
msgstr "フェザーウェイトをにリセットします"
msgctxt "Operator"
@ -60580,11 +60606,19 @@ msgid "Clear Restrict View"
msgstr "ビューの制限を解除"
msgid "Reveal temporarily hidden mask layers"
msgstr "一時的に非表示にしたマスクレイヤーを再表示します"
msgctxt "Operator"
msgid "Set Restrict View"
msgstr "ビューの制限を設定"
msgid "Temporarily hide mask layers"
msgstr "一時的にマスクレイヤーを非表示にします"
msgctxt "Operator"
msgid "Move Layer"
msgstr "レイヤー移動"
@ -66196,7 +66230,7 @@ msgstr "オブジェクトを隠す"
msgid "Temporarily hide objects from the viewport"
msgstr "一時的にビューポートからオブジェクトを隠します"
msgstr "一時的にビューポートでオブジェクトを非表示にします"
msgid "Hide unselected rather than selected objects"
@ -71032,7 +71066,7 @@ msgstr "同じ方向を維持しつつ、希望の回転にするためクォー
msgctxt "Operator"
msgid "Relax Pose to Breakdown"
msgstr "中割方向にポーズをリラックス"
msgstr "中割にポーズをリラックス"
msgid "Make the current pose more similar to its breakdown pose"
@ -87876,6 +87910,14 @@ msgid "Mini Axes Type"
msgstr "ミニ軸のタイプ"
msgid "Show small rotating 3D axes in the top right corner of the 3D viewport"
msgstr "3Dビューポートの右上の隅に、回転する小さな3D座標軸を表示します"
msgid "Simple Axes"
msgstr "シンプルな軸"
msgid "Interactive Navigation"
msgstr "インタラクティブナビゲーション"
@ -98935,35 +98977,35 @@ msgstr "選択中のキーフレーム境界の色"
msgid "Breakdown Keyframe"
msgstr "中割キーフレーム"
msgstr "ブレイクダウンキーフレーム"
msgid "Color of breakdown keyframe"
msgstr "中割タグのキーフレームの色"
msgstr "ブレイクダウンタグのキーフレームの色"
msgid "Breakdown Keyframe Selected"
msgstr "選択中の中割キーフレーム"
msgstr "選択中のブレイクダウンキーフレーム"
msgid "Color of selected breakdown keyframe"
msgstr "選択中の中割キーフレームの色"
msgstr "選択中のブレイクダウンキーフレームの色"
msgid "Extreme Keyframe"
msgstr "極端キーフレーム"
msgstr "エクストリームキーフレーム"
msgid "Color of extreme keyframe"
msgstr "極端タグのキーフレームの色"
msgstr "エクストリームタグのキーフレームの色"
msgid "Extreme Keyframe Selected"
msgstr "選択中の極端キーフレーム"
msgstr "選択中のエクストリームキーフレーム"
msgid "Color of selected extreme keyframe"
msgstr "選択中の極端キーフレームの色"
msgstr "選択中のエクストリームキーフレームの色"
msgid "Jitter Keyframe"
@ -111110,7 +111152,7 @@ msgstr "IDデータ"
msgctxt "Operator"
msgid "Paste Data-Blocks"
msgstr "データブロックをペースト"
msgstr "データブロックを貼り付け"
msgid "All View Layers"
@ -112394,6 +112436,10 @@ msgid "Playback Frame Rate (FPS)"
msgstr "再生フレームレートFPS"
msgid "3D Viewport Axes"
msgstr "3Dビューポートの軸"
msgid "Smooth Wires"
msgstr "スムーズワイヤ"
@ -117229,7 +117275,7 @@ msgstr "カスタム補間カーブがありません"
msgid "Expected current frame to be a breakdown"
msgstr "現在のフレームを中割フレームにしてください"
msgstr "現在のフレームをブレイクダウンにしてください"
msgid "Nothing to merge"
@ -120733,7 +120779,7 @@ msgstr "アクション「%s」は保存されません。残すならフェイ
msgid "No keyframes copied to keyframes copy/paste buffer"
msgstr "コピー・ペーストバッファーにコピーするキーフレームがありません"
msgstr "コピー/貼り付けバッファーにコピーするキーフレームがありません"
msgid "Keyframe pasting is not available for mask mode"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Tamar Mebonia <tammebonia@gmail.com>, 2023\n"
"Language-Team: LANGUAGE <LL@li.org>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2020-01-04 05:04+0900\n"
"Last-Translator: Geuntak Jeong <beroberos@gmail.com>\n"
"Language-Team: Korean (http://www.transifex.com/lxlalexlxl/blender/language/ko/)\n"

View File

@ -1,10 +1,10 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"(b'0000000000000000000000000000000000000000')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2013-11-05 13:47+0600\n"
"Last-Translator: Chyngyz Dzhumaliev <kyrgyzl10n@gmail.com>\n"
"Language-Team: Kirghiz <kyrgyzl10n@gmail.com>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2021-12-05 20:05+0100\n"
"Language: nl\n"
"MIME-Version: 1.0\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2017-08-26 11:13+0200\n"
"Last-Translator: Mikołaj Juda <mikolaj.juda@gmail.com>\n"
"Language: pl\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: Ivan Paulos Tomé <ivan.paulos.tome@yandex.com>\n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2017-09-08 21:24-0300\n"
"Last-Translator: Ivan Paulos Tomé <greylica@gmail.com>\n"
"Language-Team: Ivan Paulos Tomé, Inês Almeida, João Brandão (ULISBOA), Paulo Martins <ivan.paulos.tome@yandex.com>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: Leandro Paganelli <leandrobp@fastmail.com>\n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2022-03-21 19:03-0300\n"
"Last-Translator: Leandro Paganelli <leandrobp@fastmail.com>\n"
"Language-Team: Leandro Paganelli, Ivan Paulos Tomé, Dalai Felinto, Bruno Gonçalves Pirajá, Samuel Arataca, Daniel Tavares, Moraes Junior <ivan.paulos.tome@yandex.com>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2018-01-03 14:47+0000\n"
"Last-Translator: Lockal <lockalsash@gmail.com>, 2023\n"
"Language-Team: Russian (https://www.transifex.com/translateblender/teams/82039/ru/)\n"

View File

@ -1,10 +1,10 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"PO-Revision-Date: 2023-03-08 07:56+0100\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2023-03-23 08:09+0100\n"
"Last-Translator: Jozef Matta <jozef.m923@gmail.com>\n"
"Language-Team: Jozef Matta\n"
"Language: sk_SK\n"
@ -1112,6 +1112,10 @@ msgid "Copyright"
msgstr "Autorské práva"
msgid "Copyright notice for this asset. An empty copyright notice does not necessarily indicate that this is copyright-free. Contact the author if any clarification is needed"
msgstr "Upozornenie o autorských právach na toto aktívum. Prázdne upozornenie o autorských právach nemusí nevyhnutne znamenať, že je bez autorských práv. Ak je potrebné akékoľvek objasnenie, obráťte sa na autora"
msgid "Description"
msgstr "Popis"
@ -1120,6 +1124,14 @@ msgid "A description of the asset to be displayed for the user"
msgstr "Popis aktív na zobrazenie pre užívateľa"
msgid "License"
msgstr "Licencia"
msgid "The type of license this asset is distributed under. An empty license name does not necessarily indicate that this is free of licensing terms. Contact the author if any clarification is needed"
msgstr "Typ licencie, pod ktorou je toto aktívum distribuované. Prázdny názov licencie nemusí nutne znamenať, že je bez licenčných podmienok. Ak je potrebné akékoľvek objasnenie, obráťte sa na autora"
msgid "Tags"
msgstr "Príznaky"
@ -1128,6 +1140,14 @@ msgid "Custom tags (name tokens) for the asset, used for filtering and general a
msgstr "Vlastné príznaky (tokeny názvov) pre aktíva, ktoré sa používajú na filtrovanie a všeobecnú správu aktív"
msgid "Asset Representation"
msgstr "Zastúpenie aktív"
msgid "Information about an entity that makes it possible for the asset system to deal with the entity as asset"
msgstr "Informácie o entite, ktoré umožňujú systému aktív pracovať s entitou ako s aktívom"
msgid "Asset Tag"
msgstr "Príznak aktív"
@ -13703,6 +13723,11 @@ msgid "Minimum number of particles per cell (ensures that each cell has at least
msgstr "Minimálny počet častíc na bunku (zabezpečuje, aby každá bunka obsahovala aspoň toto množstvo častíc)"
msgctxt "Amount"
msgid "Number"
msgstr "Počet"
msgid "Particle number factor (higher value results in more particles)"
msgstr "Faktor počtu častíc (vyššia hodnota vedie k početnejším časticiam)"
@ -19544,6 +19569,61 @@ msgid "Editable falloff curve"
msgstr "Upravovateľné dopady krivky"
msgctxt "Curves"
msgid "Curve Preset"
msgstr "Predvoľba krivky"
msgctxt "Curves"
msgid "Custom"
msgstr "Vlastná"
msgctxt "Curves"
msgid "Smooth"
msgstr "Vyhladená"
msgctxt "Curves"
msgid "Smoother"
msgstr "Vyhladenejšia"
msgctxt "Curves"
msgid "Sphere"
msgstr "Guľa"
msgctxt "Curves"
msgid "Root"
msgstr "Koreňová"
msgctxt "Curves"
msgid "Sharp"
msgstr "Ostrá"
msgctxt "Curves"
msgid "Linear"
msgstr "Lineárna"
msgctxt "Curves"
msgid "Sharper"
msgstr "Ostrejšia"
msgctxt "Curves"
msgid "Inverse Square"
msgstr "Inverzný štvorec"
msgctxt "Curves"
msgid "Constant"
msgstr "Konštantná"
msgid "Curves Sculpt Settings"
msgstr "Nastavenia tvarovania kriviek"
@ -20988,10 +21068,25 @@ msgid "Name of the Alembic attribute used for generating motion blur data"
msgstr "Názov atribútu Alembic, ktorý sa používa na generovanie údajov o rozostrení pohybom"
msgctxt "Unit"
msgid "Velocity Unit"
msgstr "Jednotka rýchlosti"
msgid "Define how the velocity vectors are interpreted with regard to time, 'frame' means the delta time is 1 frame, 'second' means the delta time is 1 / FPS"
msgstr "Definuje, ako sa majú vektory rýchlosti interpretovať s ohľadom na čas, „snímka“ znamená, že delta čas je 1 snímka, „druhé“ znamená, že delta čas je 1 / sním/s"
msgctxt "Unit"
msgid "Second"
msgstr "Sekúnd"
msgctxt "Unit"
msgid "Frame"
msgstr "Snímka"
msgid "Camera data-block for storing camera settings"
msgstr "Blok údajov kamery na uloženie nastavení kamery"
@ -28014,6 +28109,11 @@ msgid "Text file on disk is different than the one in memory"
msgstr "Textový súbor na disku je iný ako ten v pamäti"
msgctxt "Text"
msgid "Lines"
msgstr "Riadky"
msgid "Lines of text"
msgstr "Riadky textu"
@ -33513,6 +33613,10 @@ msgid "Active Point"
msgstr "Aktívny bod"
msgid "Active point of masking layer"
msgstr "Aktívny bod vrstvy maskovania"
msgid "Grease Pencil Color"
msgstr "Farba pastelky"
@ -34050,6 +34154,11 @@ msgid "Write"
msgstr "Zápis"
msgctxt "NodeTree"
msgid "Constant"
msgstr "Konštantný"
msgid "Instances"
msgstr "Inštancie"
@ -44664,6 +44773,10 @@ msgid "Is Face Planar"
msgstr "Je plôška rovinná"
msgid "Retrieve whether all triangles in a face are on the same plane, i.e. whether they have the same normal"
msgstr "Zisťuje, či sú všetky trojuholníky na plôške v tej istej rovine, t. j. či majú rovnaký normál"
msgid "Face Neighbors"
msgstr "Susedné plôšky"
@ -53867,6 +53980,14 @@ msgid "-Z Axis"
msgstr "Os -Z"
msgid "Prioritize Active Color"
msgstr "Uprednostniť aktívne farby"
msgid "Make sure active color will be exported first. Could be important since some other software can discard other color attributes besides the first one"
msgstr "Najprv sa uistite, že sa bude exportovať aktívna farba. Mohlo by to byť dôležité, pretože niektoré iné programy môžu okrem prvého vyradiť aj iné atribúty farby"
msgid "Secondary Bone Axis"
msgstr "Sekundárne osi kosti"
@ -59919,9 +60040,17 @@ msgid "Clear Restrict View"
msgstr "Zmazať obmedzené zobrazenie"
msgid "Reveal temporarily hidden mask layers"
msgstr "Odhalí dočasne skryté vrstvy masiek"
msgctxt "Operator"
msgid "Set Restrict View"
msgstr "Nastaviť obmedzenie zobrazenia"
msgstr "Nastaviť obmedzené zobrazenie"
msgid "Temporarily hide mask layers"
msgstr "Dočasne skryje vrstvy masky"
msgctxt "Operator"
@ -80880,7 +81009,7 @@ msgstr "Priečinok textúr"
msgid "Path to the directory where imported textures will be copied"
msgstr "Cesta k priečinku, do ktorého sa budú kopírovať importované textúry "
msgstr "Cesta k priečinku, do ktorého sa budú kopírovať importované textúry"
msgid "Import Textures"
@ -87040,6 +87169,14 @@ msgid "Mini Axes Type"
msgstr "Typ mini osí"
msgid "Show small rotating 3D axes in the top right corner of the 3D viewport"
msgstr "Zobrazí malé rotujúce 3D osi v pravom hornom rohu 3D záberu"
msgid "Simple Axes"
msgstr "Jednoduché osi"
msgid "Interactive Navigation"
msgstr "Interaktívna navigácia"
@ -90045,10 +90182,25 @@ msgid "Additional subdivision along the curves"
msgstr "Dodatočné delenie pozdĺž kriviek"
msgctxt "Curves"
msgid "Curves Shape Type"
msgstr "Typ tvaru krivky"
msgid "Curves shape type"
msgstr "Typ tvaru krivky"
msgctxt "Curves"
msgid "Strand"
msgstr "Vlákno"
msgctxt "Curves"
msgid "Strip"
msgstr "Pás"
msgid "Multiple Engines"
msgstr "Viacnásobný mechanizmus"
@ -96907,7 +97059,7 @@ msgstr "Zobraziť kresbu textúry UV"
msgid "Display overlay of texture paint UV layer"
msgstr "Zobrazí prekrytie kresbou textúry UV vrstvy."
msgstr "Zobrazí prekrytie kresbou textúry UV vrstvy"
msgid "Tile Grid Shape"
@ -106332,6 +106484,10 @@ msgid "Previews clear process failed for file '%s'!"
msgstr "Proces vyčistenia náhľadov zlyhal pre súbor '%s'!"
msgid "No active camera in the scene"
msgstr "Na scéne nie je žiadna aktívna kamera"
msgid "Unexpected modifier type: "
msgstr "Neočakávaný typ modifikátora: "
@ -111408,6 +111564,10 @@ msgid "Playback Frame Rate (FPS)"
msgstr "Frekvencia prehrávania (sním/s)"
msgid "3D Viewport Axes"
msgstr "Osi 3D záberu"
msgid "Smooth Wires"
msgstr "Vyhladiť drôty"
@ -116396,6 +116556,10 @@ msgid "Error evaluating number, see Info editor for details"
msgstr "Chyba pri vyhodnocovaní čísla, ďalšie informácie nájdete v editore informácií"
msgid "Press a key"
msgstr "Stlačiť klávesu"
msgid "Missing Panel: %s"
msgstr "Chýbajúci panel: %s"
@ -123682,6 +123846,31 @@ msgid "UNDEFINED"
msgstr "NEDEFINOVANÉ"
msgctxt "NodeTree"
msgid "Functions"
msgstr "Funkcie"
msgctxt "NodeTree"
msgid "Comparison"
msgstr "Porovnanie"
msgctxt "NodeTree"
msgid "Rounding"
msgstr "Zaokrúhlenie"
msgctxt "NodeTree"
msgid "Trigonometric"
msgstr "Trigonometrický"
msgctxt "NodeTree"
msgid "Conversion"
msgstr "Konverzia"
msgid "Same input/output direction of sockets"
msgstr "Rovnaký smer vstupu/výstupu zásuviek"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2012-09-07 22:32+0100\n"
"Last-Translator: Nikola Radovanovic <cobisimo@gmail.com>\n"
"Language-Team: Nikola Radovanovic\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2012-09-07 22:32+0100\n"
"Last-Translator: Nikola Radovanovic <cobisimo@gmail.com>\n"
"Language-Team: Nikola Radovanovic\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: \n"
"Last-Translator: Arvid Rudling <arvid.r@gmail.com>\n"
"Language-Team: \n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2019-12-08 17:40+0700\n"
"Last-Translator: gongpha <gongpha@gmail.com>\n"
"Language-Team: Thai Translation Team <gongpha@gmail.com>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2023-02-05 22:00+0300\n"
"Last-Translator: Emir SARI <emir_sari@îcloud.com>\n"
"Language-Team: Turkish <>\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2021-03-01 19:15+0000\n"
"Last-Translator: lxlalexlxl <lxlalexlxl@ukr.net>\n"
"Language-Team: Ukrainian (Ukraine) (http://www.transifex.com/lxlalexlxl/blender/language/uk_UA/)\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2022-08-19 12:33+0700\n"
"Last-Translator: HỒ NHỰT CHÂU <su_huynh@yahoo.com>\n"
"Language-Team: Tỉnh An Giang, Đình Bình Phú\n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: \n"
"Last-Translator: DeathBlood\n"
"Language-Team: \n"

View File

@ -1,9 +1,9 @@
msgid ""
msgstr ""
"Project-Id-Version: Blender 3.5.0 Beta (b'3962d9b931f1')\n"
"Project-Id-Version: Blender 3.5.0 Release Candidate (b'14efe7000449')\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-20 13:37:56\n"
"POT-Creation-Date: 2023-03-27 16:38:19\n"
"PO-Revision-Date: 2023-01-28 11:09+0800\n"
"Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"
"Language-Team: Chinese (Traditional) <http://weblate.slat.org/projects/blender/blender/zh_Hant/>\n"

View File

@ -76,6 +76,8 @@ def keyconfig_update(keyconfig_data, keyconfig_version):
elif item_modal == 'ROTATE':
km_items.append(('TRACKBALL', item_event, None))
# The modal key for "Rotate Normals" also didn't exist until then.
km_items.append(('ROTATE_NORMALS', {"type": 'N', "value": 'PRESS'}, None))
break
return keyconfig_data

View File

@ -5793,6 +5793,7 @@ def km_transform_modal_map(_params):
("ROTATE", {"type": 'R', "value": 'PRESS'}, None),
("TRACKBALL", {"type": 'R', "value": 'PRESS'}, None),
("RESIZE", {"type": 'S', "value": 'PRESS'}, None),
("ROTATE_NORMALS", {"type": 'N', "value": 'PRESS'}, None),
("SNAP_TOGGLE", {"type": 'TAB', "value": 'PRESS', "shift": True}, None),
("SNAP_INV_ON", {"type": 'LEFT_CTRL', "value": 'PRESS', "any": True}, None),
("SNAP_INV_OFF", {"type": 'LEFT_CTRL', "value": 'RELEASE', "any": True}, None),

View File

@ -3975,6 +3975,7 @@ def km_transform_modal_map(_params):
("ROTATE", {"type": 'R', "value": 'PRESS'}, None),
("TRACKBALL", {"type": 'R', "value": 'PRESS'}, None),
("RESIZE", {"type": 'S', "value": 'PRESS'}, None),
("ROTATE_NORMALS", {"type": 'N', "value": 'PRESS'}, None),
("SNAP_TOGGLE", {"type": 'TAB', "value": 'PRESS', "shift": True}, None),
("SNAP_INV_ON", {"type": 'LEFT_CTRL', "value": 'PRESS', "any": True}, None),
("SNAP_INV_OFF", {"type": 'LEFT_CTRL', "value": 'RELEASE', "any": True}, None),

View File

@ -170,6 +170,10 @@ class QuickFur(ObjectModeOperator, Operator):
curves_object.modifiers.move(0, len(curves_object.modifiers) - 1)
# Workaround for #105965: Rebuild UI data of modifier input properties.
for modifier in curves_object.modifiers:
modifier.node_group = modifier.node_group
return {'FINISHED'}

View File

@ -18,7 +18,7 @@ typedef enum MeshForeachFlag {
} MeshForeachFlag;
void BKE_mesh_foreach_mapped_vert(
struct Mesh *mesh,
const struct Mesh *mesh,
void (*func)(void *userData, int index, const float co[3], const float no[3]),
void *userData,
MeshForeachFlag flag);

View File

@ -159,14 +159,14 @@ void BKE_mesh_remap_calc_source_cddata_masks_from_map_modes(
float BKE_mesh_remap_calc_difference_from_mesh(const struct SpaceTransform *space_transform,
const float (*vert_positions_dst)[3],
int numverts_dst,
struct Mesh *me_src);
const struct Mesh *me_src);
/**
* Set r_space_transform so that best bbox of dst matches best bbox of src.
*/
void BKE_mesh_remap_find_best_match_from_mesh(const float (*vert_positions_dst)[3],
int numverts_dst,
struct Mesh *me_src,
const struct Mesh *me_src,
struct SpaceTransform *r_space_transform);
void BKE_mesh_remap_calc_verts_from_mesh(int mode,
@ -176,7 +176,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(int mode,
const float (*vert_positions_dst)[3],
int numverts_dst,
bool dirty_nors_dst,
struct Mesh *me_src,
const struct Mesh *me_src,
struct Mesh *me_dst,
MeshPairRemap *r_map);
@ -189,7 +189,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(int mode,
const struct MEdge *edges_dst,
int numedges_dst,
bool dirty_nors_dst,
struct Mesh *me_src,
const struct Mesh *me_src,
struct Mesh *me_dst,
MeshPairRemap *r_map);
@ -211,7 +211,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(int mode,
bool use_split_nors_dst,
float split_angle_dst,
bool dirty_nors_dst,
struct Mesh *me_src,
const struct Mesh *me_src,
MeshRemapIslandsCalc gen_islands_src,
float islands_precision_src,
struct MeshPairRemap *r_map);
@ -226,7 +226,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(int mode,
const int *corner_verts,
const struct MPoly *polys_dst,
int numpolys_dst,
struct Mesh *me_src,
const struct Mesh *me_src,
struct MeshPairRemap *r_map);
#ifdef __cplusplus

View File

@ -218,6 +218,16 @@ static CurvesInfo get_curves_info(const CurvesGeometry &main, const CurvesGeomet
return {main, profile, main.cyclic(), profile.cyclic()};
}
static bool offsets_contain_single_point(const OffsetIndices<int> offsets)
{
for (const int64_t i : offsets.index_range()) {
if (offsets[i].size() == 1) {
return true;
}
}
return false;
}
struct ResultOffsets {
/** The total number of curve combinations. */
int total;
@ -231,68 +241,90 @@ struct ResultOffsets {
/* The indices of the main and profile curves that form each combination. */
Array<int> main_indices;
Array<int> profile_indices;
/** Whether any curve in the profile or curve input has only a single evaluated point. */
bool any_single_point_curve;
};
static ResultOffsets calculate_result_offsets(const CurvesInfo &info, const bool fill_caps)
{
ResultOffsets result;
result.total = info.main.curves_num() * info.profile.curves_num();
result.vert.reinitialize(result.total + 1);
result.edge.reinitialize(result.total + 1);
result.loop.reinitialize(result.total + 1);
result.poly.reinitialize(result.total + 1);
result.main_indices.reinitialize(result.total);
result.profile_indices.reinitialize(result.total);
const OffsetIndices<int> main_offsets = info.main.evaluated_points_by_curve();
const OffsetIndices<int> profile_offsets = info.profile.evaluated_points_by_curve();
int mesh_index = 0;
int vert_offset = 0;
int edge_offset = 0;
int loop_offset = 0;
int poly_offset = 0;
for (const int i_main : info.main.curves_range()) {
const bool main_cyclic = info.main_cyclic[i_main];
const int main_point_num = main_offsets[i_main].size();
const int main_segment_num = curves::segments_num(main_point_num, main_cyclic);
for (const int i_profile : info.profile.curves_range()) {
result.vert[mesh_index] = vert_offset;
result.edge[mesh_index] = edge_offset;
result.loop[mesh_index] = loop_offset;
result.poly[mesh_index] = poly_offset;
threading::parallel_invoke(
result.total > 1024,
[&]() {
result.vert.reinitialize(result.total + 1);
result.edge.reinitialize(result.total + 1);
result.loop.reinitialize(result.total + 1);
result.poly.reinitialize(result.total + 1);
result.main_indices[mesh_index] = i_main;
result.profile_indices[mesh_index] = i_profile;
int mesh_index = 0;
int vert_offset = 0;
int edge_offset = 0;
int loop_offset = 0;
int poly_offset = 0;
for (const int i_main : main_offsets.index_range()) {
const bool main_cyclic = info.main_cyclic[i_main];
const int main_point_num = main_offsets[i_main].size();
const int main_segment_num = curves::segments_num(main_point_num, main_cyclic);
for (const int i_profile : profile_offsets.index_range()) {
result.vert[mesh_index] = vert_offset;
result.edge[mesh_index] = edge_offset;
result.loop[mesh_index] = loop_offset;
result.poly[mesh_index] = poly_offset;
const bool profile_cyclic = info.profile_cyclic[i_profile];
const int profile_point_num = profile_offsets[i_profile].size();
const int profile_segment_num = curves::segments_num(profile_point_num, profile_cyclic);
const bool profile_cyclic = info.profile_cyclic[i_profile];
const int profile_point_num = profile_offsets[i_profile].size();
const int profile_segment_num = curves::segments_num(profile_point_num,
profile_cyclic);
const bool has_caps = fill_caps && !main_cyclic && profile_cyclic && profile_point_num > 2;
const int tube_face_num = main_segment_num * profile_segment_num;
const bool has_caps = fill_caps && !main_cyclic && profile_cyclic &&
profile_point_num > 2;
const int tube_face_num = main_segment_num * profile_segment_num;
vert_offset += main_point_num * profile_point_num;
vert_offset += main_point_num * profile_point_num;
/* Add the ring edges, with one ring for every curve vertex, and the edge loops
* that run along the length of the curve, starting on the first profile. */
edge_offset += main_point_num * profile_segment_num + main_segment_num * profile_point_num;
/* Add the ring edges, with one ring for every curve vertex, and the edge loops
* that run along the length of the curve, starting on the first profile. */
edge_offset += main_point_num * profile_segment_num +
main_segment_num * profile_point_num;
/* Add two cap N-gons for every ending. */
poly_offset += tube_face_num + (has_caps ? 2 : 0);
/* Add two cap N-gons for every ending. */
poly_offset += tube_face_num + (has_caps ? 2 : 0);
/* All faces on the tube are quads, and all cap faces are N-gons with an edge for each
* profile edge. */
loop_offset += tube_face_num * 4 + (has_caps ? profile_segment_num * 2 : 0);
/* All faces on the tube are quads, and all cap faces are N-gons with an edge for each
* profile edge. */
loop_offset += tube_face_num * 4 + (has_caps ? profile_segment_num * 2 : 0);
mesh_index++;
}
}
mesh_index++;
}
}
result.vert.last() = vert_offset;
result.edge.last() = edge_offset;
result.loop.last() = loop_offset;
result.poly.last() = poly_offset;
result.vert.last() = vert_offset;
result.edge.last() = edge_offset;
result.loop.last() = loop_offset;
result.poly.last() = poly_offset;
},
[&]() {
result.main_indices.reinitialize(result.total);
result.profile_indices.reinitialize(result.total);
int mesh_index = 0;
for (const int i_main : main_offsets.index_range()) {
for (const int i_profile : profile_offsets.index_range()) {
result.main_indices[mesh_index] = i_main;
result.profile_indices[mesh_index] = i_profile;
mesh_index++;
}
}
},
[&]() {
result.any_single_point_curve = offsets_contain_single_point(main_offsets) ||
offsets_contain_single_point(profile_offsets);
});
return result;
}
@ -739,6 +771,11 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
positions.slice(info.vert_range));
});
if (!offsets.any_single_point_curve) {
/* If there are no single point curves, every curve combination will always have faces. */
mesh->loose_edges_tag_none();
}
SpanAttributeWriter<bool> sharp_edges;
write_sharp_bezier_edges(curves_info, offsets, mesh_attributes, sharp_edges);
if (fill_caps) {

View File

@ -1037,6 +1037,15 @@ void CurvesGeometry::calculate_bezier_auto_handles()
void CurvesGeometry::translate(const float3 &translation)
{
if (math::is_zero(translation)) {
return;
}
std::optional<Bounds<float3>> bounds;
if (this->runtime->bounds_cache.is_cached()) {
bounds = this->runtime->bounds_cache.data();
}
translate_positions(this->positions_for_write(), translation);
if (!this->handle_positions_left().is_empty()) {
translate_positions(this->handle_positions_left_for_write(), translation);
@ -1045,6 +1054,12 @@ void CurvesGeometry::translate(const float3 &translation)
translate_positions(this->handle_positions_right_for_write(), translation);
}
this->tag_positions_changed();
if (bounds) {
bounds->min += translation;
bounds->max += translation;
this->runtime->bounds_cache.ensure([&](blender::Bounds<float3> &r_data) { r_data = *bounds; });
}
}
void CurvesGeometry::transform(const float4x4 &matrix)

View File

@ -256,7 +256,7 @@ int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type)
* is set).
*/
static void data_transfer_mesh_attributes_transfer_active_color_string(
Mesh *mesh_dst, Mesh *mesh_src, const eAttrDomainMask mask_domain, const int data_type)
Mesh *mesh_dst, const Mesh *mesh_src, const eAttrDomainMask mask_domain, const int data_type)
{
if (mesh_dst->active_color_attribute) {
return;
@ -264,14 +264,17 @@ static void data_transfer_mesh_attributes_transfer_active_color_string(
const char *active_color_src = BKE_id_attributes_active_color_name(&mesh_src->id);
if ((data_type == CD_PROP_COLOR) &&
!BKE_id_attribute_search(
&mesh_src->id, active_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR)) {
if ((data_type == CD_PROP_COLOR) && !BKE_id_attribute_search(&const_cast<ID &>(mesh_src->id),
active_color_src,
CD_MASK_PROP_COLOR,
ATTR_DOMAIN_MASK_COLOR)) {
return;
}
else if ((data_type == CD_PROP_BYTE_COLOR) &&
!BKE_id_attribute_search(
&mesh_src->id, active_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR)) {
!BKE_id_attribute_search(&const_cast<ID &>(mesh_src->id),
active_color_src,
CD_MASK_PROP_BYTE_COLOR,
ATTR_DOMAIN_MASK_COLOR)) {
return;
}
@ -300,7 +303,7 @@ static void data_transfer_mesh_attributes_transfer_active_color_string(
* is set).
*/
static void data_transfer_mesh_attributes_transfer_default_color_string(
Mesh *mesh_dst, Mesh *mesh_src, const eAttrDomainMask mask_domain, const int data_type)
Mesh *mesh_dst, const Mesh *mesh_src, const eAttrDomainMask mask_domain, const int data_type)
{
if (mesh_dst->default_color_attribute) {
return;
@ -308,12 +311,14 @@ static void data_transfer_mesh_attributes_transfer_default_color_string(
const char *default_color_src = BKE_id_attributes_default_color_name(&mesh_src->id);
if ((data_type == CD_PROP_COLOR) &&
!BKE_id_attribute_search(
&mesh_src->id, default_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR)) {
if ((data_type == CD_PROP_COLOR) && !BKE_id_attribute_search(&const_cast<ID &>(mesh_src->id),
default_color_src,
CD_MASK_PROP_COLOR,
ATTR_DOMAIN_MASK_COLOR)) {
return;
}
else if ((data_type == CD_PROP_BYTE_COLOR) && !BKE_id_attribute_search(&mesh_src->id,
else if ((data_type == CD_PROP_BYTE_COLOR) &&
!BKE_id_attribute_search(&const_cast<ID &>(mesh_src->id),
default_color_src,
CD_MASK_PROP_BYTE_COLOR,
ATTR_DOMAIN_MASK_COLOR)) {
@ -344,7 +349,7 @@ static void data_transfer_mesh_attributes_transfer_default_color_string(
/* Generic pre/post processing, only used by custom loop normals currently. */
static void data_transfer_dtdata_type_preprocess(Mesh *me_src,
static void data_transfer_dtdata_type_preprocess(const Mesh *me_src,
Mesh *me_dst,
const int dtdata_type,
const bool dirty_nors_dst)
@ -396,10 +401,7 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src,
}
}
static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/,
Object * /*ob_dst*/,
Mesh * /*me_src*/,
Mesh *me_dst,
static void data_transfer_dtdata_type_postprocess(Mesh *me_dst,
const int dtdata_type,
const bool changed)
{
@ -895,7 +897,7 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map,
static bool data_transfer_layersmapping_generate(ListBase *r_map,
Object *ob_src,
Object *ob_dst,
Mesh *me_src,
const Mesh *me_src,
Mesh *me_dst,
const int elem_type,
int cddata_type,
@ -909,7 +911,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
const int tolayers,
SpaceTransform *space_transform)
{
CustomData *cd_src, *cd_dst;
const CustomData *cd_src;
CustomData *cd_dst;
cd_datatransfer_interp interp = nullptr;
void *interp_data = nullptr;
@ -1299,7 +1302,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
SpaceTransform auto_space_transform;
Mesh *me_src;
const Mesh *me_src;
/* Assumed always true if not using an evaluated mesh as destination. */
bool dirty_nors_dst = true;
@ -1356,7 +1359,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
if (!me_src) {
return changed;
}
BKE_mesh_wrapper_ensure_mdata(me_src);
BKE_mesh_wrapper_ensure_mdata(const_cast<Mesh *>(me_src));
if (auto_transform) {
if (space_transform == nullptr) {
@ -1751,7 +1754,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
}
data_transfer_dtdata_type_postprocess(ob_src, ob_dst, me_src, me_dst, dtdata_type, changed);
data_transfer_dtdata_type_postprocess(me_dst, dtdata_type, changed);
}
for (int i = 0; i < DATAMAX; i++) {

View File

@ -1584,23 +1584,42 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
BKE_mesh_tag_positions_changed(me);
}
void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys)
static void translate_positions(MutableSpan<float3> positions, const float3 &translation)
{
MutableSpan<float3> positions = me->vert_positions_for_write();
for (float3 &position : positions) {
position += offset;
using namespace blender;
threading::parallel_for(positions.index_range(), 2048, [&](const IndexRange range) {
for (float3 &position : positions.slice(range)) {
position += translation;
}
});
}
void BKE_mesh_translate(Mesh *mesh, const float offset[3], const bool do_keys)
{
using namespace blender;
if (math::is_zero(float3(offset))) {
return;
}
int i;
if (do_keys && me->key) {
LISTBASE_FOREACH (KeyBlock *, kb, &me->key->block) {
float *fp = (float *)kb->data;
for (i = kb->totelem; i--; fp += 3) {
add_v3_v3(fp, offset);
}
std::optional<Bounds<float3>> bounds;
if (mesh->runtime->bounds_cache.is_cached()) {
bounds = mesh->runtime->bounds_cache.data();
}
translate_positions(mesh->vert_positions_for_write(), offset);
if (do_keys && mesh->key) {
LISTBASE_FOREACH (KeyBlock *, kb, &mesh->key->block) {
translate_positions({static_cast<float3 *>(kb->data), kb->totelem}, offset);
}
}
BKE_mesh_tag_positions_changed_uniformly(me);
BKE_mesh_tag_positions_changed_uniformly(mesh);
if (bounds) {
bounds->min += offset;
bounds->max += offset;
mesh->bounds_set_eager(*bounds);
}
}
void BKE_mesh_tessface_clear(Mesh *mesh)

View File

@ -31,7 +31,7 @@
* path needs to consist of both edit mesh and edit data checks. */
void BKE_mesh_foreach_mapped_vert(
Mesh *mesh,
const Mesh *mesh,
void (*func)(void *userData, int index, const float co[3], const float no[3]),
void *userData,
MeshForeachFlag flag)

View File

@ -112,7 +112,7 @@ static bool mesh_remap_bvhtree_query_raycast(BVHTreeFromMesh *treedata,
float BKE_mesh_remap_calc_difference_from_mesh(const SpaceTransform *space_transform,
const float (*vert_positions_dst)[3],
const int numverts_dst,
Mesh *me_src)
const Mesh *me_src)
{
BVHTreeFromMesh treedata = {nullptr};
BVHTreeNearest nearest = {0};
@ -241,7 +241,7 @@ static void mesh_calc_eigen_matrix(const float (*positions)[3],
void BKE_mesh_remap_find_best_match_from_mesh(const float (*vert_positions_dst)[3],
const int numverts_dst,
Mesh *me_src,
const Mesh *me_src,
SpaceTransform *r_space_transform)
{
/* Note that those are done so that we successively get actual mirror matrix
@ -463,7 +463,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
const float (*vert_positions_dst)[3],
const int numverts_dst,
const bool /*dirty_nors_dst*/,
Mesh *me_src,
const Mesh *me_src,
Mesh *me_dst,
MeshPairRemap *r_map)
{
@ -686,7 +686,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
const MEdge *edges_dst,
const int numedges_dst,
const bool /*dirty_nors_dst*/,
Mesh *me_src,
const Mesh *me_src,
Mesh *me_dst,
MeshPairRemap *r_map)
{
@ -1239,7 +1239,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
const bool use_split_nors_dst,
const float split_angle_dst,
const bool dirty_nors_dst,
Mesh *me_src,
const Mesh *me_src,
MeshRemapIslandsCalc gen_islands_src,
const float islands_precision_src,
MeshPairRemap *r_map)
@ -2151,7 +2151,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
const int *corner_verts_dst,
const MPoly *polys_dst,
const int numpolys_dst,
Mesh *me_src,
const Mesh *me_src,
MeshPairRemap *r_map)
{
const float full_weight = 1.0f;

View File

@ -1,5 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "IMB_colormanagement.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
@ -20,6 +22,10 @@ static Result detect_edges(Context &context,
GPUShader *shader = context.shader_manager().get("compositor_smaa_edge_detection");
GPU_shader_bind(shader);
float luminance_coefficients[3];
IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
GPU_shader_uniform_1f(shader, "smaa_threshold", threshold);
GPU_shader_uniform_1f(
shader, "smaa_local_contrast_adaptation_factor", local_contrast_adaptation_factor);

View File

@ -1,5 +1,3 @@
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
void main()
{
/* The dispatch domain covers the output image size, which might be a fraction of the input image
@ -7,16 +5,9 @@ void main()
* one. */
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
/* Since the output image might be a fraction of the input image size, and since we want to
* evaluate the input sampler at the center of the output pixel, we add an offset equal to half
* the number of input pixels that covers a single output pixel. In case the input and output
* have the same size, this will be 0.5, which is the offset required to evaluate the sampler at
* the center of the pixel. */
vec2 offset = vec2(texture_size(input_tx) / imageSize(output_img)) / 2.0;
/* Add the aforementioned offset and divide by the output image size to get the coordinates into
* the sampler's expected [0, 1] range. */
vec2 normalized_coordinates = (vec2(texel) + offset) / vec2(imageSize(output_img));
/* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size
* to get the coordinates into the sampler's expected [0, 1] range. */
vec2 normalized_coordinates = (vec2(texel) + vec2(0.5)) / vec2(imageSize(output_img));
vec4 input_color = texture(input_tx, normalized_coordinates);
float luminance = dot(input_color.rgb, luminance_coefficients);

View File

@ -5,11 +5,12 @@
GPU_SHADER_CREATE_INFO(compositor_smaa_edge_detection)
.local_group_size(16, 16)
.define("SMAA_GLSL_3")
.define("SMAA_LUMA_WEIGHT", "float4(1.0, 1.0, 1.0, 1.0)")
.define("SMAA_RT_METRICS",
"vec4(1.0 / vec2(textureSize(input_tx, 0)), vec2(textureSize(input_tx, 0)))")
.define("SMAA_LUMA_WEIGHT", "vec4(luminance_coefficients, 0.0)")
.define("SMAA_THRESHOLD", "smaa_threshold")
.define("SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR", "smaa_local_contrast_adaptation_factor")
.push_constant(Type::VEC3, "luminance_coefficients")
.push_constant(Type::FLOAT, "smaa_threshold")
.push_constant(Type::FLOAT, "smaa_local_contrast_adaptation_factor")
.sampler(0, ImageType::FLOAT_2D, "input_tx")

View File

@ -695,6 +695,7 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
}
}
curves.tag_positions_changed();
DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY);
}

View File

@ -107,24 +107,24 @@ int BIF_countTransformOrientation(const struct bContext *C);
/* to be able to add operator properties to other operators */
#define P_MIRROR (1 << 0)
#define P_MIRROR_DUMMY (P_MIRROR | (1 << 9))
#define P_PROPORTIONAL (1 << 1)
#define P_ORIENT_AXIS (1 << 2)
#define P_ORIENT_AXIS_ORTHO (1 << 16)
#define P_ORIENT_MATRIX (1 << 17)
#define P_SNAP (1 << 3)
#define P_GEO_SNAP (P_SNAP | (1 << 4))
#define P_ALIGN_SNAP (P_GEO_SNAP | (1 << 5))
#define P_CONSTRAINT (1 << 6)
#define P_OPTIONS (1 << 7)
#define P_CORRECT_UV (1 << 8)
#define P_NO_DEFAULTS (1 << 10)
#define P_NO_TEXSPACE (1 << 11)
#define P_CENTER (1 << 12)
#define P_GPENCIL_EDIT (1 << 13)
#define P_CURSOR_EDIT (1 << 14)
#define P_CLNOR_INVALIDATE (1 << 15)
#define P_VIEW2D_EDGE_PAN (1 << 16)
#define P_MIRROR_DUMMY (P_MIRROR | (1 << 1))
#define P_PROPORTIONAL (1 << 2)
#define P_ORIENT_AXIS (1 << 3)
#define P_ORIENT_AXIS_ORTHO (1 << 4)
#define P_ORIENT_MATRIX (1 << 5)
#define P_SNAP (1 << 6)
#define P_GEO_SNAP (P_SNAP | (1 << 7))
#define P_ALIGN_SNAP (P_GEO_SNAP | (1 << 8))
#define P_CONSTRAINT (1 << 9)
#define P_OPTIONS (1 << 10)
#define P_CORRECT_UV (1 << 11)
#define P_NO_DEFAULTS (1 << 12)
#define P_NO_TEXSPACE (1 << 13)
#define P_CENTER (1 << 14)
#define P_GPENCIL_EDIT (1 << 15)
#define P_CURSOR_EDIT (1 << 16)
#define P_CLNOR_INVALIDATE (1 << 17)
#define P_VIEW2D_EDGE_PAN (1 << 18)
/* For properties performed when confirming the transformation. */
#define P_POST_TRANSFORM (1 << 19)

View File

@ -34,7 +34,7 @@ bke::SpanAttributeWriter<float> float_selection_ensure(Curves &curves_id)
attributes.add(".selection",
domain,
CD_PROP_FLOAT,
bke::AttributeInitVArray(VArray<float>::ForSingle(size, 1.0f)));
bke::AttributeInitVArray(VArray<float>::ForSingle(1.0f, size)));
}
return curves.attributes_for_write().lookup_for_write_span<float>(".selection");

View File

@ -480,7 +480,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region
/** \name Timeline - Caches
* \{ */
static bool timeline_cache_is_hidden_by_setting(SpaceAction *saction, PTCacheID *pid)
static bool timeline_cache_is_hidden_by_setting(const SpaceAction *saction, const PTCacheID *pid)
{
switch (pid->type) {
case PTCACHE_TYPE_SOFTBODY:
@ -674,14 +674,14 @@ static void timeline_cache_draw_single(PTCacheID *pid, float y_offset, float hei
GPU_matrix_pop();
}
void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
void timeline_draw_cache(const SpaceAction *saction, const Object *ob, const Scene *scene)
{
if ((saction->cache_display & TIME_CACHE_DISPLAY) == 0 || ob == nullptr) {
return;
}
ListBase pidlist;
BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0);
BKE_ptcache_ids_from_object(&pidlist, const_cast<Object *>(ob), const_cast<Scene *>(scene), 0);
uint pos_id = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);

View File

@ -35,7 +35,7 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region);
*/
void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region);
void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene);
void timeline_draw_cache(const SpaceAction *saction, const Object *ob, const Scene *scene);
/* ***************************************** */
/* action_select.c */

View File

@ -44,6 +44,8 @@
#include "BLO_read_write.h"
#include "GPU_matrix.h"
#include "action_intern.hh" /* own include */
/* -------------------------------------------------------------------- */
@ -169,7 +171,6 @@ static void action_main_region_draw(const bContext *C, ARegion *region)
/* draw entirely, view changes should be handled here */
SpaceAction *saction = CTX_wm_space_action(C);
Scene *scene = CTX_data_scene(C);
Object *obact = CTX_data_active_object(C);
bAnimContext ac;
View2D *v2d = &region->v2d;
short marker_flag = 0;
@ -212,11 +213,6 @@ static void action_main_region_draw(const bContext *C, ARegion *region)
ED_markers_draw(C, marker_flag);
}
/* caches */
if (saction->mode == SACTCONT_TIMELINE) {
timeline_draw_cache(saction, obact, scene);
}
/* preview range */
UI_view2d_view_ortho(v2d);
ANIM_draw_previewrange(C, v2d, 0);
@ -240,8 +236,17 @@ static void action_main_region_draw_overlay(const bContext *C, ARegion *region)
/* draw entirely, view changes should be handled here */
const SpaceAction *saction = CTX_wm_space_action(C);
const Scene *scene = CTX_data_scene(C);
const Object *obact = CTX_data_active_object(C);
View2D *v2d = &region->v2d;
/* caches */
if (saction->mode == SACTCONT_TIMELINE) {
GPU_matrix_push_projection();
UI_view2d_view_orthoSpecial(region, v2d, 1);
timeline_draw_cache(saction, obact, scene);
GPU_matrix_pop_projection();
}
/* scrubbing region */
ED_time_scrub_draw_current_frame(region, scene, saction->flag & SACTION_DRAWTIME);

View File

@ -620,7 +620,8 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
case TFM_MODAL_ROTATE:
case TFM_MODAL_RESIZE:
case TFM_MODAL_VERT_EDGE_SLIDE:
case TFM_MODAL_TRACKBALL: {
case TFM_MODAL_TRACKBALL:
case TFM_MODAL_ROTATE_NORMALS: {
if (!transform_mode_is_changeable(t->mode)) {
return false;
}
@ -662,6 +663,9 @@ static bool transform_modal_item_poll(const wmOperator *op, int value)
t->mode != TFM_ROTATION) {
return false;
}
if (value == TFM_MODAL_ROTATE_NORMALS) {
return t->mode == TFM_ROTATION && t->data_type == &TransConvertType_Mesh;
}
break;
}
}
@ -712,6 +716,7 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf)
{TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""},
{TFM_MODAL_TRACKBALL, "TRACKBALL", 0, "TrackBall", ""},
{TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""},
{TFM_MODAL_ROTATE_NORMALS, "ROTATE_NORMALS", 0, "Rotate Normals", ""},
{TFM_MODAL_AUTOCONSTRAINT, "AUTOCONSTRAIN", 0, "Automatic Constraint", ""},
{TFM_MODAL_AUTOCONSTRAINTPLANE, "AUTOCONSTRAINPLANE", 0, "Automatic Constraint Plane", ""},
{TFM_MODAL_PRECISION, "PRECISION", 0, "Precision Mode", ""},
@ -917,8 +922,6 @@ static bool transform_event_modal_constraint(TransInfo *t, short modal_type)
int transformEvent(TransInfo *t, const wmEvent *event)
{
bool handled = false;
const int modifiers_prev = t->modifiers;
const int mode_prev = t->mode;
/* Handle modal numinput events first, if already activated. */
if (((event->val == KM_PRESS) || (event->type == EVT_MODAL_MAP)) && hasNumInput(&t->num) &&
@ -956,116 +959,86 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
break;
case TFM_MODAL_TRANSLATE:
case TFM_MODAL_ROTATE:
case TFM_MODAL_RESIZE:
case TFM_MODAL_TRACKBALL:
case TFM_MODAL_ROTATE_NORMALS:
case TFM_MODAL_VERT_EDGE_SLIDE:
/* only switch when... */
if (!transform_mode_is_changeable(t->mode)) {
break;
}
if (event->val == TFM_MODAL_VERT_EDGE_SLIDE) {
if (ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE)) {
break;
}
if ((t->obedit_type == OB_MESH) && (t->spacetype == SPACE_VIEW3D)) {
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
/* first try edge slide */
transform_mode_init(t, NULL, TFM_EDGE_SLIDE);
/* if that fails, do vertex slide */
if (t->state == TRANS_CANCEL) {
resetTransModal(t);
t->state = TRANS_STARTING;
transform_mode_init(t, NULL, TFM_VERT_SLIDE);
}
/* vert slide can fail on unconnected vertices (rare but possible) */
if (t->state == TRANS_CANCEL) {
resetTransModal(t);
t->state = TRANS_STARTING;
restoreTransObjects(t);
resetTransRestrictions(t);
transform_mode_init(t, NULL, TFM_TRANSLATION);
}
initSnapping(t, NULL); /* need to reinit after mode change */
t->redraw |= TREDRAW_HARD;
handled = true;
}
}
else {
if (t->mode == TFM_TRANSLATION) {
if (t->data_type == &TransConvertType_Tracking) {
restoreTransObjects(t);
t->flag ^= T_ALT_TRANSFORM;
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
}
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
transform_mode_init(t, NULL, TFM_TRANSLATION);
initSnapping(t, NULL); /* need to reinit after mode change */
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
case TFM_MODAL_ROTATE:
case TFM_MODAL_TRACKBALL:
/* only switch when... */
if (!transform_mode_is_changeable(t->mode)) {
break;
}
if (event->val == TFM_MODAL_TRACKBALL) {
if (t->mode == TFM_TRACKBALL) {
break;
}
}
else if (t->mode == TFM_ROTATION) {
break;
}
if (!(t->options & CTX_TEXTURE_SPACE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) {
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
if (event->val == TFM_MODAL_TRACKBALL) {
transform_mode_init(t, NULL, TFM_TRACKBALL);
}
else {
transform_mode_init(t, NULL, TFM_ROTATION);
}
initSnapping(t, NULL); /* need to reinit after mode change */
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
case TFM_MODAL_RESIZE:
/* only switch when... */
if (t->mode == TFM_RESIZE) {
if (t->options & CTX_MOVIECLIP) {
if ((event->val == TFM_MODAL_TRANSLATE && t->mode == TFM_TRANSLATION) ||
(event->val == TFM_MODAL_RESIZE && t->mode == TFM_RESIZE)) {
if (t->data_type == &TransConvertType_Tracking) {
restoreTransObjects(t);
t->flag ^= T_ALT_TRANSFORM;
t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
}
else if (transform_mode_is_changeable(t->mode)) {
if ((event->val == TFM_MODAL_ROTATE && t->mode == TFM_ROTATION) ||
(event->val == TFM_MODAL_TRACKBALL && t->mode == TFM_TRACKBALL) ||
(event->val == TFM_MODAL_ROTATE_NORMALS && t->mode == TFM_NORMAL_ROTATION) ||
(event->val == TFM_MODAL_VERT_EDGE_SLIDE &&
ELEM(t->mode, TFM_VERT_SLIDE, TFM_EDGE_SLIDE))) {
break;
}
if (event->val == TFM_MODAL_ROTATE_NORMALS && t->data_type != &TransConvertType_Mesh) {
break;
}
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
if (event->val == TFM_MODAL_TRANSLATE) {
transform_mode_init(t, NULL, TFM_TRANSLATION);
}
else if (event->val == TFM_MODAL_ROTATE) {
transform_mode_init(t, NULL, TFM_ROTATION);
}
else if (event->val == TFM_MODAL_TRACKBALL) {
transform_mode_init(t, NULL, TFM_TRACKBALL);
}
else if (event->val == TFM_MODAL_ROTATE_NORMALS) {
transform_mode_init(t, NULL, TFM_NORMAL_ROTATION);
}
else if (event->val == TFM_MODAL_RESIZE) {
/* Scale isn't normally very useful after extrude along normals, see #39756 */
if ((t->con.mode & CON_APPLY) && (t->orient[t->orient_curr].type == V3D_ORIENT_NORMAL)) {
stopConstraint(t);
}
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
transform_mode_init(t, NULL, TFM_RESIZE);
initSnapping(t, NULL); /* need to reinit after mode change */
t->redraw |= TREDRAW_HARD;
handled = true;
}
else {
/* First try Edge Slide. */
transform_mode_init(t, NULL, TFM_EDGE_SLIDE);
/* If that fails, try Vertex Slide. */
if (t->state == TRANS_CANCEL) {
resetTransModal(t);
t->state = TRANS_STARTING;
transform_mode_init(t, NULL, TFM_VERT_SLIDE);
}
/* Vert Slide can fail on unconnected vertices (rare but possible). */
if (t->state == TRANS_CANCEL) {
resetTransModal(t);
t->state = TRANS_STARTING;
resetTransRestrictions(t);
transform_mode_init(t, NULL, TFM_TRANSLATION);
}
}
/* Need to reinit after mode change. */
initSnapping(t, NULL);
applyMouseInput(t, &t->mouse, t->mval, t->values);
t->redraw |= TREDRAW_HARD;
handled = true;
break;
case TFM_MODAL_SNAP_INV_ON:
@ -1324,21 +1297,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
}
break;
case EVT_NKEY:
if (event->flag & WM_EVENT_IS_REPEAT) {
break;
}
if (ELEM(t->mode, TFM_ROTATION)) {
if ((t->flag & T_EDIT) && t->obedit_type == OB_MESH) {
restoreTransObjects(t);
resetTransModal(t);
resetTransRestrictions(t);
transform_mode_init(t, NULL, TFM_NORMAL_ROTATION);
t->redraw = TREDRAW_HARD;
handled = true;
}
}
break;
default:
break;
}
@ -1365,12 +1323,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
}
}
/* if we change snap options, get the unsnapped values back */
if ((mode_prev != t->mode) || ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) !=
(modifiers_prev & (MOD_SNAP | MOD_SNAP_INVERT)))) {
applyMouseInput(t, &t->mouse, t->mval, t->values);
}
/* Per transform event, if present */
if (t->handleEvent && (!handled ||
/* Needed for vertex slide, see #38756. */

View File

@ -142,7 +142,7 @@ typedef enum {
/** Do not display Xform gizmo even though it is available. */
T_NO_GIZMO = 1 << 24,
} eTFlag;
ENUM_OPERATORS(eTFlag, T_NO_CURSOR_WRAP);
ENUM_OPERATORS(eTFlag, T_NO_GIZMO);
#define T_ALL_RESTRICTIONS (T_NO_CONSTRAINT | T_NULL_ONE)
#define T_PROP_EDIT_ALL (T_PROP_EDIT | T_PROP_CONNECTED | T_PROP_PROJECTED)
@ -268,6 +268,7 @@ enum {
TFM_MODAL_VERT_EDGE_SLIDE = 31,
TFM_MODAL_TRACKBALL = 32,
TFM_MODAL_ROTATE_NORMALS = 33,
};
/** \} */

View File

@ -2219,7 +2219,13 @@ void VIEW3D_GGT_xform_gizmo_context(wmGizmoGroupType *gzgt)
static wmGizmoGroup *gizmogroup_xform_find(TransInfo *t)
{
wmGizmo *gizmo_modal_current = WM_gizmomap_get_modal(t->region->gizmo_map);
struct wmGizmoMap *gizmo_map = t->region->gizmo_map;
if (gizmo_map == nullptr) {
BLI_assert_msg(false, "#T_NO_GIZMO should already be set to return early before.");
return nullptr;
}
wmGizmo *gizmo_modal_current = WM_gizmomap_get_modal(gizmo_map);
if (gizmo_modal_current) {
wmGizmoGroup *gzgroup = gizmo_modal_current->parent_gzgroup;
/* Check #wmGizmoGroup::customdata to make sure the GizmoGroup has been initialized. */
@ -2229,7 +2235,7 @@ static wmGizmoGroup *gizmogroup_xform_find(TransInfo *t)
}
else {
/* See #WM_gizmomap_group_find_ptr. */
LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, WM_gizmomap_group_list(t->region->gizmo_map)) {
LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, WM_gizmomap_group_list(gizmo_map)) {
if (ELEM(gzgroup->type, g_GGT_xform_gizmo, g_GGT_xform_gizmo_context)) {
/* Choose the one that has been initialized. */
if (gzgroup->customdata) {

View File

@ -72,7 +72,8 @@ bool transform_mode_is_changeable(const int mode)
TFM_TRACKBALL,
TFM_TRANSLATION,
TFM_EDGE_SLIDE,
TFM_VERT_SLIDE);
TFM_VERT_SLIDE,
TFM_NORMAL_ROTATION);
}
/* -------------------------------------------------------------------- */

View File

@ -202,6 +202,9 @@ struct AllMeshesInfo {
VectorSet<Material *> materials;
bool create_id_attribute = false;
bool create_material_index_attribute = false;
/** True if we know that there are no loose edges in any of the input meshes. */
bool no_loose_edges_hint = false;
};
struct AllCurvesInfo {
@ -940,6 +943,12 @@ static AllMeshesInfo preprocess_meshes(const GeometrySet &geometry_set,
mesh_info.material_indices = attributes.lookup_or_default<int>(
"material_index", ATTR_DOMAIN_FACE, 0);
}
info.no_loose_edges_hint = std::all_of(
info.order.begin(), info.order.end(), [](const Mesh *mesh) {
return mesh->runtime->loose_edges_cache.is_cached() && mesh->loose_edges().count == 0;
});
return info;
}
@ -1150,6 +1159,10 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options,
}
vertex_ids.finish();
material_indices.finish();
if (all_meshes_info.no_loose_edges_hint) {
dst_mesh->loose_edges_tag_none();
}
}
/** \} */

View File

@ -800,6 +800,8 @@ if(WITH_GPU_BUILDTIME_SHADER_BUILDER)
bf_blenlib
bf_intern_ghost
${PLATFORM_LINKLIBS}
${IMATH_LIBRARIES}
${IMATH_LIBRARY}
)
target_include_directories(shader_builder PRIVATE ${INC} ${CMAKE_CURRENT_BINARY_DIR})

View File

@ -89,7 +89,7 @@ void OBJMesh::clear()
owned_export_mesh_ = nullptr;
}
export_mesh_ = nullptr;
uv_indices_.clear_and_shrink();
loop_to_uv_index_.clear_and_shrink();
uv_coords_.clear_and_shrink();
loop_to_normal_index_.clear_and_shrink();
normal_coords_.clear_and_shrink();
@ -162,7 +162,7 @@ int OBJMesh::tot_polygons() const
int OBJMesh::tot_uv_vertices() const
{
return tot_uv_vertices_;
return int(uv_coords_.size());
}
int OBJMesh::tot_edges() const
@ -290,67 +290,47 @@ Span<int> OBJMesh::calc_poly_vertex_indices(const int poly_index) const
void OBJMesh::store_uv_coords_and_indices()
{
const int totvert = export_mesh_->totvert;
const StringRef active_uv_name = CustomData_get_active_layer_name(&export_mesh_->ldata,
CD_PROP_FLOAT2);
if (active_uv_name.is_empty()) {
tot_uv_vertices_ = 0;
uv_coords_.clear();
return;
}
const bke::AttributeAccessor attributes = export_mesh_->attributes();
const VArraySpan<float2> uv_map = attributes.lookup<float2>(active_uv_name, ATTR_DOMAIN_CORNER);
const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT};
UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
mesh_polys_.data(),
nullptr,
nullptr,
mesh_corner_verts_.data(),
reinterpret_cast<const float(*)[2]>(uv_map.data()),
mesh_polys_.size(),
totvert,
limit,
false,
false);
uv_indices_.resize(mesh_polys_.size());
/* At least total vertices of a mesh will be present in its texture map. So
* reserve minimum space early. */
uv_coords_.reserve(totvert);
tot_uv_vertices_ = 0;
for (int vertex_index = 0; vertex_index < totvert; vertex_index++) {
const UvMapVert *uv_vert = BKE_mesh_uv_vert_map_get_vert(uv_vert_map, vertex_index);
for (; uv_vert; uv_vert = uv_vert->next) {
if (uv_vert->separate) {
tot_uv_vertices_ += 1;
}
const int verts_in_poly = mesh_polys_[uv_vert->poly_index].totloop;
/* Store UV vertex coordinates. */
uv_coords_.resize(tot_uv_vertices_);
const int loopstart = mesh_polys_[uv_vert->poly_index].loopstart;
Span<float> vert_uv_coords(uv_map[loopstart + uv_vert->loop_of_poly_index], 2);
uv_coords_[tot_uv_vertices_ - 1] = float2(vert_uv_coords[0], vert_uv_coords[1]);
/* Store UV vertex indices. */
uv_indices_[uv_vert->poly_index].resize(verts_in_poly);
/* Keep indices zero-based and let the writer handle the "+ 1" as per OBJ spec. */
uv_indices_[uv_vert->poly_index][uv_vert->loop_of_poly_index] = tot_uv_vertices_ - 1;
}
if (uv_map.is_empty()) {
uv_coords_.clear();
return;
}
Map<float2, int> uv_to_index;
/* We don't know how many unique UVs there will be, but this is a guess. */
uv_to_index.reserve(export_mesh_->totvert);
uv_coords_.reserve(export_mesh_->totvert);
loop_to_uv_index_.resize(uv_map.size());
for (int index = 0; index < int(uv_map.size()); index++) {
float2 uv = uv_map[index];
int uv_index = uv_to_index.lookup_default(uv, -1);
if (uv_index == -1) {
uv_index = uv_to_index.size();
uv_to_index.add(uv, uv_index);
uv_coords_.append(uv);
}
loop_to_uv_index_[index] = uv_index;
}
BKE_mesh_uv_vert_map_free(uv_vert_map);
}
Span<int> OBJMesh::calc_poly_uv_indices(const int poly_index) const
{
if (uv_indices_.size() <= 0) {
if (uv_coords_.is_empty()) {
return {};
}
BLI_assert(poly_index < export_mesh_->totpoly);
BLI_assert(poly_index < uv_indices_.size());
return uv_indices_[poly_index];
const MPoly &poly = mesh_polys_[poly_index];
return loop_to_uv_index_.as_span().slice(poly.loopstart, poly.totloop);
}
float3 OBJMesh::calc_poly_normal(const int poly_index) const

View File

@ -52,17 +52,14 @@ class OBJMesh : NonCopyable {
bool mirrored_transform_;
/**
* Total UV vertices in a mesh's texture map.
* Per-loop UV index.
*/
int tot_uv_vertices_ = 0;
/**
* Per-polygon-per-vertex UV vertex indices.
*/
Vector<Vector<int>> uv_indices_;
Vector<int> loop_to_uv_index_;
/*
* UV vertices.
*/
Vector<float2> uv_coords_;
/**
* Per-loop normal index.
*/

View File

@ -340,6 +340,19 @@ TEST_F(obj_exporter_regression_test, edges)
}
TEST_F(obj_exporter_regression_test, vertices)
{
OBJExportParamsDefault _export;
_export.params.forward_axis = IO_AXIS_Y;
_export.params.up_axis = IO_AXIS_Z;
_export.params.export_materials = false;
compare_obj_export_to_golden("io_tests" SEP_STR "blend_geometry" SEP_STR
"cube_loose_edges_verts.blend",
"io_tests" SEP_STR "obj" SEP_STR "cube_loose_edges_verts.obj",
"",
_export.params);
}
TEST_F(obj_exporter_regression_test, cube_loose_edges)
{
OBJExportParamsDefault _export;
_export.params.forward_axis = IO_AXIS_Y;

View File

@ -6731,7 +6731,7 @@ static void def_cmp_map_range(StructRNA *srna)
prop = RNA_def_property(srna, "use_clamp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
RNA_def_property_ui_text(prop, "Clamp", "Clamp result of the node to 0.0 to 1.0 range");
RNA_def_property_ui_text(prop, "Clamp", "Clamp the result of the node to the target range");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}

View File

@ -2119,7 +2119,7 @@ static void rna_def_sequence(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "start");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Start Frame", "X position where the strip begins");
RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 3, 0);
RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 100.0f, 0);
RNA_def_property_float_funcs(
prop, NULL, "rna_Sequence_start_frame_set", NULL); /* overlap tests and calc_seq_disp */
RNA_def_property_editable_func(prop, "rna_Sequence_frame_editable");
@ -2157,7 +2157,7 @@ static void rna_def_sequence(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "startofs");
// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
RNA_def_property_ui_text(prop, "Start Offset", "");
RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 3, 0);
RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 100.0f, 0);
RNA_def_property_float_funcs(
prop, NULL, "rna_Sequence_frame_offset_start_set", "rna_Sequence_frame_offset_start_range");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_frame_change_update");
@ -2166,7 +2166,7 @@ static void rna_def_sequence(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "endofs");
// RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* overlap tests */
RNA_def_property_ui_text(prop, "End Offset", "");
RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 3, 0);
RNA_def_property_ui_range(prop, MINFRAME, MAXFRAME, 100.0f, 0);
RNA_def_property_float_funcs(
prop, NULL, "rna_Sequence_frame_offset_end_set", "rna_Sequence_frame_offset_end_range");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_frame_change_update");

View File

@ -54,14 +54,6 @@ static void transform_positions(MutableSpan<float3> positions, const float4x4 &m
});
}
static void translate_mesh(Mesh &mesh, const float3 translation)
{
if (!math::is_zero(translation)) {
translate_positions(mesh.vert_positions_for_write(), translation);
BKE_mesh_tag_positions_changed_uniformly(&mesh);
}
}
static void transform_mesh(Mesh &mesh, const float4x4 &transform)
{
transform_positions(mesh.vert_positions_for_write(), transform);
@ -70,11 +62,26 @@ static void transform_mesh(Mesh &mesh, const float4x4 &transform)
static void translate_pointcloud(PointCloud &pointcloud, const float3 translation)
{
if (math::is_zero(translation)) {
return;
}
std::optional<Bounds<float3>> bounds;
if (pointcloud.runtime->bounds_cache.is_cached()) {
bounds = pointcloud.runtime->bounds_cache.data();
}
MutableAttributeAccessor attributes = pointcloud.attributes_for_write();
SpanAttributeWriter position = attributes.lookup_or_add_for_write_span<float3>(
"position", ATTR_DOMAIN_POINT);
translate_positions(position.span, translation);
position.finish();
if (bounds) {
bounds->min += translation;
bounds->max += translation;
pointcloud.runtime->bounds_cache.ensure([&](Bounds<float3> &r_data) { r_data = *bounds; });
}
}
static void transform_pointcloud(PointCloud &pointcloud, const float4x4 &transform)
@ -199,7 +206,7 @@ static void translate_geometry_set(GeoNodeExecParams &params,
curves->geometry.wrap().translate(translation);
}
if (Mesh *mesh = geometry.get_mesh_for_write()) {
translate_mesh(*mesh, translation);
BKE_mesh_translate(mesh, translation, false);
}
if (PointCloud *pointcloud = geometry.get_pointcloud_for_write()) {
translate_pointcloud(*pointcloud, translation);