Compare commits
569 Commits
temp-geome
...
lanpr-unde
Author | SHA1 | Date | |
---|---|---|---|
ef19258423 | |||
9166075cbe | |||
10c097eff0 | |||
a3b9322845 | |||
89b7ba1b3b | |||
c5a59fba58 | |||
b30687b2ca | |||
c2f0ee013b | |||
4885b649ef | |||
282d12663f | |||
0c0686bd1a | |||
1870205455 | |||
3ef840fa2d | |||
72f0947c12 | |||
64f573c8b5 | |||
351cf10bf2 | |||
50ff559544 | |||
6b6052713c | |||
a60b3071b5 | |||
0bed1158e0 | |||
85899dd8ae | |||
e5310101fa | |||
67852caf0b | |||
22875e3ab0 | |||
eade6d3ae5 | |||
ac90022760 | |||
6d3ce4cf07 | |||
05089352b8 | |||
51f07e1652 | |||
2c35b091bf | |||
96ef8ed07f | |||
d1dee06e5e | |||
24a97e07ee | |||
3da9bee809 | |||
4d382591ff | |||
418d99d2c7 | |||
bd9a8de00c | |||
2700d8509f | |||
e5c3317527 | |||
2f953ef6e9 | |||
f475abdad2 | |||
de02909d02 | |||
31f13c2ae7 | |||
2ff102e651 | |||
dc96fdda01 | |||
6f8ebd5e50 | |||
5efc132c2c | |||
bb80b1278c | |||
ee4069e460 | |||
abbe7c9e6a | |||
dfe08487a4 | |||
00e7a89f81 | |||
bd46b40756 | |||
603dfdcc9d | |||
cba8012cd9 | |||
c4304b3e0f | |||
009314d417 | |||
dd9fce0ba0 | |||
18a6508505 | |||
7354580f5d | |||
35d16ff452 | |||
bea6d5ebd4 | |||
8732277b8c | |||
dbdd026fb3 | |||
8ff66f0183 | |||
88eb5b43c3 | |||
1c35405ec4 | |||
c99754dabc | |||
e1800eb8e5 | |||
34d7559ffe | |||
661fa309f1 | |||
097bb6065c | |||
d1152b069a | |||
d58c2568bb | |||
8adb6b3595 | |||
4775d79df5 | |||
257f620f75 | |||
b985019186 | |||
67f28300c0 | |||
fb52b3b69d | |||
78a6c9cfb0 | |||
aecceb7b1e | |||
8d9c76f43a | |||
bbcc73607c | |||
9ec833266c | |||
626ab18f18 | |||
4ca8357baf | |||
b35611632f | |||
ba4a481c91 | |||
50578422f4 | |||
6c54cdaab5 | |||
d142b5605e | |||
624bb6c9e2 | |||
77030d813e | |||
70867ff74e | |||
3a00152fe7 | |||
d244a66175 | |||
ed0341ca4c | |||
bb25a7a59a | |||
2d8d86359c | |||
40ba7e7392 | |||
717c9f0682 | |||
8bfaf0152b | |||
d6eb20701a | |||
fe8800eaae | |||
f4c22820f0 | |||
970d4ad696 | |||
fe578d7c7d | |||
4f52220fbf | |||
d2e86c49aa | |||
bc7af55b7a | |||
ff71b67f75 | |||
43770adf13 | |||
9eefbdfc51 | |||
bb231515e5 | |||
c28f0e55c1 | |||
6d53c218de | |||
0c15f1ed3e | |||
97656f68e1 | |||
ecb734cd02 | |||
52ef81f848 | |||
6b8b0024db | |||
cfb867fdaf | |||
945222740f | |||
8b2694a005 | |||
![]() |
36c273b68c | ||
91b0bfc809 | |||
691183242b | |||
162277f050 | |||
49b3691c23 | |||
5796c1455f | |||
da87ee1d05 | |||
a8e7d15fa0 | |||
a319af986a | |||
81ad816441 | |||
![]() |
c95015bf96 | ||
f0b5fceac2 | |||
310d85678e | |||
![]() |
bcaed55995 | ||
62c8f77395 | |||
![]() |
0a87fd4b92 | ||
fe0b6b564b | |||
89565e0631 | |||
d704c293c2 | |||
cc13cac397 | |||
179d94e407 | |||
82422c8d1f | |||
6fb70a29de | |||
b9d063ab59 | |||
7cc23f317b | |||
2ed35a9f93 | |||
cb39e2800f | |||
94c0d3a4cc | |||
33aef1b100 | |||
157f4f37ad | |||
7b38f90bd1 | |||
f3fd29d609 | |||
03853fb303 | |||
bb936cfb6a | |||
0bcf788c61 | |||
78dc814112 | |||
03d50cddb3 | |||
d7fe06b35b | |||
4b51eb5743 | |||
ce55b10522 | |||
24ab978a67 | |||
0a42b85fc4 | |||
992735589d | |||
6b91c61a4f | |||
69e46f11dd | |||
a603f3ad53 | |||
11c94ad244 | |||
ca7838d76a | |||
42e710b87a | |||
c5302b95de | |||
416ca93300 | |||
639d92f1ed | |||
3f76836e72 | |||
12e07cf9de | |||
a7d6caf94e | |||
92104a822d | |||
1a5106c0d1 | |||
dc6cdfb8d5 | |||
7567d8959e | |||
175d684470 | |||
08503a9062 | |||
a75700a775 | |||
46dc226b23 | |||
62d3a0d1ec | |||
bbba3c7e72 | |||
2ac3613084 | |||
a78e132bf4 | |||
5130c9e7a6 | |||
617a60f8b7 | |||
c50483f548 | |||
90e05b47cd | |||
d8d0ae39a3 | |||
fdfd5dcdf1 | |||
5eaa709063 | |||
df558cb605 | |||
501d064ee9 | |||
a47a64d9e4 | |||
bfe222561c | |||
a823597548 | |||
![]() |
adfa705804 | ||
2604bade6c | |||
d0e2ce54ac | |||
6d5794e6bc | |||
7c0068c10f | |||
964071403a | |||
9282b3b936 | |||
383c9717b5 | |||
7efa3cec8b | |||
f18f6d5354 | |||
0e1dd86c5b | |||
10f8a79f6a | |||
b45728bbc0 | |||
f14bb97cbf | |||
00eee5090d | |||
5f4be7f48e | |||
60881cf8d9 | |||
954c79fe51 | |||
a55c383752 | |||
b51ebc6785 | |||
64438d679f | |||
b8cf5b7215 | |||
27307a2be6 | |||
328b28cf06 | |||
bba9a70c00 | |||
7e063e00ac | |||
7b6e6ef977 | |||
64362a1c13 | |||
1fa0102959 | |||
450f3498ca | |||
ccef1c234a | |||
59c47ac6d1 | |||
54a7adbe79 | |||
856265b0d8 | |||
6a02e9186b | |||
1198a68f25 | |||
8f611fd0bb | |||
19b5f837b1 | |||
0c95f4f774 | |||
b3decec480 | |||
15ca1f8823 | |||
aa07f958fa | |||
a8703111c4 | |||
9dfff48b99 | |||
6b255bd9bb | |||
d81206066d | |||
02cdabddcb | |||
ac04fdb1d9 | |||
886c2936b0 | |||
b5c8596096 | |||
9061c6919f | |||
518b8a469d | |||
fded457fcb | |||
cc7a57c34e | |||
15855dcbcd | |||
c3735cc332 | |||
09b2374ac0 | |||
a326688c69 | |||
9a9b7c3213 | |||
f79dea97df | |||
2eaf5ec228 | |||
d1ca1b1338 | |||
3d1ea081cf | |||
33f24a5db2 | |||
e25fb868d7 | |||
1e7a51daa6 | |||
b76ffc6e04 | |||
6ea694ceb8 | |||
5ca4e75d95 | |||
2103a1d145 | |||
30dfe126a6 | |||
b132cba50a | |||
c3d1e690cf | |||
64ea607ce4 | |||
3e42356af1 | |||
b99a5e70a1 | |||
2fec1a99c2 | |||
0e9ebfe053 | |||
77971dc662 | |||
716a772d1a | |||
ac220268c8 | |||
77e2f9629d | |||
5c660f0ff4 | |||
100d1c395c | |||
c52aab8b72 | |||
a3044f4733 | |||
0de0b8f335 | |||
d84ba71149 | |||
31b9fa4e9a | |||
d842334b24 | |||
7ecfb0bca8 | |||
3402f6dec0 | |||
d44a93f411 | |||
9a04768b8b | |||
59714f2a00 | |||
3d33971422 | |||
cd9317e74e | |||
653c6819d4 | |||
56e6cccefb | |||
b33dc98893 | |||
d84ec55cff | |||
a7bdfd86e9 | |||
2a4e6aaf48 | |||
c7b0368803 | |||
b82d1cc4c7 | |||
77b00ef498 | |||
9f4d79d02a | |||
c760d3069c | |||
73747311d5 | |||
1f9d955faf | |||
3abb56792d | |||
474e2aef72 | |||
ef01d800ec | |||
839fba88b9 | |||
a4f3f5cec3 | |||
a416b3e210 | |||
3817355e88 | |||
77aa5edffd | |||
91767d7e88 | |||
153815a856 | |||
ab3b1aa3bf | |||
20b39e4bd6 | |||
29f160a7a8 | |||
5fc69361be | |||
5222521bc7 | |||
03f56a9fd6 | |||
a7ed36c803 | |||
7afee455b1 | |||
0dd6a7647c | |||
aaa2da3e6d | |||
1652026cb7 | |||
c53504a5b5 | |||
0c96ae6724 | |||
56cfae9ef0 | |||
c89742c5b1 | |||
b29749af5f | |||
56183da948 | |||
7a489cd639 | |||
0ef3f6760f | |||
7f57b9f2c1 | |||
cbbc9e69c5 | |||
cf365828d8 | |||
9b7b93b206 | |||
15a012de17 | |||
ceb3b7098c | |||
ef2189542d | |||
7fea51be5a | |||
ce3447c064 | |||
8c0845eb7e | |||
5753786bae | |||
173d690149 | |||
9784c5021b | |||
4503af102d | |||
d5d73554c0 | |||
494b75c654 | |||
b08d72d2c8 | |||
e586101619 | |||
24bce50e58 | |||
3cd09680a0 | |||
18754b54b1 | |||
e22c86cbc3 | |||
f58c3f94c9 | |||
c4a4f6ebce | |||
9971dcc073 | |||
338cef6158 | |||
8cdcc3703b | |||
61aad4f0ab | |||
5927aaafb7 | |||
c7d0ad77b0 | |||
38a66b5f1a | |||
501489c55e | |||
7316aeb433 | |||
47985f0ea0 | |||
bd7308e951 | |||
f8ad9f1f8a | |||
1250e862e3 | |||
5c74c712a9 | |||
6fc5b82375 | |||
ef8ee6b2fd | |||
7675d3e6e2 | |||
c4057a0e86 | |||
3d13c7ebbc | |||
0fd17d27ed | |||
2696d9b293 | |||
695ad46107 | |||
a045a2dac6 | |||
98ce3d23a9 | |||
8fabcb8372 | |||
07153475ab | |||
4de6902afe | |||
24c9b37e4b | |||
4139347532 | |||
8c01374ed6 | |||
023e4a5935 | |||
cce663421e | |||
6cbb2ffb0c | |||
19d73bd6b2 | |||
49ebb8095c | |||
7b96cd604a | |||
9f6c0715ec | |||
3be3892d85 | |||
a4d3e6bd47 | |||
1699d79b42 | |||
25de3e5294 | |||
7f6efc6769 | |||
84e504dd3b | |||
342a51c38c | |||
214a2c637f | |||
bbb32cf494 | |||
3f273fbc96 | |||
302d9b38a7 | |||
d4f9a1c134 | |||
afc0b5875e | |||
6b216909c7 | |||
5186330893 | |||
4679d1857f | |||
fac0a317cb | |||
c80318c84c | |||
6f262f79ff | |||
05ffc6fbcb | |||
4bea9c0d2b | |||
7d28cbf05f | |||
365df4b5aa | |||
0bf58275f6 | |||
49152c98a5 | |||
248585b3cc | |||
cde5978cf7 | |||
928da5b65a | |||
ee0a9a26da | |||
44ba7b7e1e | |||
6e64a8d900 | |||
152d2c5184 | |||
53b1c2c278 | |||
a945849f66 | |||
ec9ec3b134 | |||
f19ed441b8 | |||
fcec150c50 | |||
da7964ea49 | |||
3e39b45fa4 | |||
c6fd4b97d0 | |||
35430988c1 | |||
624994718d | |||
705a77765d | |||
09f72c5dba | |||
f2873a2f03 | |||
74dd526809 | |||
f2c5b7ea86 | |||
c963898200 | |||
8f1d640a6f | |||
5b16ae068b | |||
dea7176dba | |||
77115c8832 | |||
141fa711e4 | |||
e09d0b1330 | |||
554ae0bd05 | |||
cc2a1954d9 | |||
cb676fa7da | |||
ef33474ed2 | |||
0abac43019 | |||
ac56bf75c0 | |||
dad2db3bc9 | |||
b6f390f6a9 | |||
0aed42f8a7 | |||
39419bf99f | |||
bf9680f0b4 | |||
44f66c3808 | |||
19ba395d99 | |||
c8f3e4cc6c | |||
db211c8edd | |||
26609e2639 | |||
1b7ea80690 | |||
941ed655a8 | |||
a3dc4a472d | |||
a180717911 | |||
1b856226f7 | |||
29d02c7c30 | |||
78490a7837 | |||
80011e847d | |||
4273836cdc | |||
26e91f4f1e | |||
231bfe46a4 | |||
e9ad44e368 | |||
497633df39 | |||
9803f4502d | |||
b0dda64a95 | |||
56ebc769a6 | |||
cbe77c9110 | |||
48a7fcdf75 | |||
46cd0a12d4 | |||
b211885d0f | |||
43df7f9f6a | |||
050e6bdea7 | |||
35d83ade04 | |||
117c0c18a3 | |||
c2ce9fdee9 | |||
fc3f80d1bb | |||
0ae685b584 | |||
bfbf0bb7f7 | |||
3b52dfe549 | |||
cd54abd2c1 | |||
f7770cb97b | |||
b47883a990 | |||
b5abbc40a0 | |||
c2c6447229 | |||
191b890883 | |||
f83f168c92 | |||
7804323e33 | |||
89e01395a8 | |||
781c9f5206 | |||
6f7f80775d | |||
8b041081c3 | |||
7f81bb4931 | |||
2243de9a90 | |||
798e93b634 | |||
ca43179932 | |||
6967d60c4b | |||
1c2b864155 | |||
cb47cc14cd | |||
352eb65a57 | |||
8eb44bfb81 | |||
acd8fae2d8 | |||
![]() |
541fb672ec | ||
![]() |
6ccd672fee | ||
![]() |
cf38c4d49f | ||
12bf6ee36c | |||
![]() |
4227b81826 | ||
![]() |
cf623d8e7b | ||
![]() |
692f20604c | ||
9f35ef219f | |||
aa4ff9e5d3 | |||
1e801df3ef | |||
f8384c0d2d | |||
5aa70ac589 | |||
c2fbf7668d | |||
365faddd79 | |||
c508138e95 | |||
0476090983 | |||
7da7d97aff | |||
9b27248c64 | |||
b95f15862e | |||
232e13d4cb | |||
96d470c0e2 | |||
7e577c4857 | |||
66aa0a2181 | |||
ba5c4414b0 | |||
ec9cdd6e51 | |||
b3d226ffdb | |||
bdd96da5eb | |||
43419e4c32 | |||
dc9f9faff7 | |||
f2f2f5f6c7 | |||
9c7f536251 | |||
a921c5f239 | |||
bb38766ba6 | |||
45eb04adc8 | |||
ee7785510b | |||
db12505f51 | |||
314439e652 | |||
9a9fa3a206 | |||
c3799f1c31 | |||
ef1cd34e8d | |||
dba890910d | |||
3bcdf06a54 | |||
1924e96f7d | |||
![]() |
e9df7caf19 |
@@ -332,6 +332,9 @@ mark_as_advanced(WITH_SYSTEM_GLOG)
|
||||
# Freestyle
|
||||
option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
|
||||
|
||||
# LRT
|
||||
option(WITH_LINEART "Enable LRT (more advanced edges rendering)" ON)
|
||||
|
||||
# Misc
|
||||
if(WIN32)
|
||||
option(WITH_INPUT_IME "Enable Input Method Editor (IME) for complex Asian character input" ON)
|
||||
@@ -1900,6 +1903,7 @@ if(FIRST_RUN)
|
||||
info_cfg_option(WITH_IK_SOLVER)
|
||||
info_cfg_option(WITH_INPUT_NDOF)
|
||||
info_cfg_option(WITH_INTERNATIONAL)
|
||||
info_cfg_option(WITH_LINEART)
|
||||
info_cfg_option(WITH_OPENCOLLADA)
|
||||
info_cfg_option(WITH_OPENCOLORIO)
|
||||
info_cfg_option(WITH_OPENIMAGEDENOISE)
|
||||
|
@@ -18,6 +18,7 @@ set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_DRACO ON CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
|
||||
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_LINEART ON CACHE BOOL "" FORCE)
|
||||
set(WITH_GMP ON CACHE BOOL "" FORCE)
|
||||
set(WITH_HARU ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
|
||||
|
@@ -23,6 +23,7 @@ set(WITH_CYCLES_DEVICE_OPTIX OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_DRACO OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_FREESTYLE OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_LINEART OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_GMP OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_HARU OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE)
|
||||
|
@@ -19,6 +19,7 @@ set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_DRACO ON CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
|
||||
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_LINEART ON CACHE BOOL "" FORCE)
|
||||
set(WITH_GMP ON CACHE BOOL "" FORCE)
|
||||
set(WITH_HARU ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
|
||||
|
Submodule release/datafiles/locale updated: b06e7fe345...8a05b618f0
Submodule release/scripts/addons updated: ef3104dae3...67f1fbca14
Submodule release/scripts/addons_contrib updated: a140f066ac...ef6ef414d2
@@ -67,6 +67,7 @@ _modules = [
|
||||
"properties_scene",
|
||||
"properties_texture",
|
||||
"properties_world",
|
||||
"properties_collection",
|
||||
|
||||
# Generic Space Modules
|
||||
#
|
||||
@@ -104,6 +105,9 @@ import bpy
|
||||
if bpy.app.build_options.freestyle:
|
||||
_modules.append("properties_freestyle")
|
||||
|
||||
if bpy.app.build_options.lineart:
|
||||
_modules.append("properties_lineart")
|
||||
|
||||
__import__(name=__name__, fromlist=_modules)
|
||||
_namespace = globals()
|
||||
_modules_loaded = [_namespace[name] for name in _modules]
|
||||
|
85
release/scripts/startup/bl_ui/properties_collection.py
Normal file
85
release/scripts/startup/bl_ui/properties_collection.py
Normal file
@@ -0,0 +1,85 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
from bpy.types import Panel
|
||||
|
||||
|
||||
class CollectionButtonsPanel:
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "collection"
|
||||
|
||||
|
||||
def lineart_make_line_type_entry(col, line_type, text_disp, expand, search_from):
|
||||
col.prop(line_type, "use", text=text_disp)
|
||||
if line_type.use and expand:
|
||||
col.prop_search(line_type, "layer", search_from,
|
||||
"layers", icon='GREASEPENCIL')
|
||||
col.prop_search(line_type, "material", search_from,
|
||||
"materials", icon='SHADING_TEXTURE')
|
||||
|
||||
|
||||
class COLLECTION_PT_collection_flags(CollectionButtonsPanel, Panel):
|
||||
bl_label = "Collection Flags"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
vl = context.view_layer
|
||||
vlc = vl.active_layer_collection
|
||||
return (vlc.name != 'Master Collection')
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
collection = context.collection
|
||||
vl = context.view_layer
|
||||
vlc = vl.active_layer_collection
|
||||
|
||||
row = layout.row()
|
||||
col = row.column(align=True)
|
||||
col.prop(vlc, "holdout", toggle=False)
|
||||
col.prop(vlc, "indirect_only", toggle=False)
|
||||
row = layout.row()
|
||||
col = row.column(align=True)
|
||||
col.prop(collection, "hide_select", text="Selectable", toggle=False, invert_checkbox=True)
|
||||
col.prop(collection, "hide_viewport", toggle=False)
|
||||
col.prop(collection, "hide_render", toggle=False)
|
||||
|
||||
|
||||
class COLLECTION_PT_lineart_collection(CollectionButtonsPanel, Panel):
|
||||
bl_label = "Collection Line Art"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
collection = context.collection
|
||||
|
||||
row = layout.row()
|
||||
row.prop(collection, "lineart_usage")
|
||||
|
||||
|
||||
classes = (
|
||||
COLLECTION_PT_collection_flags,
|
||||
COLLECTION_PT_lineart_collection,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
from bpy.utils import register_class
|
||||
for cls in classes:
|
||||
register_class(cls)
|
58
release/scripts/startup/bl_ui/properties_lineart.py
Normal file
58
release/scripts/startup/bl_ui/properties_lineart.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
from bpy.types import Panel
|
||||
|
||||
|
||||
class LineartButtonsPanel:
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "object"
|
||||
|
||||
|
||||
class OBJECT_PT_lineart(LineartButtonsPanel, Panel):
|
||||
bl_label = "Line Art"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
return (ob.type in {'MESH', 'FONT', 'CURVE', 'SURFACE'})
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
lineart = context.object.lineart
|
||||
|
||||
layout.use_property_split = True
|
||||
|
||||
layout.prop(lineart, 'usage')
|
||||
layout.use_property_split = True
|
||||
|
||||
row = layout.row(heading="Override Crease")
|
||||
row.prop(lineart, "use_crease_override", text="")
|
||||
row.prop(lineart, "crease_threshold", slider=True, text="")
|
||||
|
||||
|
||||
classes = (
|
||||
OBJECT_PT_lineart,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
from bpy.utils import register_class
|
||||
for cls in classes:
|
||||
register_class(cls)
|
@@ -274,6 +274,38 @@ class MATERIAL_PT_viewport(MaterialButtonsPanel, Panel):
|
||||
col.prop(mat, "roughness")
|
||||
|
||||
|
||||
class MATERIAL_PT_lineart(MaterialButtonsPanel, Panel):
|
||||
bl_label = "Line Art"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
mat = context.material
|
||||
return mat and not mat.grease_pencil
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
mat = context.material
|
||||
lineart = mat.lineart
|
||||
|
||||
layout.prop(lineart, "use_transparency")
|
||||
|
||||
if lineart.use_transparency:
|
||||
|
||||
layout.label(text="Transparency Masks:")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(lineart, "transparency_mask_0", text="0", toggle=True)
|
||||
row.prop(lineart, "transparency_mask_1", text="1", toggle=True)
|
||||
row.prop(lineart, "transparency_mask_2", text="2", toggle=True)
|
||||
row.prop(lineart, "transparency_mask_3", text="3", toggle=True)
|
||||
row.prop(lineart, "transparency_mask_4", text="4", toggle=True)
|
||||
row.prop(lineart, "transparency_mask_5", text="5", toggle=True)
|
||||
row.prop(lineart, "transparency_mask_6", text="6", toggle=True)
|
||||
row.prop(lineart, "transparency_mask_7", text="7", toggle=True)
|
||||
|
||||
|
||||
classes = (
|
||||
MATERIAL_MT_context_menu,
|
||||
MATERIAL_UL_matslots,
|
||||
@@ -282,6 +314,7 @@ classes = (
|
||||
EEVEE_MATERIAL_PT_surface,
|
||||
EEVEE_MATERIAL_PT_volume,
|
||||
EEVEE_MATERIAL_PT_settings,
|
||||
MATERIAL_PT_lineart,
|
||||
MATERIAL_PT_viewport,
|
||||
EEVEE_MATERIAL_PT_viewport_settings,
|
||||
MATERIAL_PT_custom_props,
|
||||
|
@@ -696,6 +696,158 @@ class RENDER_PT_simplify_greasepencil(RenderButtonsPanel, Panel, GreasePencilSim
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
|
||||
class RENDER_PT_lineart(RenderButtonsPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
bl_label = "Line Art"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw_header(self, context):
|
||||
self.layout.prop(context.scene.lineart, "auto_update", text="")
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
lineart = scene.lineart
|
||||
|
||||
layout = self.layout
|
||||
layout.active = lineart.auto_update
|
||||
layout.use_property_split = True
|
||||
|
||||
if not scene.camera:
|
||||
layout.label(text="No active camera.")
|
||||
|
||||
else:
|
||||
layout.prop(lineart, "use_contour", text='Contour')
|
||||
layout.prop(lineart, "use_material", text='Material Separation')
|
||||
layout.prop(lineart, "use_edge_mark", text='Edge Marks')
|
||||
|
||||
|
||||
class RENDER_PT_lineart_crease(RenderButtonsPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
bl_label = "Crease Lines"
|
||||
bl_parent_id = "RENDER_PT_lineart"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return (scene.camera is not None)
|
||||
|
||||
def draw_header(self, context):
|
||||
scene = context.scene
|
||||
lineart = scene.lineart
|
||||
|
||||
self.layout.prop(lineart, "use_crease", text='')
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
lineart = scene.lineart
|
||||
|
||||
layout = self.layout
|
||||
layout.active = lineart.auto_update
|
||||
layout.use_property_split = True
|
||||
|
||||
layout.prop(lineart, "crease_threshold", slider=True)
|
||||
|
||||
|
||||
class RENDER_PT_lineart_intersection(RenderButtonsPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
bl_label = "Intersection Lines"
|
||||
bl_parent_id = "RENDER_PT_lineart"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return (scene.camera is not None)
|
||||
|
||||
|
||||
def draw_header(self, context):
|
||||
scene = context.scene
|
||||
lineart = scene.lineart
|
||||
self.layout.prop(lineart, "use_intersections", text='')
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
lineart = scene.lineart
|
||||
|
||||
layout = self.layout
|
||||
layout.active = lineart.auto_update
|
||||
layout.use_property_split = True
|
||||
|
||||
row = layout.row(align=False)
|
||||
row.active = not lineart.fuzzy_everything
|
||||
row.prop(lineart, "fuzzy_intersections")
|
||||
|
||||
|
||||
class RENDER_PT_lineart_extras(RenderButtonsPanel, Panel):
|
||||
bl_label = "Extras"
|
||||
bl_parent_id = "RENDER_PT_lineart"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return (scene.camera is not None)
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
lineart = scene.lineart
|
||||
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
layout.prop(lineart, "angle_splitting_threshold", slider=True)
|
||||
|
||||
layout.prop(lineart, "chaining_image_threshold")
|
||||
layout.prop(lineart, "chaining_geometry_threshold")
|
||||
|
||||
layout.label(text="Advanced Options:")
|
||||
layout.prop(lineart, "fuzzy_everything")
|
||||
layout.prop(lineart, "allow_duplication", text="Instancing")
|
||||
layout.prop(lineart, "allow_overlapping_edges")
|
||||
layout.prop(lineart, "allow_clipping_boundaries",
|
||||
text="Show Clipping Boundaries")
|
||||
layout.prop(lineart, "remove_doubles")
|
||||
|
||||
|
||||
class RENDER_PT_lineart_baking(RenderButtonsPanel, Panel):
|
||||
bl_label = "Baking"
|
||||
bl_parent_id = "RENDER_PT_lineart"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
return (scene.camera is not None)
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
lineart = scene.lineart
|
||||
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
layout.prop(lineart, "gpencil_overwrite", text='Overwrite')
|
||||
|
||||
layout.prop(lineart, "baking_final_range")
|
||||
|
||||
if not lineart.baking_final_range:
|
||||
col = layout.column(align=True)
|
||||
col.prop(lineart, "baking_preview_start", text='Start')
|
||||
col.prop(lineart, "baking_preview_end", text='End')
|
||||
|
||||
layout.prop(lineart, "baking_keyframes_only")
|
||||
|
||||
if not lineart.baking_keyframes_only:
|
||||
layout.prop(lineart, "baking_skip")
|
||||
|
||||
layout.operator('scene.lineart_bake_strokes')
|
||||
|
||||
|
||||
classes = (
|
||||
RENDER_PT_context,
|
||||
RENDER_PT_eevee_sampling,
|
||||
@@ -727,6 +879,12 @@ classes = (
|
||||
RENDER_PT_simplify_viewport,
|
||||
RENDER_PT_simplify_render,
|
||||
RENDER_PT_simplify_greasepencil,
|
||||
|
||||
RENDER_PT_lineart,
|
||||
RENDER_PT_lineart_crease,
|
||||
RENDER_PT_lineart_intersection,
|
||||
RENDER_PT_lineart_extras,
|
||||
RENDER_PT_lineart_baking,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
@@ -3809,11 +3809,10 @@ class VIEW3D_MT_edit_mesh_context_menu(Menu):
|
||||
col.operator("mesh.mark_sharp")
|
||||
col.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
|
||||
|
||||
if render.use_freestyle:
|
||||
col.separator()
|
||||
col.separator()
|
||||
|
||||
col.operator("mesh.mark_freestyle_edge").clear = False
|
||||
col.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
|
||||
col.operator("mesh.mark_freestyle_edge").clear = False
|
||||
col.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
|
||||
|
||||
col.separator()
|
||||
|
||||
@@ -4008,11 +4007,10 @@ class VIEW3D_MT_edit_mesh_edges_data(Menu):
|
||||
props.use_verts = True
|
||||
props.clear = True
|
||||
|
||||
if render.use_freestyle:
|
||||
layout.separator()
|
||||
layout.separator()
|
||||
|
||||
layout.operator("mesh.mark_freestyle_edge").clear = False
|
||||
layout.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
|
||||
layout.operator("mesh.mark_freestyle_edge").clear = False
|
||||
layout.operator("mesh.mark_freestyle_edge", text="Clear Freestyle Edge").clear = True
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_edges(Menu):
|
||||
@@ -4021,7 +4019,7 @@ class VIEW3D_MT_edit_mesh_edges(Menu):
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
with_freestyle = bpy.app.build_options.freestyle
|
||||
with_freestyle = bpy.app.build_options.freestyle or bpy.app.build_options.lineart
|
||||
|
||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
|
||||
|
@@ -56,6 +56,7 @@ set(SRC_DNA_INC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_layer_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_light_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_lightprobe_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_lineart_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_linestyle_types.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_listBase.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_mask_types.h
|
||||
|
@@ -82,6 +82,8 @@ struct Collection *BKE_collection_master_add(void);
|
||||
|
||||
bool BKE_collection_has_object(struct Collection *collection, const struct Object *ob);
|
||||
bool BKE_collection_has_object_recursive(struct Collection *collection, struct Object *ob);
|
||||
bool BKE_collection_has_object_recursive_instanced(struct Collection *collection,
|
||||
struct Object *ob);
|
||||
struct Collection *BKE_collection_object_find(struct Main *bmain,
|
||||
struct Scene *scene,
|
||||
struct Collection *collection,
|
||||
@@ -123,6 +125,7 @@ bool BKE_collection_object_cyclic_check(struct Main *bmain,
|
||||
/* Object list cache. */
|
||||
|
||||
struct ListBase BKE_collection_object_cache_get(struct Collection *collection);
|
||||
ListBase BKE_collection_object_cache_instanced_get(struct Collection *collection);
|
||||
void BKE_collection_object_cache_free(struct Collection *collection);
|
||||
|
||||
struct Base *BKE_collection_or_layer_objects(const struct ViewLayer *view_layer,
|
||||
|
@@ -77,6 +77,7 @@ typedef struct Global {
|
||||
* * 1112: Disable new Cloth internal springs handling (09/2014).
|
||||
* * 1234: Disable new dyntopo code fixing skinny faces generation (04/2015).
|
||||
* * 3001: Enable additional Fluid modifier (Mantaflow) options (02/2020).
|
||||
* * 4000: Line Art state output and debugging logs (07/2020).
|
||||
* * 16384 and above: Reserved for python (add-ons) usage.
|
||||
*/
|
||||
short debug_value;
|
||||
|
@@ -212,6 +212,10 @@ void BKE_gpencil_layer_mask_sort(struct bGPdata *gpd, struct bGPDlayer *gpl);
|
||||
void BKE_gpencil_layer_mask_sort_all(struct bGPdata *gpd);
|
||||
void BKE_gpencil_layer_frames_sort(struct bGPDlayer *gpl, bool *r_has_duplicate_frames);
|
||||
|
||||
struct bGPDlayer *BKE_gpencil_layer_get_by_name(struct bGPdata *gpd,
|
||||
char *name,
|
||||
int first_if_not_found);
|
||||
|
||||
/* Brush */
|
||||
struct Material *BKE_gpencil_brush_material_get(struct Brush *brush);
|
||||
void BKE_gpencil_brush_material_set(struct Brush *brush, struct Material *material);
|
||||
@@ -231,6 +235,7 @@ struct Material *BKE_gpencil_object_material_new(struct Main *bmain,
|
||||
int *r_index);
|
||||
|
||||
int BKE_gpencil_object_material_index_get(struct Object *ob, struct Material *ma);
|
||||
int BKE_gpencil_object_material_get_index_name(struct Object *ob, char *name);
|
||||
|
||||
struct Material *BKE_gpencil_object_material_from_brush_get(struct Object *ob,
|
||||
struct Brush *brush);
|
||||
|
@@ -206,7 +206,8 @@ typedef struct GpencilModifierTypeInfo {
|
||||
* This function is optional.
|
||||
*/
|
||||
void (*updateDepsgraph)(struct GpencilModifierData *md,
|
||||
const struct ModifierUpdateDepsgraphContext *ctx);
|
||||
const struct ModifierUpdateDepsgraphContext *ctx,
|
||||
const int mode);
|
||||
|
||||
/**
|
||||
* Should return true if the modifier needs to be recalculated on time
|
||||
|
@@ -679,6 +679,10 @@ if(WITH_FREESTYLE)
|
||||
add_definitions(-DWITH_FREESTYLE)
|
||||
endif()
|
||||
|
||||
if(WITH_LINEART)
|
||||
add_definitions(-DWITH_LINEART)
|
||||
endif()
|
||||
|
||||
if(WITH_ALEMBIC)
|
||||
list(APPEND INC
|
||||
../io/alembic
|
||||
|
@@ -122,7 +122,9 @@ static void collection_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons
|
||||
}
|
||||
|
||||
collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
||||
collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
||||
BLI_listbase_clear(&collection_dst->object_cache);
|
||||
BLI_listbase_clear(&collection_dst->object_cache_instanced);
|
||||
|
||||
BLI_listbase_clear(&collection_dst->gobject);
|
||||
BLI_listbase_clear(&collection_dst->children);
|
||||
@@ -214,8 +216,10 @@ static void collection_blend_write(BlendWriter *writer, ID *id, const void *id_a
|
||||
if (collection->id.us > 0 || BLO_write_is_undo(writer)) {
|
||||
/* Clean up, important in undo case to reduce false detection of changed data-blocks. */
|
||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
||||
collection->tag = 0;
|
||||
BLI_listbase_clear(&collection->object_cache);
|
||||
BLI_listbase_clear(&collection->object_cache_instanced);
|
||||
BLI_listbase_clear(&collection->parents);
|
||||
|
||||
/* write LibData */
|
||||
@@ -246,8 +250,10 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect
|
||||
BKE_previewimg_blend_read(reader, collection->preview);
|
||||
|
||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
||||
collection->tag = 0;
|
||||
BLI_listbase_clear(&collection->object_cache);
|
||||
BLI_listbase_clear(&collection->object_cache_instanced);
|
||||
BLI_listbase_clear(&collection->parents);
|
||||
|
||||
#ifdef USE_COLLECTION_COMPAT_28
|
||||
@@ -773,7 +779,10 @@ const char *BKE_collection_ui_name_get(struct Collection *collection)
|
||||
/** \name Object List Cache
|
||||
* \{ */
|
||||
|
||||
static void collection_object_cache_fill(ListBase *lb, Collection *collection, int parent_restrict)
|
||||
static void collection_object_cache_fill(ListBase *lb,
|
||||
Collection *collection,
|
||||
int parent_restrict,
|
||||
bool with_instances)
|
||||
{
|
||||
int child_restrict = collection->flag | parent_restrict;
|
||||
|
||||
@@ -784,6 +793,10 @@ static void collection_object_cache_fill(ListBase *lb, Collection *collection, i
|
||||
base = MEM_callocN(sizeof(Base), "Object Base");
|
||||
base->object = cob->ob;
|
||||
BLI_addtail(lb, base);
|
||||
if (with_instances && cob->ob->instance_collection) {
|
||||
collection_object_cache_fill(
|
||||
lb, cob->ob->instance_collection, child_restrict, with_instances);
|
||||
}
|
||||
}
|
||||
|
||||
/* Only collection flags are checked here currently, object restrict flag is checked
|
||||
@@ -798,7 +811,7 @@ static void collection_object_cache_fill(ListBase *lb, Collection *collection, i
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
|
||||
collection_object_cache_fill(lb, child->collection, child_restrict);
|
||||
collection_object_cache_fill(lb, child->collection, child_restrict, with_instances);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -809,7 +822,7 @@ ListBase BKE_collection_object_cache_get(Collection *collection)
|
||||
|
||||
BLI_mutex_lock(&cache_lock);
|
||||
if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE)) {
|
||||
collection_object_cache_fill(&collection->object_cache, collection, 0);
|
||||
collection_object_cache_fill(&collection->object_cache, collection, 0, false);
|
||||
collection->flag |= COLLECTION_HAS_OBJECT_CACHE;
|
||||
}
|
||||
BLI_mutex_unlock(&cache_lock);
|
||||
@@ -818,11 +831,29 @@ ListBase BKE_collection_object_cache_get(Collection *collection)
|
||||
return collection->object_cache;
|
||||
}
|
||||
|
||||
ListBase BKE_collection_object_cache_instanced_get(Collection *collection)
|
||||
{
|
||||
if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE_INSTANCED)) {
|
||||
static ThreadMutex cache_lock = BLI_MUTEX_INITIALIZER;
|
||||
|
||||
BLI_mutex_lock(&cache_lock);
|
||||
if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE_INSTANCED)) {
|
||||
collection_object_cache_fill(&collection->object_cache_instanced, collection, 0, true);
|
||||
collection->flag |= COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
||||
}
|
||||
BLI_mutex_unlock(&cache_lock);
|
||||
}
|
||||
|
||||
return collection->object_cache_instanced;
|
||||
}
|
||||
|
||||
static void collection_object_cache_free(Collection *collection)
|
||||
{
|
||||
/* Clear own cache an for all parents, since those are affected by changes as well. */
|
||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
||||
BLI_freelistN(&collection->object_cache);
|
||||
BLI_freelistN(&collection->object_cache_instanced);
|
||||
|
||||
LISTBASE_FOREACH (CollectionParent *, parent, &collection->parents) {
|
||||
collection_object_cache_free(parent->collection);
|
||||
@@ -928,6 +959,16 @@ bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
|
||||
return (BLI_findptr(&objects, ob, offsetof(Base, object)));
|
||||
}
|
||||
|
||||
bool BKE_collection_has_object_recursive_instanced(Collection *collection, Object *ob)
|
||||
{
|
||||
if (ELEM(NULL, collection, ob)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ListBase objects = BKE_collection_object_cache_instanced_get(collection);
|
||||
return (BLI_findptr(&objects, ob, offsetof(Base, object)));
|
||||
}
|
||||
|
||||
static Collection *collection_next_find(Main *bmain, Scene *scene, Collection *collection)
|
||||
{
|
||||
if (scene && collection == scene->master_collection) {
|
||||
|
@@ -1663,6 +1663,32 @@ bGPDlayer *BKE_gpencil_layer_active_get(bGPdata *gpd)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bGPDlayer *BKE_gpencil_layer_get_by_name(bGPdata *gpd, char *name, int first_if_not_found)
|
||||
{
|
||||
bGPDlayer *gpl;
|
||||
int i = 0;
|
||||
|
||||
/* error checking */
|
||||
if (ELEM(NULL, gpd, gpd->layers.first)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* loop over layers until found (assume only one active) */
|
||||
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
if (STREQ(name, gpl->info)) {
|
||||
return gpl;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
/* no such layer */
|
||||
if (first_if_not_found) {
|
||||
return gpd->layers.first;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set the active gp-layer */
|
||||
/**
|
||||
* Set active grease pencil layer.
|
||||
* \param gpd: Grease pencil data-block
|
||||
@@ -2421,6 +2447,22 @@ int BKE_gpencil_object_material_index_get(Object *ob, Material *ma)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int BKE_gpencil_object_material_get_index_name(Object *ob, char *name)
|
||||
{
|
||||
short *totcol = BKE_object_material_len_p(ob);
|
||||
Material *read_ma = NULL;
|
||||
for (short i = 0; i < *totcol; i++) {
|
||||
read_ma = BKE_object_material_get(ob, i + 1);
|
||||
/* Material names are like "MAMaterial.001" */
|
||||
if (STREQ(name, &read_ma->id.name[2])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create a default palette */
|
||||
/**
|
||||
* Create a default palette.
|
||||
* \param bmain: Main pointer
|
||||
|
@@ -176,12 +176,14 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
|
||||
|
||||
CustomData_MeshMasks cddata_masks = scene->customdata_mask;
|
||||
CustomData_MeshMasks_update(&cddata_masks, &CD_MASK_BAREMESH);
|
||||
if (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER) {
|
||||
/* Make sure Freestyle edge/face marks appear in DM for render (see T40315). */
|
||||
/* Make sure Freestyle edge/face marks appear in DM for render (see T40315). Due to Line Art
|
||||
* impementation, edge marks should also be shown in viewport. */
|
||||
#ifdef WITH_FREESTYLE
|
||||
cddata_masks.emask |= CD_MASK_FREESTYLE_EDGE;
|
||||
cddata_masks.pmask |= CD_MASK_FREESTYLE_FACE;
|
||||
cddata_masks.emask |= CD_MASK_FREESTYLE_EDGE;
|
||||
cddata_masks.pmask |= CD_MASK_FREESTYLE_FACE;
|
||||
cddata_masks.vmask |= CD_MASK_MDEFORMVERT;
|
||||
#endif
|
||||
if (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER) {
|
||||
/* Always compute UVs, vertex colors as orcos for render. */
|
||||
cddata_masks.lmask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL;
|
||||
cddata_masks.vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR;
|
||||
|
@@ -117,6 +117,9 @@ MINLINE float sasqrt(float fac);
|
||||
MINLINE float interpf(float a, float b, float t);
|
||||
MINLINE double interpd(double a, double b, double t);
|
||||
|
||||
MINLINE float ratiof(float min, float max, float pos);
|
||||
MINLINE double ratiod(double min, double max, double pos);
|
||||
|
||||
/* NOTE: Compilers will upcast all types smaller than int to int when performing arithmetic
|
||||
* operation. */
|
||||
MINLINE int square_s(short a);
|
||||
|
@@ -180,6 +180,18 @@ MINLINE double interpd(double target, double origin, double fac)
|
||||
return (fac * target) + (1.0f - fac) * origin;
|
||||
}
|
||||
|
||||
MINLINE float ratiof(float min, float max, float pos)
|
||||
{
|
||||
float range = max - min;
|
||||
return range == 0 ? 0 : ((pos - min) / range);
|
||||
}
|
||||
|
||||
MINLINE double ratiod(double min, double max, double pos)
|
||||
{
|
||||
double range = max - min;
|
||||
return range == 0 ? 0 : ((pos - min) / range);
|
||||
}
|
||||
|
||||
/* used for zoom values*/
|
||||
MINLINE float power_of_2(float val)
|
||||
{
|
||||
|
@@ -51,6 +51,7 @@
|
||||
#include "DNA_genfile.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_layer_types.h"
|
||||
#include "DNA_lineart_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_packedFile_types.h"
|
||||
#include "DNA_sdna_types.h"
|
||||
|
@@ -1527,6 +1527,16 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
|
||||
if (!DNA_struct_find(fd->filesdna, "SceneLineArt")) {
|
||||
LISTBASE_FOREACH (Scene *, sc, &bmain->scenes) {
|
||||
sc->lineart.crease_threshold = DEG2RAD(140.0f);
|
||||
sc->lineart.line_types |= LRT_EDGE_FLAG_ALL_TYPE;
|
||||
sc->lineart.flags |= (LRT_ALLOW_DUPLI_OBJECTS | LRT_REMOVE_DOUBLES);
|
||||
sc->lineart.angle_splitting_threshold = DEG2RAD(60.0f);
|
||||
sc->lineart.chaining_geometry_threshold = 0.001f;
|
||||
sc->lineart.chaining_image_threshold = 0.001f;
|
||||
}
|
||||
}
|
||||
/* Default properties editors to auto outliner sync. */
|
||||
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
||||
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
||||
|
@@ -95,6 +95,7 @@
|
||||
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_fileglobal_types.h"
|
||||
#include "DNA_lineart_types.h"
|
||||
#include "DNA_genfile.h"
|
||||
#include "DNA_sdna_types.h"
|
||||
|
||||
|
@@ -2085,7 +2085,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
|
||||
if (mti->updateDepsgraph) {
|
||||
DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
|
||||
ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle);
|
||||
mti->updateDepsgraph(md, &ctx);
|
||||
mti->updateDepsgraph(md, &ctx, graph_->mode);
|
||||
}
|
||||
if (BKE_object_modifier_gpencil_use_time(object, md)) {
|
||||
TimeSourceKey time_src_key;
|
||||
|
@@ -138,6 +138,11 @@ void DRW_draw_select_id(struct Depsgraph *depsgraph,
|
||||
bool DRW_render_check_grease_pencil(struct Depsgraph *depsgraph);
|
||||
void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph);
|
||||
|
||||
/* Line Art calls */
|
||||
#ifdef WITH_LINEART
|
||||
void DRW_scene_lineart_freecache(struct Scene *sce);
|
||||
#endif
|
||||
|
||||
/* This is here because GPUViewport needs it */
|
||||
struct DRWInstanceDataList *DRW_instance_data_list_create(void);
|
||||
void DRW_instance_data_list_free(struct DRWInstanceDataList *idatalist);
|
||||
|
@@ -67,3 +67,8 @@ if(WITH_BLENDER)
|
||||
endif()
|
||||
|
||||
add_subdirectory(datafiles)
|
||||
|
||||
if(WITH_LINEART)
|
||||
add_definitions(-DWITH_LINEART)
|
||||
add_subdirectory(lineart)
|
||||
endif()
|
||||
|
@@ -36,6 +36,7 @@ set(SRC
|
||||
annotate_paint.c
|
||||
drawgpencil.c
|
||||
editaction_gpencil.c
|
||||
gpencil_add_lineart.c
|
||||
gpencil_add_monkey.c
|
||||
gpencil_add_stroke.c
|
||||
gpencil_armature.c
|
||||
|
120
source/blender/editors/gpencil/gpencil_add_lineart.c
Normal file
120
source/blender/editors/gpencil/gpencil_add_lineart.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2017 Blender Foundation
|
||||
* This is a new part of Blender
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup edgpencil
|
||||
*/
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_gpencil.h"
|
||||
#include "BKE_gpencil_geom.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_material.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "ED_gpencil.h"
|
||||
|
||||
/* Definition of the most important info from a color */
|
||||
typedef struct ColorTemplate {
|
||||
const char *name;
|
||||
float line[4];
|
||||
float fill[4];
|
||||
} ColorTemplate;
|
||||
|
||||
/* Add color an ensure duplications (matched by name) */
|
||||
static int gpencil_lineart_material(Main *bmain,
|
||||
Object *ob,
|
||||
const ColorTemplate *pct,
|
||||
const bool fill)
|
||||
{
|
||||
short *totcol = BKE_object_material_len_p(ob);
|
||||
Material *ma = NULL;
|
||||
for (short i = 0; i < *totcol; i++) {
|
||||
ma = BKE_gpencil_material(ob, i + 1);
|
||||
if (STREQ(ma->id.name, pct->name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
int idx;
|
||||
|
||||
/* create a new one */
|
||||
ma = BKE_gpencil_object_material_new(bmain, ob, pct->name, &idx);
|
||||
|
||||
copy_v4_v4(ma->gp_style->stroke_rgba, pct->line);
|
||||
srgb_to_linearrgb_v4(ma->gp_style->stroke_rgba, ma->gp_style->stroke_rgba);
|
||||
|
||||
copy_v4_v4(ma->gp_style->fill_rgba, pct->fill);
|
||||
srgb_to_linearrgb_v4(ma->gp_style->fill_rgba, ma->gp_style->fill_rgba);
|
||||
|
||||
if (fill) {
|
||||
ma->gp_style->flag |= GP_MATERIAL_FILL_SHOW;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/* ***************************************************************** */
|
||||
/* Color Data */
|
||||
|
||||
static const ColorTemplate gp_stroke_material_black = {
|
||||
"Black",
|
||||
{0.0f, 0.0f, 0.0f, 1.0f},
|
||||
{0.0f, 0.0f, 0.0f, 0.0f},
|
||||
};
|
||||
|
||||
/* ***************************************************************** */
|
||||
/* LineArt API */
|
||||
|
||||
/* Add a Simple LineArt setup. */
|
||||
void ED_gpencil_create_lineart(bContext *C, Object *ob)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
bGPdata *gpd = (bGPdata *)ob->data;
|
||||
|
||||
/* create colors */
|
||||
int color_black = gpencil_lineart_material(bmain, ob, &gp_stroke_material_black, false);
|
||||
|
||||
/* set first color as active and in brushes */
|
||||
ob->actcol = color_black + 1;
|
||||
|
||||
/* layers */
|
||||
bGPDlayer *lines = BKE_gpencil_layer_addnew(gpd, "Lines", true);
|
||||
|
||||
/* frames */
|
||||
BKE_gpencil_frame_addnew(lines, CFRA);
|
||||
|
||||
/* update depsgraph */
|
||||
/* To trigger modifier update, this is still needed although we don't have any strokes. */
|
||||
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
|
||||
gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
|
||||
}
|
@@ -250,6 +250,7 @@ void ED_gpencil_brush_draw_eraser(struct Brush *brush, int x, int y);
|
||||
|
||||
void ED_gpencil_create_monkey(struct bContext *C, struct Object *ob, float mat[4][4]);
|
||||
void ED_gpencil_create_stroke(struct bContext *C, struct Object *ob, float mat[4][4]);
|
||||
void ED_gpencil_create_lineart(struct bContext *C, struct Object *ob);
|
||||
|
||||
/* ------------ Object Utilities ------------ */
|
||||
struct Object *ED_gpencil_add_object(struct bContext *C,
|
||||
|
693
source/blender/editors/include/ED_lineart.h
Normal file
693
source/blender/editors/include/ED_lineart.h
Normal file
@@ -0,0 +1,693 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2008 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef WITH_LINEART
|
||||
# error Lineart code included in non-Lineart-enabled build
|
||||
#endif
|
||||
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "DNA_lineart_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct LineartStaticMemPoolNode {
|
||||
Link item;
|
||||
size_t size;
|
||||
size_t used_byte;
|
||||
/* User memory starts here */
|
||||
} LineartStaticMemPoolNode;
|
||||
|
||||
typedef struct LineartStaticMemPool {
|
||||
ListBase pools;
|
||||
SpinLock lock_mem;
|
||||
} LineartStaticMemPool;
|
||||
|
||||
typedef struct LineartRenderTriangleAdjacent {
|
||||
struct LineartRenderLine *rl[3];
|
||||
} LineartRenderTriangleAdjacent;
|
||||
|
||||
typedef struct LineartRenderTriangle {
|
||||
struct LineartRenderVert *v[3];
|
||||
|
||||
/* first culled in line list to use adjacent triangle info, then go through triangle list. */
|
||||
double gn[3];
|
||||
|
||||
/* Material flag is removed to save space. */
|
||||
unsigned char transparency_mask;
|
||||
unsigned char flags; /* eLineartTriangleFlags */
|
||||
|
||||
/* Now only use single link list, because we don't need to go back in order. */
|
||||
struct LinkNode *intersecting_verts;
|
||||
} LineartRenderTriangle;
|
||||
|
||||
typedef struct LineartRenderTriangleThread {
|
||||
struct LineartRenderTriangle base;
|
||||
/** This variable is used to store per-thread triangle-line testing pair,
|
||||
* also re-used to store triangle-triangle pair for intersection testing stage.
|
||||
* Do not directly use LineartRenderTriangleThread, but use it as a pointer,
|
||||
* the size of LineartRenderTriangle is dynamically allocated to contain set thread number of
|
||||
* "testing" field, at least one thread is present, thus we always have at least testing[0].*/
|
||||
struct LineartRenderLine *testing[127];
|
||||
} LineartRenderTriangleThread;
|
||||
|
||||
typedef enum eLineArtElementNodeFlag {
|
||||
LRT_ELEMENT_IS_ADDITIONAL = (1 << 0),
|
||||
LRT_ELEMENT_BORDER_ONLY = (1 << 1),
|
||||
LRT_ELEMENT_NO_INTERSECTION = (1 << 2),
|
||||
} eLineArtElementNodeFlag;
|
||||
|
||||
typedef struct LineartRenderElementLinkNode {
|
||||
struct LineartRenderElementLinkNode *next, *prev;
|
||||
void *pointer;
|
||||
int element_count;
|
||||
void *object_ref;
|
||||
eLineArtElementNodeFlag flags;
|
||||
|
||||
/* Per object value, always set, if not enabled by ObjectLineArt, then it's set to global. */
|
||||
float crease_threshold;
|
||||
} LineartRenderElementLinkNode;
|
||||
|
||||
typedef struct LineartRenderLineSegment {
|
||||
struct LineartRenderLineSegment *next, *prev;
|
||||
/** at==0: left at==1: right (this is in 2D projected space) */
|
||||
double at;
|
||||
/** Occlusion level after "at" point */
|
||||
unsigned char occlusion;
|
||||
|
||||
/** For determining lines beind a glass window material.
|
||||
* the size of this variable should also be dynamically decided, 1 byte to 8 byte,
|
||||
* allows 8 to 64 materials for "transparent mask". 1 byte (8 materials) should be
|
||||
* enought for most cases.
|
||||
*/
|
||||
unsigned char transparency_mask;
|
||||
} LineartRenderLineSegment;
|
||||
|
||||
typedef struct LineartRenderVert {
|
||||
double gloc[3];
|
||||
double fbcoord[4];
|
||||
|
||||
int index;
|
||||
|
||||
/** Intersection data flag is here, when LRT_VERT_HAS_INTERSECTION_DATA is set,
|
||||
* size of the struct is extended to include intersection data.
|
||||
* See eLineArtVertFlags.
|
||||
*/
|
||||
char flag;
|
||||
|
||||
} LineartRenderVert;
|
||||
|
||||
typedef struct LineartRenderVertIntersection {
|
||||
struct LineartRenderVert base;
|
||||
/* Use vert index because we only use this to check vertex equal. This way we save 8 Bytes. */
|
||||
int isec1, isec2;
|
||||
struct LineartRenderTriangle *intersecting_with;
|
||||
} LineartRenderVertIntersection;
|
||||
|
||||
typedef enum eLineArtVertFlags {
|
||||
LRT_VERT_HAS_INTERSECTION_DATA = (1 << 0),
|
||||
LRT_VERT_EDGE_USED = (1 << 1),
|
||||
} eLineArtVertFlags;
|
||||
|
||||
typedef struct LineartRenderLine {
|
||||
/* We only need link node kind of list here. */
|
||||
struct LineartRenderLine *next;
|
||||
struct LineartRenderVert *l, *r;
|
||||
/* Local vertex index for two ends, not puting in RenderVert because all verts are loaded, so as
|
||||
* long as fewer than half of the mesh edges are becoming a feature line, we save more memory. */
|
||||
int l_obindex, r_obindex;
|
||||
struct LineartRenderTriangle *tl, *tr;
|
||||
ListBase segments;
|
||||
char min_occ;
|
||||
|
||||
/** Also for line type determination on chainning */
|
||||
unsigned char flags;
|
||||
|
||||
/** Still need this entry because culled lines will not add to object reln node,
|
||||
* TODO: If really need more savings, we can allocate this in a "extended" way too, but we need
|
||||
* another bit in flags to be able to show the difference.
|
||||
*/
|
||||
struct Object *object_ref;
|
||||
} LineartRenderLine;
|
||||
|
||||
typedef struct LineartRenderLineChain {
|
||||
struct LineartRenderLineChain *next, *prev;
|
||||
ListBase chain;
|
||||
|
||||
/** Calculated before draw cmd. */
|
||||
float length;
|
||||
|
||||
/** Used when re-connecting and gp stroke generation */
|
||||
char picked;
|
||||
char level;
|
||||
|
||||
/** Chain now only contains one type of segments */
|
||||
int type;
|
||||
unsigned char transparency_mask;
|
||||
|
||||
struct Object *object_ref;
|
||||
} LineartRenderLineChain;
|
||||
|
||||
typedef struct LineartRenderLineChainItem {
|
||||
struct LineartRenderLineChainItem *next, *prev;
|
||||
/** Need z value for fading */
|
||||
float pos[3];
|
||||
/** For restoring position to 3d space */
|
||||
float gpos[3];
|
||||
float normal[3];
|
||||
char line_type;
|
||||
char occlusion;
|
||||
unsigned char transparency_mask;
|
||||
size_t index;
|
||||
} LineartRenderLineChainItem;
|
||||
|
||||
typedef struct LineartChainRegisterEntry {
|
||||
struct LineartChainRegisterEntry *next, *prev;
|
||||
LineartRenderLineChain *rlc;
|
||||
LineartRenderLineChainItem *rlci;
|
||||
char picked;
|
||||
|
||||
/** left/right mark.
|
||||
* Because we revert list in chaining so we need the flag. */
|
||||
char is_left;
|
||||
} LineartChainRegisterEntry;
|
||||
|
||||
typedef struct LineartRenderBuffer {
|
||||
struct LineartRenderBuffer *prev, *next;
|
||||
|
||||
/** For render. */
|
||||
int is_copied;
|
||||
|
||||
int w, h;
|
||||
int tile_size_w, tile_size_h;
|
||||
int tile_count_x, tile_count_y;
|
||||
double width_per_tile, height_per_tile;
|
||||
double view_projection[4][4];
|
||||
|
||||
int output_mode;
|
||||
int output_aa_level;
|
||||
|
||||
struct LineartBoundingArea *initial_bounding_areas;
|
||||
unsigned int bounding_area_count;
|
||||
|
||||
ListBase vertex_buffer_pointers;
|
||||
ListBase line_buffer_pointers;
|
||||
ListBase triangle_buffer_pointers;
|
||||
|
||||
/* This one's memory is not from main pool and is free()ed after culling stage. */
|
||||
ListBase triangle_adjacent_pointers;
|
||||
|
||||
ListBase intersecting_vertex_buffer;
|
||||
/** Use the one comes with Line Art. */
|
||||
LineartStaticMemPool render_data_pool;
|
||||
ListBase wasted_cuts;
|
||||
SpinLock lock_cuts;
|
||||
|
||||
struct Material *material_pointers[2048];
|
||||
|
||||
/* Render status */
|
||||
double view_vector[3];
|
||||
|
||||
int triangle_size;
|
||||
|
||||
unsigned int contour_count;
|
||||
unsigned int contour_processed;
|
||||
LineartRenderLine *contour_managed;
|
||||
/* Now changed to linknodes. */
|
||||
LineartRenderLine *contours;
|
||||
|
||||
unsigned int intersection_count;
|
||||
unsigned int intersection_processed;
|
||||
LineartRenderLine *intersection_managed;
|
||||
LineartRenderLine *intersection_lines;
|
||||
|
||||
unsigned int crease_count;
|
||||
unsigned int crease_processed;
|
||||
LineartRenderLine *crease_managed;
|
||||
LineartRenderLine *crease_lines;
|
||||
|
||||
unsigned int material_line_count;
|
||||
unsigned int material_processed;
|
||||
LineartRenderLine *material_managed;
|
||||
LineartRenderLine *material_lines;
|
||||
|
||||
unsigned int edge_mark_count;
|
||||
unsigned int edge_mark_processed;
|
||||
LineartRenderLine *edge_mark_managed;
|
||||
LineartRenderLine *edge_marks;
|
||||
|
||||
ListBase chains;
|
||||
|
||||
/** For managing calculation tasks for multiple threads. */
|
||||
SpinLock lock_task;
|
||||
|
||||
/* settings */
|
||||
|
||||
int max_occlusion_level;
|
||||
double crease_angle;
|
||||
double crease_cos;
|
||||
int thread_count;
|
||||
|
||||
int draw_material_preview;
|
||||
double material_transparency;
|
||||
|
||||
bool use_contour;
|
||||
bool use_crease;
|
||||
bool use_material;
|
||||
bool use_edge_marks;
|
||||
bool use_intersections;
|
||||
bool fuzzy_intersections;
|
||||
bool fuzzy_everything;
|
||||
bool allow_boundaries;
|
||||
bool remove_doubles;
|
||||
|
||||
/** Keep an copy of these data so the scene can be freed when lineart is runnning. */
|
||||
bool cam_is_persp;
|
||||
float cam_obmat[4][4];
|
||||
double camera_pos[3];
|
||||
double near_clip, far_clip;
|
||||
float shift_x, shift_y;
|
||||
float crease_threshold;
|
||||
float chaining_image_threshold;
|
||||
float chaining_geometry_threshold;
|
||||
float angle_splitting_threshold;
|
||||
} LineartRenderBuffer;
|
||||
|
||||
typedef enum eLineartRenderStatus {
|
||||
LRT_RENDER_IDLE = 0,
|
||||
LRT_RENDER_RUNNING = 1,
|
||||
LRT_RENDER_INCOMPELTE = 2, /* Not used yet. */
|
||||
LRT_RENDER_FINISHED = 3,
|
||||
LRT_RENDER_CANCELING = 4,
|
||||
} eLineartRenderStatus;
|
||||
|
||||
typedef enum eLineartInitStatus {
|
||||
LRT_INIT_ENGINE = (1 << 0),
|
||||
LRT_INIT_LOCKS = (1 << 1),
|
||||
} eLineartInitStatus;
|
||||
|
||||
typedef enum eLineartModifierSyncStatus {
|
||||
LRT_SYNC_IDLE = 0,
|
||||
LRT_SYNC_WAITING = 1,
|
||||
LRT_SYNC_FRESH = 2,
|
||||
LRT_SYNC_IGNORE = 3,
|
||||
LRT_SYNC_CLEARING = 4,
|
||||
} eLineartModifierSyncStatus;
|
||||
|
||||
typedef struct LineartSharedResource {
|
||||
|
||||
/* We only allocate once for all */
|
||||
LineartRenderBuffer *render_buffer_shared;
|
||||
|
||||
/* Don't put this in render buffer as the checker function doesn't have rb pointer, this design
|
||||
* is for performance. */
|
||||
char allow_overlapping_edges;
|
||||
|
||||
/* cache */
|
||||
struct BLI_mempool *mp_sample;
|
||||
struct BLI_mempool *mp_line_strip;
|
||||
struct BLI_mempool *mp_line_strip_point;
|
||||
struct BLI_mempool *mp_batch_list;
|
||||
|
||||
struct TaskPool *background_render_task;
|
||||
struct TaskPool *pending_render_task;
|
||||
|
||||
eLineartInitStatus init_complete;
|
||||
|
||||
/** To bypass or cancel rendering.
|
||||
* This status flag should be kept in lineart_share not render_buffer,
|
||||
* because render_buffer will get re-initialized every frame.
|
||||
*/
|
||||
SpinLock lock_render_status;
|
||||
eLineartRenderStatus flag_render_status;
|
||||
eLineartModifierSyncStatus flag_sync_staus;
|
||||
/** count of pending modifiers that is waiting for the data. */
|
||||
int customers;
|
||||
|
||||
int thread_count;
|
||||
|
||||
/** To determine whether all threads are completely canceled. Each thread add 1 into this value
|
||||
* before return, until it reaches thread count. Not needed for the implementation at the moment
|
||||
* as occlusion thread is work-and-wait, preserved for future usages. */
|
||||
int canceled_thread_accumulator;
|
||||
|
||||
/** Geometry loading is done in the worker thread,
|
||||
* Lock the render thread until loading is done, so that
|
||||
* we can avoid depsgrapgh deleting the scene before
|
||||
* LRT finishes loading. Also keep this in lineart_share.
|
||||
*/
|
||||
SpinLock lock_loader;
|
||||
|
||||
/** When drawing in the viewport, use the following values. */
|
||||
/** Set to override to -1 before creating lineart render buffer to use scene camera. */
|
||||
int viewport_camera_override;
|
||||
char camera_is_persp;
|
||||
float camera_pos[3];
|
||||
float near_clip, far_clip;
|
||||
float viewinv[4][4];
|
||||
float persp[4][4];
|
||||
float viewquat[4];
|
||||
|
||||
/* Use these to set cursor and progress. */
|
||||
wmWindowManager *wm;
|
||||
wmWindow *main_window;
|
||||
} LineartSharedResource;
|
||||
|
||||
#define DBL_TRIANGLE_LIM 1e-8
|
||||
#define DBL_EDGE_LIM 1e-9
|
||||
|
||||
#define LRT_MEMORY_POOL_64MB (1 << 26)
|
||||
|
||||
typedef enum eLineartTriangleFlags {
|
||||
LRT_CULL_DONT_CARE = 0,
|
||||
LRT_CULL_USED = (1 << 0),
|
||||
LRT_CULL_DISCARD = (1 << 1),
|
||||
LRT_CULL_GENERATED = (1 << 2),
|
||||
LRT_TRIANGLE_INTERSECTION_ONLY = (1 << 3),
|
||||
LRT_TRIANGLE_NO_INTERSECTION = (1 << 4),
|
||||
} eLineartTriangleFlags;
|
||||
|
||||
/** Controls how many lines a worker thread is processing at one request.
|
||||
* There's no significant performance impact on choosing different values.
|
||||
* Don't make it too small so that the worker thread won't request too many times. */
|
||||
#define LRT_THREAD_LINE_COUNT 1000
|
||||
|
||||
typedef struct LineartRenderTaskInfo {
|
||||
int thread_id;
|
||||
|
||||
LineartRenderLine *contour;
|
||||
LineartRenderLine *contour_end;
|
||||
|
||||
LineartRenderLine *intersection;
|
||||
LineartRenderLine *intersection_end;
|
||||
|
||||
LineartRenderLine *crease;
|
||||
LineartRenderLine *crease_end;
|
||||
|
||||
LineartRenderLine *material;
|
||||
LineartRenderLine *material_end;
|
||||
|
||||
LineartRenderLine *edge_mark;
|
||||
LineartRenderLine *edge_mark_end;
|
||||
|
||||
} LineartRenderTaskInfo;
|
||||
|
||||
/** Bounding area diagram:
|
||||
*
|
||||
* +----+ <----U (Upper edge Y value)
|
||||
* | |
|
||||
* +----+ <----B (Bottom edge Y value)
|
||||
* ^ ^
|
||||
* L R (Left/Right edge X value)
|
||||
*
|
||||
* Example structure when subdividing 1 bounding areas:
|
||||
* 1 area can be divided into 4 smaller children to
|
||||
* accomodate image areas with denser triangle distribution.
|
||||
* +--+--+-----+
|
||||
* +--+--+ |
|
||||
* +--+--+-----+
|
||||
* | | |
|
||||
* +-----+-----+
|
||||
* lp/rp/up/bp is the list for
|
||||
* storing pointers to adjacent bounding areas.
|
||||
*/
|
||||
typedef struct LineartBoundingArea {
|
||||
double l, r, u, b;
|
||||
double cx, cy;
|
||||
|
||||
/** 1,2,3,4 quadrant */
|
||||
struct LineartBoundingArea *child;
|
||||
|
||||
ListBase lp;
|
||||
ListBase rp;
|
||||
ListBase up;
|
||||
ListBase bp;
|
||||
|
||||
short triangle_count;
|
||||
|
||||
ListBase linked_triangles;
|
||||
ListBase linked_lines;
|
||||
|
||||
/** Reserved for image space reduction && multithread chainning */
|
||||
ListBase linked_chains;
|
||||
} LineartBoundingArea;
|
||||
|
||||
#define LRT_TILE(tile, r, c, CCount) tile[r * CCount + c]
|
||||
|
||||
#define LRT_CLAMP(a, Min, Max) a = a < Min ? Min : (a > Max ? Max : a)
|
||||
|
||||
#define LRT_MAX3_INDEX(a, b, c) (a > b ? (a > c ? 0 : (b > c ? 1 : 2)) : (b > c ? 1 : 2))
|
||||
|
||||
#define LRT_MIN3_INDEX(a, b, c) (a < b ? (a < c ? 0 : (b < c ? 1 : 2)) : (b < c ? 1 : 2))
|
||||
|
||||
#define LRT_MAX3_INDEX_ABC(x, y, z) (x > y ? (x > z ? a : (y > z ? b : c)) : (y > z ? b : c))
|
||||
|
||||
#define LRT_MIN3_INDEX_ABC(x, y, z) (x < y ? (x < z ? a : (y < z ? b : c)) : (y < z ? b : c))
|
||||
|
||||
#define LRT_ABC(index) (index == 0 ? a : (index == 1 ? b : c))
|
||||
|
||||
#define LRT_DOUBLE_CLOSE_ENOUGH(a, b) (((a) + DBL_EDGE_LIM) >= (b) && ((a)-DBL_EDGE_LIM) <= (b))
|
||||
|
||||
BLI_INLINE int lineart_LineIntersectTest2d(
|
||||
const double *a1, const double *a2, const double *b1, const double *b2, double *aRatio)
|
||||
{
|
||||
#define USE_VECTOR_LINE_INTERSECTION
|
||||
#ifdef USE_VECTOR_LINE_INTERSECTION
|
||||
|
||||
/* from isect_line_line_v2_point() */
|
||||
|
||||
double s10[2], s32[2];
|
||||
double div;
|
||||
|
||||
sub_v2_v2v2_db(s10, a2, a1);
|
||||
sub_v2_v2v2_db(s32, b2, b1);
|
||||
|
||||
div = cross_v2v2_db(s10, s32);
|
||||
if (div != 0.0f) {
|
||||
const double u = cross_v2v2_db(a2, a1);
|
||||
const double v = cross_v2v2_db(b2, b1);
|
||||
|
||||
const double rx = ((s32[0] * u) - (s10[0] * v)) / div;
|
||||
const double ry = ((s32[1] * u) - (s10[1] * v)) / div;
|
||||
double rr;
|
||||
|
||||
if (fabs(a2[0] - a1[0]) > fabs(a2[1] - a1[1])) {
|
||||
*aRatio = ratiod(a1[0], a2[0], rx);
|
||||
if (fabs(b2[0] - b1[0]) > fabs(b2[1] - b1[1])) {
|
||||
rr = ratiod(b1[0], b2[0], rx);
|
||||
}
|
||||
else {
|
||||
rr = ratiod(b1[1], b2[1], ry);
|
||||
}
|
||||
if ((*aRatio) > 0 && (*aRatio) < 1 && rr > 0 && rr < 1) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
*aRatio = ratiod(a1[1], a2[1], ry);
|
||||
if (fabs(b2[0] - b1[0]) > fabs(b2[1] - b1[1])) {
|
||||
rr = ratiod(b1[0], b2[0], rx);
|
||||
}
|
||||
else {
|
||||
rr = ratiod(b1[1], b2[1], ry);
|
||||
}
|
||||
if ((*aRatio) > 0 && (*aRatio) < 1 && rr > 0 && rr < 1) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
#else
|
||||
double k1, k2;
|
||||
double x;
|
||||
double y;
|
||||
double ratio;
|
||||
double x_diff = (a2[0] - a1[0]);
|
||||
double x_diff2 = (b2[0] - b1[0]);
|
||||
|
||||
if (LRT_DOUBLE_CLOSE_ENOUGH(x_diff, 0)) {
|
||||
if (LRT_DOUBLE_CLOSE_ENOUGH(x_diff2, 0)) {
|
||||
*aRatio = 0;
|
||||
return 0;
|
||||
}
|
||||
double r2 = ratiod(b1[0], b2[0], a1[0]);
|
||||
x = interpd(b2[0], b1[0], r2);
|
||||
y = interpd(b2[1], b1[1], r2);
|
||||
*aRatio = ratio = ratiod(a1[1], a2[1], y);
|
||||
}
|
||||
else {
|
||||
if (LRT_DOUBLE_CLOSE_ENOUGH(x_diff2, 0)) {
|
||||
ratio = ratiod(a1[0], a2[0], b1[0]);
|
||||
x = interpd(a2[0], a1[0], ratio);
|
||||
*aRatio = ratio;
|
||||
}
|
||||
else {
|
||||
k1 = (a2[1] - a1[1]) / x_diff;
|
||||
k2 = (b2[1] - b1[1]) / x_diff2;
|
||||
|
||||
if ((k1 == k2))
|
||||
return 0;
|
||||
|
||||
x = (a1[1] - b1[1] - k1 * a1[0] + k2 * b1[0]) / (k2 - k1);
|
||||
|
||||
ratio = (x - a1[0]) / x_diff;
|
||||
|
||||
*aRatio = ratio;
|
||||
}
|
||||
}
|
||||
|
||||
if (LRT_DOUBLE_CLOSE_ENOUGH(b1[0], b2[0])) {
|
||||
y = interpd(a2[1], a1[1], ratio);
|
||||
if (y > MAX2(b1[1], b2[1]) || y < MIN2(b1[1], b2[1]))
|
||||
return 0;
|
||||
}
|
||||
else if (ratio <= 0 || ratio > 1 || (b1[0] > b2[0] && x > b1[0]) ||
|
||||
(b1[0] < b2[0] && x < b1[0]) || (b2[0] > b1[0] && x > b2[0]) ||
|
||||
(b2[0] < b1[0] && x < b2[0]))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ED_lineart_point_inside_triangled(double v[2], double v0[2], double v1[2], double v2[2]);
|
||||
|
||||
struct Depsgraph;
|
||||
struct SceneLineArt;
|
||||
struct Scene;
|
||||
struct LineartRenderBuffer;
|
||||
|
||||
void ED_lineart_init_locks(void);
|
||||
struct LineartRenderBuffer *ED_lineart_create_render_buffer(struct Scene *s);
|
||||
void ED_lineart_destroy_render_data(void);
|
||||
void ED_lineart_destroy_render_data_external(void);
|
||||
|
||||
int ED_lineart_object_collection_usage_check(struct Collection *c, struct Object *o);
|
||||
|
||||
void ED_lineart_chain_feature_lines(LineartRenderBuffer *rb);
|
||||
void ED_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb);
|
||||
void ED_lineart_chain_connect(LineartRenderBuffer *rb, const int do_geometry_space);
|
||||
void ED_lineart_chain_discard_short(LineartRenderBuffer *rb, const float threshold);
|
||||
void ED_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshold_rad);
|
||||
|
||||
int ED_lineart_chain_count(const LineartRenderLineChain *rlc);
|
||||
void ED_lineart_chain_clear_picked_flag(struct LineartRenderBuffer *rb);
|
||||
|
||||
void ED_lineart_calculation_flag_set(eLineartRenderStatus flag);
|
||||
bool ED_lineart_calculation_flag_check(eLineartRenderStatus flag);
|
||||
|
||||
void ED_lineart_modifier_sync_flag_set(eLineartModifierSyncStatus flag, bool is_from_modifier);
|
||||
bool ED_lineart_modifier_sync_flag_check(eLineartModifierSyncStatus flag);
|
||||
void ED_lineart_modifier_sync_add_customer(void);
|
||||
void ED_lineart_modifier_sync_remove_customer(void);
|
||||
bool ED_lineart_modifier_sync_still_has_customer(void);
|
||||
|
||||
int ED_lineart_compute_feature_lines_internal(struct Depsgraph *depsgraph,
|
||||
const int show_frame_progress);
|
||||
|
||||
void ED_lineart_compute_feature_lines_background(struct Depsgraph *dg,
|
||||
const int show_frame_progress);
|
||||
|
||||
struct Scene;
|
||||
|
||||
LineartBoundingArea *ED_lineart_get_point_bounding_area(LineartRenderBuffer *rb,
|
||||
double x,
|
||||
double y);
|
||||
|
||||
LineartBoundingArea *ED_lineart_get_point_bounding_area_deep(LineartRenderBuffer *rb,
|
||||
double x,
|
||||
double y);
|
||||
|
||||
struct bGPDlayer;
|
||||
struct bGPDframe;
|
||||
struct GpencilModifierData;
|
||||
|
||||
void ED_lineart_gpencil_generate(struct Depsgraph *depsgraph,
|
||||
Object *gpencil_object,
|
||||
float (*gp_obmat_inverse)[4],
|
||||
struct bGPDlayer *UNUSED(gpl),
|
||||
struct bGPDframe *gpf,
|
||||
int level_start,
|
||||
int level_end,
|
||||
int material_nr,
|
||||
struct Object *source_object,
|
||||
struct Collection *source_collection,
|
||||
int types,
|
||||
unsigned char transparency_flags,
|
||||
unsigned char transparency_mask,
|
||||
short thickness,
|
||||
float opacity,
|
||||
float pre_sample_length,
|
||||
const char *source_vgname,
|
||||
const char *vgname,
|
||||
int modifier_flags);
|
||||
|
||||
void ED_lineart_gpencil_generate_with_type(struct Depsgraph *depsgraph,
|
||||
struct Object *ob,
|
||||
struct bGPDlayer *gpl,
|
||||
struct bGPDframe *gpf,
|
||||
char source_type,
|
||||
void *source_reference,
|
||||
int level_start,
|
||||
int level_end,
|
||||
int mat_nr,
|
||||
short line_types,
|
||||
unsigned char transparency_flags,
|
||||
unsigned char transparency_mask,
|
||||
short thickness,
|
||||
float opacity,
|
||||
float pre_sample_length,
|
||||
const char *source_vgname,
|
||||
const char *vgname,
|
||||
int modifier_flags);
|
||||
|
||||
struct bContext;
|
||||
|
||||
void ED_lineart_post_frame_update_external(struct bContext *C,
|
||||
struct Scene *s,
|
||||
struct Depsgraph *dg,
|
||||
bool from_modifier);
|
||||
|
||||
struct SceneLineArt;
|
||||
|
||||
void ED_lineart_update_render_progress(int nr, const char *info);
|
||||
|
||||
float ED_lineart_chain_compute_length(LineartRenderLineChain *rlc);
|
||||
|
||||
struct wmOperatorType;
|
||||
|
||||
/* Operator types */
|
||||
void SCENE_OT_lineart_update_strokes(struct wmOperatorType *ot);
|
||||
void SCENE_OT_lineart_bake_strokes(struct wmOperatorType *ot);
|
||||
|
||||
void ED_operatortypes_lineart(void);
|
46
source/blender/editors/lineart/CMakeLists.txt
Normal file
46
source/blender/editors/lineart/CMakeLists.txt
Normal file
@@ -0,0 +1,46 @@
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
set(INC
|
||||
../include
|
||||
../../blenkernel
|
||||
../../blenlib
|
||||
../../bmesh
|
||||
../../depsgraph
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../windowmanager
|
||||
../../../../intern/guardedalloc
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
|
||||
)
|
||||
|
||||
set(SRC
|
||||
lineart_ops.c
|
||||
lineart_cpu.c
|
||||
lineart_chain.c
|
||||
lineart_util.c
|
||||
|
||||
lineart_intern.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
)
|
||||
|
||||
blender_add_lib(bf_editor_lineart "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
984
source/blender/editors/lineart/lineart_chain.c
Normal file
984
source/blender/editors/lineart/lineart_chain.c
Normal file
@@ -0,0 +1,984 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_lineart_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "ED_lineart.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
#include "lineart_intern.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define LRT_OTHER_RV(rl, rv) ((rv) == (rl)->l ? (rl)->r : (rl)->l)
|
||||
|
||||
static LineartRenderLine *lineart_line_get_connected(LineartBoundingArea *ba,
|
||||
LineartRenderVert *rv,
|
||||
LineartRenderVert **new_rv,
|
||||
int match_flag)
|
||||
{
|
||||
LineartRenderLine *nrl;
|
||||
|
||||
LISTBASE_FOREACH (LinkData *, lip, &ba->linked_lines) {
|
||||
nrl = lip->data;
|
||||
|
||||
if ((!(nrl->flags & LRT_EDGE_FLAG_ALL_TYPE)) || (nrl->flags & LRT_EDGE_FLAG_CHAIN_PICKED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (match_flag && ((nrl->flags & LRT_EDGE_FLAG_ALL_TYPE) & match_flag) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* always chain connected lines for now. */
|
||||
/* simplification will take care of the sharp points. */
|
||||
|
||||
if (rv != nrl->l && rv != nrl->r) {
|
||||
if (nrl->flags & LRT_EDGE_FLAG_INTERSECTION) {
|
||||
if (rv->fbcoord[0] == nrl->l->fbcoord[0] && rv->fbcoord[1] == nrl->l->fbcoord[1]) {
|
||||
*new_rv = LRT_OTHER_RV(nrl, nrl->l);
|
||||
return nrl;
|
||||
}
|
||||
else {
|
||||
if (rv->fbcoord[0] == nrl->r->fbcoord[0] && rv->fbcoord[1] == nrl->r->fbcoord[1]) {
|
||||
*new_rv = LRT_OTHER_RV(nrl, nrl->r);
|
||||
return nrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
*new_rv = LRT_OTHER_RV(nrl, rv);
|
||||
return nrl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static LineartRenderLineChain *lineart_chain_create(LineartRenderBuffer *rb)
|
||||
{
|
||||
LineartRenderLineChain *rlc;
|
||||
rlc = lineart_mem_aquire(&rb->render_data_pool, sizeof(LineartRenderLineChain));
|
||||
|
||||
BLI_addtail(&rb->chains, rlc);
|
||||
|
||||
return rlc;
|
||||
}
|
||||
|
||||
static bool lineart_point_overlapping(LineartRenderLineChainItem *rlci,
|
||||
float x,
|
||||
float y,
|
||||
double threshold)
|
||||
{
|
||||
if (!rlci) {
|
||||
return false;
|
||||
}
|
||||
if (((rlci->pos[0] + threshold) >= x) && ((rlci->pos[0] - threshold) <= x) &&
|
||||
((rlci->pos[1] + threshold) >= y) && ((rlci->pos[1] - threshold) <= y)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static LineartRenderLineChainItem *lineart_chain_append_point(LineartRenderBuffer *rb,
|
||||
LineartRenderLineChain *rlc,
|
||||
float *fbcoord,
|
||||
float *gpos,
|
||||
float *normal,
|
||||
char type,
|
||||
int level,
|
||||
unsigned char transparency_mask,
|
||||
size_t index)
|
||||
{
|
||||
LineartRenderLineChainItem *rlci;
|
||||
|
||||
if (lineart_point_overlapping(rlc->chain.last, fbcoord[0], fbcoord[1], 1e-5)) {
|
||||
/* Because segment type is determined by the leading chain point, so we need to ensure the
|
||||
* type and occlusion is correct after omitting overlapping point*/
|
||||
LineartRenderLineChainItem *old_rlci = rlc->chain.last;
|
||||
old_rlci->line_type = type;
|
||||
old_rlci->occlusion = level;
|
||||
return old_rlci;
|
||||
}
|
||||
|
||||
rlci = lineart_mem_aquire(&rb->render_data_pool, sizeof(LineartRenderLineChainItem));
|
||||
|
||||
copy_v2_v2(rlci->pos, fbcoord);
|
||||
copy_v3_v3(rlci->gpos, gpos);
|
||||
rlci->index = index;
|
||||
copy_v3_v3(rlci->normal, normal);
|
||||
rlci->line_type = type & LRT_EDGE_FLAG_ALL_TYPE;
|
||||
rlci->occlusion = level;
|
||||
rlci->transparency_mask = transparency_mask;
|
||||
BLI_addtail(&rlc->chain, rlci);
|
||||
|
||||
return rlci;
|
||||
}
|
||||
|
||||
static LineartRenderLineChainItem *lineart_chain_push_point(LineartRenderBuffer *rb,
|
||||
LineartRenderLineChain *rlc,
|
||||
float *fbcoord,
|
||||
float *gpos,
|
||||
float *normal,
|
||||
char type,
|
||||
int level,
|
||||
unsigned char transparency_mask,
|
||||
size_t index)
|
||||
{
|
||||
LineartRenderLineChainItem *rlci;
|
||||
|
||||
if (lineart_point_overlapping(rlc->chain.first, fbcoord[0], fbcoord[1], 1e-5)) {
|
||||
return rlc->chain.first;
|
||||
}
|
||||
|
||||
rlci = lineart_mem_aquire(&rb->render_data_pool, sizeof(LineartRenderLineChainItem));
|
||||
|
||||
copy_v2_v2(rlci->pos, fbcoord);
|
||||
copy_v3_v3(rlci->gpos, gpos);
|
||||
rlci->index = index;
|
||||
copy_v3_v3(rlci->normal, normal);
|
||||
rlci->line_type = type & LRT_EDGE_FLAG_ALL_TYPE;
|
||||
rlci->occlusion = level;
|
||||
rlci->transparency_mask = transparency_mask;
|
||||
BLI_addhead(&rlc->chain, rlci);
|
||||
|
||||
return rlci;
|
||||
}
|
||||
|
||||
void ED_lineart_chain_feature_lines(LineartRenderBuffer *rb)
|
||||
{
|
||||
LineartRenderLineChain *rlc;
|
||||
LineartRenderLineChainItem *rlci;
|
||||
LineartBoundingArea *ba;
|
||||
LineartRenderLineSegment *rls;
|
||||
int last_occlusion;
|
||||
unsigned char last_transparency;
|
||||
/* for converting from double */
|
||||
float use_fbcoord[2];
|
||||
float use_gpos[3];
|
||||
|
||||
#define VERT_COORD_TO_FLOAT(a) \
|
||||
copy_v2fl_v2db(use_fbcoord, (a)->fbcoord); \
|
||||
copy_v3fl_v3db(use_gpos, (a)->gloc);
|
||||
|
||||
#define POS_TO_FLOAT(lpos, gpos) \
|
||||
copy_v2fl_v2db(use_fbcoord, lpos); \
|
||||
copy_v3fl_v3db(use_gpos, gpos);
|
||||
|
||||
LRT_ITER_ALL_LINES_BEGIN
|
||||
{
|
||||
if ((!(rl->flags & LRT_EDGE_FLAG_ALL_TYPE)) || (rl->flags & LRT_EDGE_FLAG_CHAIN_PICKED)) {
|
||||
LRT_ITER_ALL_LINES_NEXT
|
||||
continue;
|
||||
}
|
||||
|
||||
rl->flags |= LRT_EDGE_FLAG_CHAIN_PICKED;
|
||||
|
||||
rlc = lineart_chain_create(rb);
|
||||
|
||||
rlc->object_ref = rl->object_ref; /* can only be the same object in a chain. */
|
||||
|
||||
LineartRenderLine *new_rl = rl;
|
||||
LineartRenderVert *new_rv;
|
||||
float N[3] = {0};
|
||||
|
||||
if (rl->tl) {
|
||||
N[0] += rl->tl->gn[0];
|
||||
N[1] += rl->tl->gn[1];
|
||||
N[2] += rl->tl->gn[2];
|
||||
}
|
||||
if (rl->tr) {
|
||||
N[0] += rl->tr->gn[0];
|
||||
N[1] += rl->tr->gn[1];
|
||||
N[2] += rl->tr->gn[2];
|
||||
}
|
||||
if (rl->tl || rl->tr) {
|
||||
normalize_v3(N);
|
||||
}
|
||||
|
||||
/* step 1: grow left. */
|
||||
ba = ED_lineart_get_point_bounding_area_deep(rb, rl->l->fbcoord[0], rl->l->fbcoord[1]);
|
||||
new_rv = rl->l;
|
||||
rls = rl->segments.first;
|
||||
VERT_COORD_TO_FLOAT(new_rv);
|
||||
lineart_chain_push_point(rb,
|
||||
rlc,
|
||||
use_fbcoord,
|
||||
use_gpos,
|
||||
N,
|
||||
rl->flags,
|
||||
rls->occlusion,
|
||||
rls->transparency_mask,
|
||||
rl->l_obindex);
|
||||
while (ba && (new_rl = lineart_line_get_connected(ba, new_rv, &new_rv, rl->flags))) {
|
||||
new_rl->flags |= LRT_EDGE_FLAG_CHAIN_PICKED;
|
||||
|
||||
if (new_rl->tl || new_rl->tr) {
|
||||
zero_v3(N);
|
||||
if (new_rl->tl) {
|
||||
N[0] += new_rl->tl->gn[0];
|
||||
N[1] += new_rl->tl->gn[1];
|
||||
N[2] += new_rl->tl->gn[2];
|
||||
}
|
||||
if (new_rl->tr) {
|
||||
N[0] += new_rl->tr->gn[0];
|
||||
N[1] += new_rl->tr->gn[1];
|
||||
N[2] += new_rl->tr->gn[2];
|
||||
}
|
||||
normalize_v3(N);
|
||||
}
|
||||
|
||||
if (new_rv == new_rl->l) {
|
||||
for (rls = new_rl->segments.last; rls; rls = rls->prev) {
|
||||
double gpos[3], lpos[3];
|
||||
double *lfb = new_rl->l->fbcoord, *rfb = new_rl->r->fbcoord;
|
||||
double global_at = lfb[3] * rls->at / (rls->at * lfb[3] + (1 - rls->at) * rfb[3]);
|
||||
interp_v3_v3v3_db(lpos, new_rl->l->fbcoord, new_rl->r->fbcoord, rls->at);
|
||||
interp_v3_v3v3_db(gpos, new_rl->l->gloc, new_rl->r->gloc, global_at);
|
||||
POS_TO_FLOAT(lpos, gpos)
|
||||
lineart_chain_push_point(rb,
|
||||
rlc,
|
||||
use_fbcoord,
|
||||
use_gpos,
|
||||
N,
|
||||
new_rl->flags,
|
||||
rls->occlusion,
|
||||
rls->transparency_mask,
|
||||
new_rl->l_obindex);
|
||||
last_occlusion = rls->occlusion;
|
||||
last_transparency = rls->transparency_mask;
|
||||
}
|
||||
}
|
||||
else if (new_rv == new_rl->r) {
|
||||
rls = new_rl->segments.first;
|
||||
last_occlusion = rls->occlusion;
|
||||
last_transparency = rls->transparency_mask;
|
||||
rls = rls->next;
|
||||
for (; rls; rls = rls->next) {
|
||||
double gpos[3], lpos[3];
|
||||
double *lfb = new_rl->l->fbcoord, *rfb = new_rl->r->fbcoord;
|
||||
double global_at = lfb[3] * rls->at / (rls->at * lfb[3] + (1 - rls->at) * rfb[3]);
|
||||
interp_v3_v3v3_db(lpos, new_rl->l->fbcoord, new_rl->r->fbcoord, rls->at);
|
||||
interp_v3_v3v3_db(gpos, new_rl->l->gloc, new_rl->r->gloc, global_at);
|
||||
POS_TO_FLOAT(lpos, gpos)
|
||||
lineart_chain_push_point(rb,
|
||||
rlc,
|
||||
use_fbcoord,
|
||||
use_gpos,
|
||||
N,
|
||||
new_rl->flags,
|
||||
last_occlusion,
|
||||
last_transparency,
|
||||
new_rl->r_obindex);
|
||||
last_occlusion = rls->occlusion;
|
||||
last_transparency = rls->transparency_mask;
|
||||
}
|
||||
VERT_COORD_TO_FLOAT(new_rl->r);
|
||||
lineart_chain_push_point(rb,
|
||||
rlc,
|
||||
use_fbcoord,
|
||||
use_gpos,
|
||||
N,
|
||||
new_rl->flags,
|
||||
last_occlusion,
|
||||
last_transparency,
|
||||
new_rl->r_obindex);
|
||||
}
|
||||
ba = ED_lineart_get_point_bounding_area_deep(rb, new_rv->fbcoord[0], new_rv->fbcoord[1]);
|
||||
}
|
||||
|
||||
/* Restore normal value. */
|
||||
if (rl->tl || rl->tr) {
|
||||
zero_v3(N);
|
||||
if (rl->tl) {
|
||||
N[0] += rl->tl->gn[0];
|
||||
N[1] += rl->tl->gn[1];
|
||||
N[2] += rl->tl->gn[2];
|
||||
}
|
||||
if (rl->tr) {
|
||||
N[0] += rl->tr->gn[0];
|
||||
N[1] += rl->tr->gn[1];
|
||||
N[2] += rl->tr->gn[2];
|
||||
}
|
||||
normalize_v3(N);
|
||||
}
|
||||
/* step 2: this line. */
|
||||
rls = rl->segments.first;
|
||||
last_occlusion = ((LineartRenderLineSegment *)rls)->occlusion;
|
||||
last_transparency = ((LineartRenderLineSegment *)rls)->transparency_mask;
|
||||
for (rls = rls->next; rls; rls = rls->next) {
|
||||
double gpos[3], lpos[3];
|
||||
double *lfb = rl->l->fbcoord, *rfb = rl->r->fbcoord;
|
||||
double global_at = lfb[3] * rls->at / (rls->at * lfb[3] + (1 - rls->at) * rfb[3]);
|
||||
interp_v3_v3v3_db(lpos, rl->l->fbcoord, rl->r->fbcoord, rls->at);
|
||||
interp_v3_v3v3_db(gpos, rl->l->gloc, rl->r->gloc, global_at);
|
||||
POS_TO_FLOAT(lpos, gpos)
|
||||
lineart_chain_append_point(rb,
|
||||
rlc,
|
||||
use_fbcoord,
|
||||
use_gpos,
|
||||
N,
|
||||
rl->flags,
|
||||
rls->occlusion,
|
||||
rls->transparency_mask,
|
||||
rl->l_obindex);
|
||||
last_occlusion = rls->occlusion;
|
||||
}
|
||||
VERT_COORD_TO_FLOAT(rl->r)
|
||||
lineart_chain_append_point(rb,
|
||||
rlc,
|
||||
use_fbcoord,
|
||||
use_gpos,
|
||||
N,
|
||||
rl->flags,
|
||||
last_occlusion,
|
||||
last_transparency,
|
||||
rl->r_obindex);
|
||||
|
||||
/* step 3: grow right. */
|
||||
ba = ED_lineart_get_point_bounding_area_deep(rb, rl->r->fbcoord[0], rl->r->fbcoord[1]);
|
||||
new_rv = rl->r;
|
||||
/* below already done in step 2. */
|
||||
/* lineart_chain_push_point(rb,rlc,new_rv->fbcoord[0],new_rv->fbcoord[1],rl->flags,0);
|
||||
. */
|
||||
while (ba && (new_rl = lineart_line_get_connected(ba, new_rv, &new_rv, rl->flags))) {
|
||||
new_rl->flags |= LRT_EDGE_FLAG_CHAIN_PICKED;
|
||||
|
||||
if (new_rl->tl || new_rl->tr) {
|
||||
zero_v3(N);
|
||||
if (new_rl->tl) {
|
||||
N[0] += new_rl->tl->gn[0];
|
||||
N[1] += new_rl->tl->gn[1];
|
||||
N[2] += new_rl->tl->gn[2];
|
||||
}
|
||||
if (new_rl->tr) {
|
||||
N[0] += new_rl->tr->gn[0];
|
||||
N[1] += new_rl->tr->gn[1];
|
||||
N[2] += new_rl->tr->gn[2];
|
||||
}
|
||||
normalize_v3(N);
|
||||
}
|
||||
|
||||
/* fix leading vertex type. */
|
||||
rlci = rlc->chain.last;
|
||||
rlci->line_type = new_rl->flags & LRT_EDGE_FLAG_ALL_TYPE;
|
||||
|
||||
if (new_rv == new_rl->l) {
|
||||
rls = new_rl->segments.last;
|
||||
last_occlusion = rls->occlusion;
|
||||
last_transparency = rls->transparency_mask;
|
||||
rlci->occlusion = last_occlusion; /* fix leading vertex occlusion. */
|
||||
for (rls = new_rl->segments.last; rls; rls = rls->prev) {
|
||||
double gpos[3], lpos[3];
|
||||
double *lfb = new_rl->l->fbcoord, *rfb = new_rl->r->fbcoord;
|
||||
double global_at = lfb[3] * rls->at / (rls->at * lfb[3] + (1 - rls->at) * rfb[3]);
|
||||
interp_v3_v3v3_db(lpos, new_rl->l->fbcoord, new_rl->r->fbcoord, rls->at);
|
||||
interp_v3_v3v3_db(gpos, new_rl->l->gloc, new_rl->r->gloc, global_at);
|
||||
last_occlusion = rls->prev ? rls->prev->occlusion : last_occlusion;
|
||||
POS_TO_FLOAT(lpos, gpos)
|
||||
lineart_chain_append_point(rb,
|
||||
rlc,
|
||||
use_fbcoord,
|
||||
use_gpos,
|
||||
N,
|
||||
new_rl->flags,
|
||||
last_occlusion,
|
||||
last_transparency,
|
||||
new_rl->l_obindex);
|
||||
}
|
||||
}
|
||||
else if (new_rv == new_rl->r) {
|
||||
rls = new_rl->segments.first;
|
||||
last_occlusion = rls->occlusion;
|
||||
last_transparency = rls->transparency_mask;
|
||||
rlci->occlusion = last_occlusion;
|
||||
rls = rls->next;
|
||||
for (; rls; rls = rls->next) {
|
||||
double gpos[3], lpos[3];
|
||||
double *lfb = new_rl->l->fbcoord, *rfb = new_rl->r->fbcoord;
|
||||
double global_at = lfb[3] * rls->at / (rls->at * lfb[3] + (1 - rls->at) * rfb[3]);
|
||||
interp_v3_v3v3_db(lpos, new_rl->l->fbcoord, new_rl->r->fbcoord, rls->at);
|
||||
interp_v3_v3v3_db(gpos, new_rl->l->gloc, new_rl->r->gloc, global_at);
|
||||
POS_TO_FLOAT(lpos, gpos)
|
||||
lineart_chain_append_point(rb,
|
||||
rlc,
|
||||
use_fbcoord,
|
||||
use_gpos,
|
||||
N,
|
||||
new_rl->flags,
|
||||
rls->occlusion,
|
||||
rls->transparency_mask,
|
||||
new_rl->r_obindex);
|
||||
last_occlusion = rls->occlusion;
|
||||
last_transparency = rls->transparency_mask;
|
||||
}
|
||||
VERT_COORD_TO_FLOAT(new_rl->r)
|
||||
lineart_chain_append_point(rb,
|
||||
rlc,
|
||||
use_fbcoord,
|
||||
use_gpos,
|
||||
N,
|
||||
new_rl->flags,
|
||||
last_occlusion,
|
||||
last_transparency,
|
||||
new_rl->r_obindex);
|
||||
}
|
||||
ba = ED_lineart_get_point_bounding_area_deep(rb, new_rv->fbcoord[0], new_rv->fbcoord[1]);
|
||||
}
|
||||
if (rb->fuzzy_everything) {
|
||||
rlc->type = LRT_EDGE_FLAG_CONTOUR;
|
||||
}
|
||||
else {
|
||||
rlc->type = (rl->flags & LRT_EDGE_FLAG_ALL_TYPE);
|
||||
}
|
||||
}
|
||||
LRT_ITER_ALL_LINES_END
|
||||
}
|
||||
|
||||
static LineartBoundingArea *lineart_bounding_area_get_rlci_recursive(
|
||||
LineartRenderBuffer *rb, LineartBoundingArea *root, LineartRenderLineChainItem *rlci)
|
||||
{
|
||||
if (root->child == NULL) {
|
||||
return root;
|
||||
}
|
||||
else {
|
||||
LineartBoundingArea *ch = root->child;
|
||||
#define IN_BOUND(ba, rlci) \
|
||||
ba.l <= rlci->pos[0] && ba.r >= rlci->pos[0] && ba.b <= rlci->pos[1] && ba.u >= rlci->pos[1]
|
||||
|
||||
if (IN_BOUND(ch[0], rlci)) {
|
||||
return lineart_bounding_area_get_rlci_recursive(rb, &ch[0], rlci);
|
||||
}
|
||||
else if (IN_BOUND(ch[1], rlci)) {
|
||||
return lineart_bounding_area_get_rlci_recursive(rb, &ch[1], rlci);
|
||||
}
|
||||
else if (IN_BOUND(ch[2], rlci)) {
|
||||
return lineart_bounding_area_get_rlci_recursive(rb, &ch[2], rlci);
|
||||
}
|
||||
else if (IN_BOUND(ch[3], rlci)) {
|
||||
return lineart_bounding_area_get_rlci_recursive(rb, &ch[3], rlci);
|
||||
}
|
||||
#undef IN_BOUND
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static LineartBoundingArea *lineart_bounding_area_get_end_point(LineartRenderBuffer *rb,
|
||||
LineartRenderLineChainItem *rlci)
|
||||
{
|
||||
if (!rlci) {
|
||||
return NULL;
|
||||
}
|
||||
LineartBoundingArea *root = ED_lineart_get_point_bounding_area(rb, rlci->pos[0], rlci->pos[1]);
|
||||
if (root == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return lineart_bounding_area_get_rlci_recursive(rb, root, rlci);
|
||||
}
|
||||
|
||||
/* if reduction threshold is even larger than a small bounding area,. */
|
||||
/* then 1) geometry is simply too dense. */
|
||||
/* 2) probably need to add it to root bounding area which has larger surface area then it
|
||||
* will. */
|
||||
/* cover typical threshold values. */
|
||||
static void lineart_bounding_area_link_point_recursive(LineartRenderBuffer *rb,
|
||||
LineartBoundingArea *root,
|
||||
LineartRenderLineChain *rlc,
|
||||
LineartRenderLineChainItem *rlci)
|
||||
{
|
||||
if (root->child == NULL) {
|
||||
LineartChainRegisterEntry *cre = lineart_list_append_pointer_pool_sized(
|
||||
&root->linked_chains, &rb->render_data_pool, rlc, sizeof(LineartChainRegisterEntry));
|
||||
|
||||
cre->rlci = rlci;
|
||||
|
||||
if (rlci == rlc->chain.first) {
|
||||
cre->is_left = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LineartBoundingArea *ch = root->child;
|
||||
|
||||
#define IN_BOUND(ba, rlci) \
|
||||
ba.l <= rlci->pos[0] && ba.r >= rlci->pos[0] && ba.b <= rlci->pos[1] && ba.u >= rlci->pos[1]
|
||||
|
||||
if (IN_BOUND(ch[0], rlci)) {
|
||||
lineart_bounding_area_link_point_recursive(rb, &ch[0], rlc, rlci);
|
||||
}
|
||||
else if (IN_BOUND(ch[1], rlci)) {
|
||||
lineart_bounding_area_link_point_recursive(rb, &ch[1], rlc, rlci);
|
||||
}
|
||||
else if (IN_BOUND(ch[2], rlci)) {
|
||||
lineart_bounding_area_link_point_recursive(rb, &ch[2], rlc, rlci);
|
||||
}
|
||||
else if (IN_BOUND(ch[3], rlci)) {
|
||||
lineart_bounding_area_link_point_recursive(rb, &ch[3], rlc, rlci);
|
||||
}
|
||||
|
||||
#undef IN_BOUND
|
||||
}
|
||||
}
|
||||
|
||||
static void lineart_bounding_area_link_chain(LineartRenderBuffer *rb, LineartRenderLineChain *rlc)
|
||||
{
|
||||
LineartRenderLineChainItem *pl = rlc->chain.first;
|
||||
LineartRenderLineChainItem *pr = rlc->chain.last;
|
||||
LineartBoundingArea *ba1 = ED_lineart_get_point_bounding_area(rb, pl->pos[0], pl->pos[1]);
|
||||
LineartBoundingArea *ba2 = ED_lineart_get_point_bounding_area(rb, pr->pos[0], pr->pos[1]);
|
||||
|
||||
if (ba1) {
|
||||
lineart_bounding_area_link_point_recursive(rb, ba1, rlc, pl);
|
||||
}
|
||||
if (ba2) {
|
||||
lineart_bounding_area_link_point_recursive(rb, ba2, rlc, pr);
|
||||
}
|
||||
}
|
||||
|
||||
void ED_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
|
||||
{
|
||||
LineartRenderLineChain *rlc, *new_rlc;
|
||||
LineartRenderLineChainItem *rlci, *next_rlci;
|
||||
ListBase swap = {0};
|
||||
|
||||
swap.first = rb->chains.first;
|
||||
swap.last = rb->chains.last;
|
||||
|
||||
rb->chains.last = rb->chains.first = NULL;
|
||||
|
||||
while ((rlc = BLI_pophead(&swap)) != NULL) {
|
||||
rlc->next = rlc->prev = NULL;
|
||||
BLI_addtail(&rb->chains, rlc);
|
||||
LineartRenderLineChainItem *first_rlci = (LineartRenderLineChainItem *)rlc->chain.first;
|
||||
int fixed_occ = first_rlci->occlusion;
|
||||
unsigned char fixed_mask = first_rlci->transparency_mask;
|
||||
rlc->level = fixed_occ;
|
||||
rlc->transparency_mask = fixed_mask;
|
||||
for (rlci = first_rlci->next; rlci; rlci = next_rlci) {
|
||||
next_rlci = rlci->next;
|
||||
if (rlci->occlusion != fixed_occ || rlci->transparency_mask != fixed_mask) {
|
||||
if (next_rlci) {
|
||||
if (lineart_point_overlapping(next_rlci, rlci->pos[0], rlci->pos[1], 1e-5)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Set the same occlusion level for the end vertex, so when further connection is needed
|
||||
* the backwards occlusion info is also correct. */
|
||||
rlci->occlusion = fixed_occ;
|
||||
/* No need to split at the last point anyway. */
|
||||
break;
|
||||
}
|
||||
new_rlc = lineart_chain_create(rb);
|
||||
new_rlc->chain.first = rlci;
|
||||
new_rlc->chain.last = rlc->chain.last;
|
||||
rlc->chain.last = rlci->prev;
|
||||
((LineartRenderLineChainItem *)rlc->chain.last)->next = 0;
|
||||
rlci->prev = 0;
|
||||
|
||||
/* end the previous one. */
|
||||
lineart_chain_append_point(rb,
|
||||
rlc,
|
||||
rlci->pos,
|
||||
rlci->gpos,
|
||||
rlci->normal,
|
||||
rlci->line_type,
|
||||
fixed_occ,
|
||||
fixed_mask,
|
||||
rlci->index);
|
||||
new_rlc->object_ref = rlc->object_ref;
|
||||
new_rlc->type = rlc->type;
|
||||
rlc = new_rlc;
|
||||
fixed_occ = rlci->occlusion;
|
||||
fixed_mask = rlci->transparency_mask;
|
||||
rlc->level = fixed_occ;
|
||||
rlc->transparency_mask = fixed_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
LISTBASE_FOREACH (LineartRenderLineChain *, irlc, &rb->chains) {
|
||||
lineart_bounding_area_link_chain(rb, irlc);
|
||||
}
|
||||
}
|
||||
|
||||
/* note: segment type (crease/material/contour...) is ambiguous after this. */
|
||||
static void lineart_chain_connect(LineartRenderBuffer *UNUSED(rb),
|
||||
LineartRenderLineChain *onto,
|
||||
LineartRenderLineChain *sub,
|
||||
int reverse_1,
|
||||
int reverse_2)
|
||||
{
|
||||
LineartRenderLineChainItem *rlci;
|
||||
if (onto->type == LRT_EDGE_FLAG_INTERSECTION) {
|
||||
if (sub->object_ref) {
|
||||
onto->object_ref = sub->object_ref;
|
||||
onto->type = LRT_EDGE_FLAG_CONTOUR;
|
||||
}
|
||||
}
|
||||
else if (sub->type == LRT_EDGE_FLAG_INTERSECTION) {
|
||||
if (onto->type != LRT_EDGE_FLAG_INTERSECTION) {
|
||||
onto->type = LRT_EDGE_FLAG_CONTOUR;
|
||||
}
|
||||
}
|
||||
if (!reverse_1) { /* L--R L-R. */
|
||||
if (reverse_2) { /* L--R R-L. */
|
||||
BLI_listbase_reverse(&sub->chain);
|
||||
}
|
||||
rlci = sub->chain.first;
|
||||
if (lineart_point_overlapping(onto->chain.last, rlci->pos[0], rlci->pos[1], 1e-5)) {
|
||||
BLI_pophead(&sub->chain);
|
||||
if (sub->chain.first == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
((LineartRenderLineChainItem *)onto->chain.last)->next = sub->chain.first;
|
||||
((LineartRenderLineChainItem *)sub->chain.first)->prev = onto->chain.last;
|
||||
onto->chain.last = sub->chain.last;
|
||||
}
|
||||
else { /* L-R L--R. */
|
||||
if (!reverse_2) { /* R-L L--R. */
|
||||
BLI_listbase_reverse(&sub->chain);
|
||||
}
|
||||
rlci = onto->chain.first;
|
||||
if (lineart_point_overlapping(sub->chain.last, rlci->pos[0], rlci->pos[1], 1e-5)) {
|
||||
BLI_pophead(&onto->chain);
|
||||
if (onto->chain.first == NULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
((LineartRenderLineChainItem *)sub->chain.last)->next = onto->chain.first;
|
||||
((LineartRenderLineChainItem *)onto->chain.first)->prev = sub->chain.last;
|
||||
onto->chain.first = sub->chain.first;
|
||||
}
|
||||
}
|
||||
|
||||
static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuffer *rb,
|
||||
LineartBoundingArea *ba,
|
||||
LineartRenderLineChain *rlc,
|
||||
LineartRenderLineChainItem *rlci,
|
||||
int occlusion,
|
||||
unsigned char transparency_mask,
|
||||
float dist,
|
||||
int do_geometry_space,
|
||||
float *result_new_len,
|
||||
LineartBoundingArea *caller_ba)
|
||||
{
|
||||
|
||||
LineartChainRegisterEntry *closest_cre = NULL;
|
||||
|
||||
/* Keep using for loop because cre could be removed from the iteration before getting to the
|
||||
* next one. */
|
||||
LISTBASE_FOREACH_MUTABLE (LineartChainRegisterEntry *, cre, &ba->linked_chains) {
|
||||
if (cre->rlc->object_ref != rlc->object_ref) {
|
||||
if (!rb->fuzzy_everything) {
|
||||
if (rb->fuzzy_intersections) {
|
||||
/* If none of those are intersection lines... */
|
||||
if ((!(cre->rlc->type & LRT_EDGE_FLAG_INTERSECTION)) &&
|
||||
(!(rlc->type & LRT_EDGE_FLAG_INTERSECTION))) {
|
||||
continue; /* We don't want to chain along different objects at the moment. */
|
||||
}
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cre->rlc->picked || cre->picked) {
|
||||
continue;
|
||||
}
|
||||
if (cre->rlc == rlc || (!cre->rlc->chain.first) || (cre->rlc->level != occlusion) ||
|
||||
(cre->rlc->transparency_mask != transparency_mask)) {
|
||||
continue;
|
||||
}
|
||||
if (!rb->fuzzy_everything) {
|
||||
if (cre->rlc->type != rlc->type) {
|
||||
if (rb->fuzzy_intersections) {
|
||||
if (!(cre->rlc->type == LRT_EDGE_FLAG_INTERSECTION ||
|
||||
rlc->type == LRT_EDGE_FLAG_INTERSECTION)) {
|
||||
continue; /* fuzzy intersetions but no intersection line found. */
|
||||
}
|
||||
}
|
||||
else { /* line type different but no fuzzy. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float new_len = do_geometry_space ? len_v3v3(cre->rlci->gpos, rlci->gpos) :
|
||||
len_v2v2(cre->rlci->pos, rlci->pos);
|
||||
if (new_len < dist) {
|
||||
closest_cre = cre;
|
||||
dist = new_len;
|
||||
if (result_new_len) {
|
||||
(*result_new_len) = new_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
float adjacent_new_len =
|
||||
dist; /* We want a closer point anyway. So using modified dist is fine. */
|
||||
LineartChainRegisterEntry *adjacent_closest;
|
||||
|
||||
#define LRT_TEST_ADJACENT_AREAS(dist_to, list) \
|
||||
if (dist_to < dist && dist_to > 0) { \
|
||||
LISTBASE_FOREACH (LinkData *, ld, list) { \
|
||||
LineartBoundingArea *sba = (LineartBoundingArea *)ld->data; \
|
||||
adjacent_closest = lineart_chain_get_closest_cre(rb, \
|
||||
sba, \
|
||||
rlc, \
|
||||
rlci, \
|
||||
occlusion, \
|
||||
transparency_mask, \
|
||||
dist, \
|
||||
do_geometry_space, \
|
||||
&adjacent_new_len, \
|
||||
ba); \
|
||||
if (adjacent_new_len < dist) { \
|
||||
dist = adjacent_new_len; \
|
||||
closest_cre = adjacent_closest; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
if (!do_geometry_space && !caller_ba) {
|
||||
LRT_TEST_ADJACENT_AREAS(rlci->pos[0] - ba->l, &ba->lp);
|
||||
LRT_TEST_ADJACENT_AREAS(ba->r - rlci->pos[0], &ba->rp);
|
||||
LRT_TEST_ADJACENT_AREAS(ba->u - rlci->pos[1], &ba->up);
|
||||
LRT_TEST_ADJACENT_AREAS(rlci->pos[1] - ba->b, &ba->bp);
|
||||
}
|
||||
if (result_new_len) {
|
||||
(*result_new_len) = dist;
|
||||
}
|
||||
return closest_cre;
|
||||
}
|
||||
|
||||
/* this only does head-tail connection. */
|
||||
/* overlapping / tiny isolated segment / loop reduction not implemented here yet. */
|
||||
void ED_lineart_chain_connect(LineartRenderBuffer *rb, const int do_geometry_space)
|
||||
{
|
||||
LineartRenderLineChain *rlc;
|
||||
LineartRenderLineChainItem *rlci_l, *rlci_r;
|
||||
LineartBoundingArea *ba_l, *ba_r;
|
||||
LineartChainRegisterEntry *closest_cre_l, *closest_cre_r, *closest_cre;
|
||||
float dist = do_geometry_space ? rb->chaining_geometry_threshold : rb->chaining_image_threshold;
|
||||
float dist_l, dist_r;
|
||||
int occlusion, reverse_main;
|
||||
unsigned char transparency_mask;
|
||||
ListBase swap = {0};
|
||||
|
||||
if ((!do_geometry_space && rb->chaining_image_threshold < 0.0001) ||
|
||||
(do_geometry_space && rb->chaining_geometry_threshold < 0.0001)) {
|
||||
return;
|
||||
}
|
||||
|
||||
swap.first = rb->chains.first;
|
||||
swap.last = rb->chains.last;
|
||||
|
||||
rb->chains.last = rb->chains.first = NULL;
|
||||
|
||||
while ((rlc = BLI_pophead(&swap)) != NULL) {
|
||||
rlc->next = rlc->prev = NULL;
|
||||
if (rlc->picked) {
|
||||
continue;
|
||||
}
|
||||
BLI_addtail(&rb->chains, rlc);
|
||||
|
||||
occlusion = rlc->level;
|
||||
transparency_mask = rlc->transparency_mask;
|
||||
|
||||
rlci_l = rlc->chain.first;
|
||||
rlci_r = rlc->chain.last;
|
||||
while ((ba_l = lineart_bounding_area_get_end_point(rb, rlci_l)) &&
|
||||
(ba_r = lineart_bounding_area_get_end_point(rb, rlci_r))) {
|
||||
closest_cre_l = lineart_chain_get_closest_cre(rb,
|
||||
ba_l,
|
||||
rlc,
|
||||
rlci_l,
|
||||
occlusion,
|
||||
transparency_mask,
|
||||
dist,
|
||||
do_geometry_space,
|
||||
&dist_l,
|
||||
NULL);
|
||||
closest_cre_r = lineart_chain_get_closest_cre(rb,
|
||||
ba_r,
|
||||
rlc,
|
||||
rlci_r,
|
||||
occlusion,
|
||||
transparency_mask,
|
||||
dist,
|
||||
do_geometry_space,
|
||||
&dist_r,
|
||||
NULL);
|
||||
if (closest_cre_l && closest_cre_r) {
|
||||
if (dist_l < dist_r) {
|
||||
closest_cre = closest_cre_l;
|
||||
reverse_main = 1;
|
||||
}
|
||||
else {
|
||||
closest_cre = closest_cre_r;
|
||||
reverse_main = 0;
|
||||
}
|
||||
}
|
||||
else if (closest_cre_l) {
|
||||
closest_cre = closest_cre_l;
|
||||
reverse_main = 1;
|
||||
}
|
||||
else if (closest_cre_r) {
|
||||
closest_cre = closest_cre_r;
|
||||
BLI_remlink(&ba_r->linked_chains, closest_cre_r);
|
||||
reverse_main = 0;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
closest_cre->picked = 1;
|
||||
closest_cre->rlc->picked = 1;
|
||||
if (closest_cre->is_left) {
|
||||
lineart_chain_connect(rb, rlc, closest_cre->rlc, reverse_main, 0);
|
||||
}
|
||||
else {
|
||||
lineart_chain_connect(rb, rlc, closest_cre->rlc, reverse_main, 1);
|
||||
}
|
||||
BLI_remlink(&swap, closest_cre->rlc);
|
||||
rlci_l = rlc->chain.first;
|
||||
rlci_r = rlc->chain.last;
|
||||
}
|
||||
rlc->picked = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* length is in image space. */
|
||||
float ED_lineart_chain_compute_length(LineartRenderLineChain *rlc)
|
||||
{
|
||||
LineartRenderLineChainItem *rlci;
|
||||
float offset_accum = 0;
|
||||
float dist;
|
||||
float last_point[2];
|
||||
|
||||
rlci = rlc->chain.first;
|
||||
copy_v2_v2(last_point, rlci->pos);
|
||||
for (rlci = rlc->chain.first; rlci; rlci = rlci->next) {
|
||||
dist = len_v2v2(rlci->pos, last_point);
|
||||
offset_accum += dist;
|
||||
copy_v2_v2(last_point, rlci->pos);
|
||||
}
|
||||
return offset_accum;
|
||||
}
|
||||
|
||||
void ED_lineart_chain_discard_short(LineartRenderBuffer *rb, const float threshold)
|
||||
{
|
||||
LineartRenderLineChain *rlc, *next_rlc;
|
||||
for (rlc = rb->chains.first; rlc; rlc = next_rlc) {
|
||||
next_rlc = rlc->next;
|
||||
if (ED_lineart_chain_compute_length(rlc) < threshold) {
|
||||
BLI_remlink(&rb->chains, rlc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ED_lineart_chain_count(const LineartRenderLineChain *rlc)
|
||||
{
|
||||
int count = 0;
|
||||
LISTBASE_FOREACH (LineartRenderLineChainItem *, rlci, &rlc->chain) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void ED_lineart_chain_clear_picked_flag(LineartRenderBuffer *rb)
|
||||
{
|
||||
if (rb == NULL) {
|
||||
return;
|
||||
}
|
||||
LISTBASE_FOREACH (LineartRenderLineChain *, rlc, &rb->chains) {
|
||||
rlc->picked = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* This should always be the last stage!, see the end of
|
||||
* ED_lineart_chain_split_for_fixed_occlusion().*/
|
||||
void ED_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshold_rad)
|
||||
{
|
||||
LineartRenderLineChain *rlc, *new_rlc;
|
||||
LineartRenderLineChainItem *rlci, *next_rlci, *prev_rlci;
|
||||
ListBase swap = {0};
|
||||
|
||||
swap.first = rb->chains.first;
|
||||
swap.last = rb->chains.last;
|
||||
|
||||
rb->chains.last = rb->chains.first = NULL;
|
||||
|
||||
while ((rlc = BLI_pophead(&swap)) != NULL) {
|
||||
rlc->next = rlc->prev = NULL;
|
||||
BLI_addtail(&rb->chains, rlc);
|
||||
LineartRenderLineChainItem *first_rlci = (LineartRenderLineChainItem *)rlc->chain.first;
|
||||
for (rlci = first_rlci->next; rlci; rlci = next_rlci) {
|
||||
next_rlci = rlci->next;
|
||||
prev_rlci = rlci->prev;
|
||||
float angle = M_PI;
|
||||
if (next_rlci && prev_rlci) {
|
||||
angle = angle_v2v2v2(prev_rlci->pos, rlci->pos, next_rlci->pos);
|
||||
}
|
||||
else {
|
||||
break; /* No need to split at the last point anyway.*/
|
||||
}
|
||||
if (angle < angle_threshold_rad) {
|
||||
new_rlc = lineart_chain_create(rb);
|
||||
new_rlc->chain.first = rlci;
|
||||
new_rlc->chain.last = rlc->chain.last;
|
||||
rlc->chain.last = rlci->prev;
|
||||
((LineartRenderLineChainItem *)rlc->chain.last)->next = 0;
|
||||
rlci->prev = 0;
|
||||
|
||||
/* end the previous one. */
|
||||
lineart_chain_append_point(rb,
|
||||
rlc,
|
||||
rlci->pos,
|
||||
rlci->gpos,
|
||||
rlci->normal,
|
||||
rlci->line_type,
|
||||
rlc->level,
|
||||
rlci->transparency_mask,
|
||||
rlci->index);
|
||||
new_rlc->object_ref = rlc->object_ref;
|
||||
new_rlc->type = rlc->type;
|
||||
new_rlc->level = rlc->level;
|
||||
new_rlc->transparency_mask = rlc->transparency_mask;
|
||||
rlc = new_rlc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
4289
source/blender/editors/lineart/lineart_cpu.c
Normal file
4289
source/blender/editors/lineart/lineart_cpu.c
Normal file
File diff suppressed because it is too large
Load Diff
111
source/blender/editors/lineart/lineart_intern.h
Normal file
111
source/blender/editors/lineart/lineart_intern.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
#ifndef __LRT_INTERN_H__
|
||||
#define __LRT_INTERN_H__
|
||||
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "DNA_lineart_types.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
struct LineartStaticMemPoolNode;
|
||||
struct LineartRenderLine;
|
||||
struct LineartRenderBuffer;
|
||||
|
||||
void *lineart_list_append_pointer_pool(ListBase *h, struct LineartStaticMemPool *smp, void *p);
|
||||
void *lineart_list_append_pointer_pool_sized(ListBase *h,
|
||||
struct LineartStaticMemPool *smp,
|
||||
void *p,
|
||||
int size);
|
||||
void *list_push_pointer_static(ListBase *h, struct LineartStaticMemPool *smp, void *p);
|
||||
void *list_push_pointer_static_sized(ListBase *h,
|
||||
struct LineartStaticMemPool *smp,
|
||||
void *p,
|
||||
int size);
|
||||
|
||||
void *lineart_list_pop_pointer_no_free(ListBase *h);
|
||||
void lineart_list_remove_pointer_item_no_free(ListBase *h, LinkData *lip);
|
||||
|
||||
LineartStaticMemPoolNode *lineart_mem_new_static_pool(struct LineartStaticMemPool *smp,
|
||||
size_t size);
|
||||
void *lineart_mem_aquire(struct LineartStaticMemPool *smp, size_t size);
|
||||
void *lineart_mem_aquire_thread(struct LineartStaticMemPool *smp, size_t size);
|
||||
void lineart_mem_destroy(LineartStaticMemPool *smp);
|
||||
|
||||
void lineart_prepend_line_direct(LineartRenderLine **first, void *node);
|
||||
void lineart_prepend_pool(LinkNode **first, LineartStaticMemPool *smp, void *link);
|
||||
|
||||
void lineart_matrix_ortho_44d(double (*mProjection)[4],
|
||||
double xMin,
|
||||
double xMax,
|
||||
double yMin,
|
||||
double yMax,
|
||||
double zMin,
|
||||
double zMax);
|
||||
void lineart_matrix_perspective_44d(
|
||||
double (*mProjection)[4], double fFov_rad, double fAspect, double zMin, double zMax);
|
||||
|
||||
int lineart_count_intersection_segment_count(struct LineartRenderBuffer *rb);
|
||||
|
||||
void lineart_count_and_print_render_buffer_memory(LineartRenderBuffer *rb);
|
||||
|
||||
#define LRT_ITER_ALL_LINES_BEGIN \
|
||||
LineartRenderLine *rl, *next_rl, **current_list; \
|
||||
rl = rb->contours; \
|
||||
for (current_list = &rb->contours; rl; rl = next_rl) { \
|
||||
next_rl = rl->next;
|
||||
|
||||
#define LRT_ITER_ALL_LINES_NEXT \
|
||||
while (!next_rl) { \
|
||||
if (current_list == &rb->contours) { \
|
||||
current_list = &rb->crease_lines; \
|
||||
} \
|
||||
else if (current_list == &rb->crease_lines) { \
|
||||
current_list = &rb->material_lines; \
|
||||
} \
|
||||
else if (current_list == &rb->material_lines) { \
|
||||
current_list = &rb->edge_marks; \
|
||||
} \
|
||||
else if (current_list == &rb->edge_marks) { \
|
||||
current_list = &rb->intersection_lines; \
|
||||
} \
|
||||
else { \
|
||||
break; \
|
||||
} \
|
||||
next_rl = *current_list; \
|
||||
}
|
||||
|
||||
#define LRT_ITER_ALL_LINES_END \
|
||||
LRT_ITER_ALL_LINES_NEXT \
|
||||
}
|
||||
|
||||
#define LRT_BOUND_AREA_CROSSES(b1, b2) \
|
||||
((b1)[0] < (b2)[1] && (b1)[1] > (b2)[0] && (b1)[3] < (b2)[2] && (b1)[2] > (b2)[3])
|
||||
|
||||
#endif
|
250
source/blender/editors/lineart/lineart_ops.c
Normal file
250
source/blender/editors/lineart/lineart_ops.c
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_gpencil.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "DNA_gpencil_modifier_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "ED_lineart.h"
|
||||
|
||||
#include "lineart_intern.h"
|
||||
|
||||
extern LineartSharedResource lineart_share;
|
||||
|
||||
static int lineart_gpencil_update_strokes_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Depsgraph *dg = CTX_data_depsgraph_pointer(C);
|
||||
|
||||
BLI_spin_lock(&lineart_share.lock_loader);
|
||||
|
||||
ED_lineart_compute_feature_lines_background(dg, 0);
|
||||
|
||||
/* Wait for loading finish. */
|
||||
BLI_spin_lock(&lineart_share.lock_loader);
|
||||
BLI_spin_unlock(&lineart_share.lock_loader);
|
||||
|
||||
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int lineart_gpencil_bake_strokes_invoke(bContext *C,
|
||||
wmOperator *op,
|
||||
const wmEvent *UNUSED(event))
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
SceneLineArt *lineart = &scene->lineart;
|
||||
Depsgraph *dg = CTX_data_depsgraph_pointer(C);
|
||||
int frame;
|
||||
int frame_begin = ((lineart->flags & LRT_BAKING_FINAL_RANGE) ? MAX2(scene->r.sfra, 1) :
|
||||
lineart->baking_preview_start);
|
||||
int frame_end = ((lineart->flags & LRT_BAKING_FINAL_RANGE) ? scene->r.efra :
|
||||
lineart->baking_preview_end);
|
||||
int frame_total = frame_end - frame_begin;
|
||||
int frame_orig = scene->r.cfra;
|
||||
int frame_increment = ((lineart->flags & LRT_BAKING_KEYFRAMES_ONLY) ?
|
||||
1 :
|
||||
(lineart->baking_skip + 1));
|
||||
LineartGpencilModifierData *lmd;
|
||||
LineartRenderBuffer *rb;
|
||||
int use_types;
|
||||
bool frame_updated;
|
||||
|
||||
/* Needed for progress report. */
|
||||
lineart_share.wm = CTX_wm_manager(C);
|
||||
lineart_share.main_window = CTX_wm_window(C);
|
||||
|
||||
for (frame = frame_begin; frame <= frame_end; frame += frame_increment) {
|
||||
|
||||
frame_updated = false;
|
||||
|
||||
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (
|
||||
scene->master_collection, ob, DAG_EVAL_RENDER) {
|
||||
|
||||
int cleared = 0;
|
||||
if (ob->type == OB_GPENCIL) {
|
||||
LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
|
||||
if (md->type == eGpencilModifierType_Lineart) {
|
||||
lmd = (LineartGpencilModifierData *)md;
|
||||
bGPdata *gpd = ob->data;
|
||||
bGPDlayer *gpl = BKE_gpencil_layer_get_by_name(gpd, lmd->target_layer, 1);
|
||||
bGPDframe *gpf = ((lineart->flags & LRT_BAKING_KEYFRAMES_ONLY) ?
|
||||
BKE_gpencil_layer_frame_find(gpl, frame) :
|
||||
BKE_gpencil_layer_frame_get(gpl, frame, GP_GETFRAME_ADD_NEW));
|
||||
|
||||
if (!gpf) {
|
||||
continue; /* happens when it's keyframe only. */
|
||||
}
|
||||
|
||||
if (!frame_updated) {
|
||||
/* Reset flags. LRT_SYNC_IGNORE prevent any line art modifiers run calculation
|
||||
* function when depsgraph calls for modifier evalurates. */
|
||||
ED_lineart_modifier_sync_flag_set(LRT_SYNC_IGNORE, false);
|
||||
ED_lineart_calculation_flag_set(LRT_RENDER_IDLE);
|
||||
|
||||
BKE_scene_frame_set(scene, frame);
|
||||
BKE_scene_graph_update_for_newframe(dg);
|
||||
|
||||
ED_lineart_update_render_progress(
|
||||
(int)((float)(frame - frame_begin) / frame_total * 100), NULL);
|
||||
|
||||
BLI_spin_lock(&lineart_share.lock_loader);
|
||||
ED_lineart_compute_feature_lines_background(dg, 0);
|
||||
|
||||
/* Wait for loading finish. */
|
||||
BLI_spin_lock(&lineart_share.lock_loader);
|
||||
BLI_spin_unlock(&lineart_share.lock_loader);
|
||||
|
||||
while (!ED_lineart_modifier_sync_flag_check(LRT_SYNC_FRESH) ||
|
||||
!ED_lineart_calculation_flag_check(LRT_RENDER_FINISHED)) {
|
||||
/* Wait till it's done. */
|
||||
}
|
||||
|
||||
ED_lineart_chain_clear_picked_flag(lineart_share.render_buffer_shared);
|
||||
|
||||
frame_updated = true;
|
||||
}
|
||||
|
||||
/* Clear original frame. */
|
||||
if ((scene->lineart.flags & LRT_GPENCIL_OVERWRITE) && (!cleared)) {
|
||||
BKE_gpencil_layer_frame_delete(gpl, gpf);
|
||||
gpf = BKE_gpencil_layer_frame_get(gpl, frame, GP_GETFRAME_ADD_NEW);
|
||||
cleared = 1;
|
||||
}
|
||||
|
||||
rb = lineart_share.render_buffer_shared;
|
||||
|
||||
if (rb->fuzzy_everything) {
|
||||
use_types = LRT_EDGE_FLAG_CONTOUR;
|
||||
}
|
||||
else if (rb->fuzzy_intersections) {
|
||||
use_types = lmd->line_types | LRT_EDGE_FLAG_INTERSECTION;
|
||||
}
|
||||
else {
|
||||
use_types = lmd->line_types;
|
||||
}
|
||||
|
||||
ED_lineart_gpencil_generate_with_type(
|
||||
dg,
|
||||
ob,
|
||||
gpl,
|
||||
gpf,
|
||||
lmd->source_type,
|
||||
lmd->source_type == LRT_SOURCE_OBJECT ? (void *)lmd->source_object :
|
||||
(void *)lmd->source_collection,
|
||||
lmd->level_start,
|
||||
lmd->use_multiple_levels ? lmd->level_end : lmd->level_start,
|
||||
lmd->target_material ?
|
||||
BKE_gpencil_object_material_index_get(ob, lmd->target_material) :
|
||||
0,
|
||||
use_types,
|
||||
lmd->transparency_flags,
|
||||
lmd->transparency_mask,
|
||||
lmd->thickness,
|
||||
lmd->opacity,
|
||||
lmd->pre_sample_length,
|
||||
lmd->source_vertex_group,
|
||||
lmd->vgname,
|
||||
lmd->flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
|
||||
}
|
||||
|
||||
/* Restore original frame. */
|
||||
BKE_scene_frame_set(scene, frame_orig);
|
||||
BKE_scene_graph_update_for_newframe(dg);
|
||||
|
||||
ED_lineart_modifier_sync_flag_set(LRT_SYNC_IDLE, false);
|
||||
ED_lineart_calculation_flag_set(LRT_RENDER_FINISHED);
|
||||
|
||||
BKE_report(op->reports, RPT_INFO, "Line Art baking is complete.");
|
||||
WM_operator_confirm_message_ex(C,
|
||||
op,
|
||||
"Line Art baking is complete.",
|
||||
ICON_MOD_WIREFRAME,
|
||||
"Disable Line Art master switch",
|
||||
WM_OP_EXEC_REGION_WIN);
|
||||
|
||||
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
|
||||
|
||||
ED_lineart_update_render_progress(100, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int lineart_gpencil_bake_strokes_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
/* If confirmed in the dialog, then just turn off the master switch upon finished baking. */
|
||||
scene->lineart.flags &= (~LRT_AUTO_UPDATE);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* Blocking 1 frame update. */
|
||||
void SCENE_OT_lineart_update_strokes(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Update Line Art Strokes";
|
||||
ot->description = "Update strokes for Line Art grease pencil targets";
|
||||
ot->idname = "SCENE_OT_lineart_update_strokes";
|
||||
|
||||
ot->exec = lineart_gpencil_update_strokes_exec;
|
||||
}
|
||||
|
||||
/* All frames in range. */
|
||||
void SCENE_OT_lineart_bake_strokes(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Bake Line Art Strokes";
|
||||
ot->description = "Bake Line Art into grease pencil strokes for all frames";
|
||||
ot->idname = "SCENE_OT_lineart_bake_strokes";
|
||||
|
||||
ot->invoke = lineart_gpencil_bake_strokes_invoke;
|
||||
ot->exec = lineart_gpencil_bake_strokes_exec;
|
||||
}
|
||||
|
||||
void ED_operatortypes_lineart(void)
|
||||
{
|
||||
WM_operatortype_append(SCENE_OT_lineart_update_strokes);
|
||||
WM_operatortype_append(SCENE_OT_lineart_bake_strokes);
|
||||
}
|
233
source/blender/editors/lineart/lineart_util.c
Normal file
233
source/blender/editors/lineart/lineart_util.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup editors
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
/* #include <time.h> */
|
||||
#include "ED_lineart.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "lineart_intern.h"
|
||||
|
||||
/* Line art memory and list helper */
|
||||
|
||||
void *lineart_list_append_pointer_pool(ListBase *h, LineartStaticMemPool *smp, void *data)
|
||||
{
|
||||
LinkData *lip;
|
||||
if (h == NULL) {
|
||||
return 0;
|
||||
}
|
||||
lip = lineart_mem_aquire(smp, sizeof(LinkData));
|
||||
lip->data = data;
|
||||
BLI_addtail(h, lip);
|
||||
return lip;
|
||||
}
|
||||
void *lineart_list_append_pointer_pool_sized(ListBase *h,
|
||||
LineartStaticMemPool *smp,
|
||||
void *data,
|
||||
int size)
|
||||
{
|
||||
LinkData *lip;
|
||||
if (h == NULL) {
|
||||
return 0;
|
||||
}
|
||||
lip = lineart_mem_aquire(smp, size);
|
||||
lip->data = data;
|
||||
BLI_addtail(h, lip);
|
||||
return lip;
|
||||
}
|
||||
|
||||
void *lineart_list_pop_pointer_no_free(ListBase *h)
|
||||
{
|
||||
LinkData *lip;
|
||||
void *rev = 0;
|
||||
if (h == NULL) {
|
||||
return 0;
|
||||
}
|
||||
lip = BLI_pophead(h);
|
||||
rev = lip ? lip->data : 0;
|
||||
return rev;
|
||||
}
|
||||
void lineart_list_remove_pointer_item_no_free(ListBase *h, LinkData *lip)
|
||||
{
|
||||
BLI_remlink(h, (void *)lip);
|
||||
}
|
||||
|
||||
LineartStaticMemPoolNode *lineart_mem_new_static_pool(LineartStaticMemPool *smp, size_t size)
|
||||
{
|
||||
size_t set_size = size;
|
||||
if (set_size < LRT_MEMORY_POOL_64MB) {
|
||||
set_size = LRT_MEMORY_POOL_64MB; /* Prevent too many small allocations. */
|
||||
}
|
||||
size_t total_size = size + sizeof(LineartStaticMemPoolNode);
|
||||
LineartStaticMemPoolNode *smpn = MEM_callocN(total_size, "mempool");
|
||||
smpn->size = total_size;
|
||||
smpn->used_byte = sizeof(LineartStaticMemPoolNode);
|
||||
BLI_addhead(&smp->pools, smpn);
|
||||
return smpn;
|
||||
}
|
||||
void *lineart_mem_aquire(LineartStaticMemPool *smp, size_t size)
|
||||
{
|
||||
LineartStaticMemPoolNode *smpn = smp->pools.first;
|
||||
void *ret;
|
||||
|
||||
if (!smpn || (smpn->used_byte + size) > smpn->size) {
|
||||
smpn = lineart_mem_new_static_pool(smp, size);
|
||||
}
|
||||
|
||||
ret = ((unsigned char *)smpn) + smpn->used_byte;
|
||||
|
||||
smpn->used_byte += size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
void *lineart_mem_aquire_thread(LineartStaticMemPool *smp, size_t size)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
BLI_spin_lock(&smp->lock_mem);
|
||||
|
||||
LineartStaticMemPoolNode *smpn = smp->pools.first;
|
||||
|
||||
if (!smpn || (smpn->used_byte + size) > smpn->size) {
|
||||
smpn = lineart_mem_new_static_pool(smp, size);
|
||||
}
|
||||
|
||||
ret = ((unsigned char *)smpn) + smpn->used_byte;
|
||||
|
||||
smpn->used_byte += size;
|
||||
|
||||
BLI_spin_unlock(&smp->lock_mem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
void lineart_mem_destroy(LineartStaticMemPool *smp)
|
||||
{
|
||||
LineartStaticMemPoolNode *smpn;
|
||||
while ((smpn = BLI_pophead(&smp->pools)) != NULL) {
|
||||
MEM_freeN(smpn);
|
||||
}
|
||||
}
|
||||
|
||||
void lineart_prepend_line_direct(LineartRenderLine **first, void *node)
|
||||
{
|
||||
LineartRenderLine *ln = (LineartRenderLine *)node;
|
||||
ln->next = (*first);
|
||||
(*first) = ln;
|
||||
}
|
||||
|
||||
void lineart_prepend_pool(LinkNode **first, LineartStaticMemPool *smp, void *link)
|
||||
{
|
||||
LinkNode *ln = lineart_mem_aquire_thread(smp, sizeof(LinkNode));
|
||||
ln->next = (*first);
|
||||
ln->link = link;
|
||||
(*first) = ln;
|
||||
}
|
||||
|
||||
/* =======================================================================[str] */
|
||||
|
||||
void lineart_matrix_perspective_44d(
|
||||
double (*mProjection)[4], double fFov_rad, double fAspect, double zMin, double zMax)
|
||||
{
|
||||
double yMax;
|
||||
double yMin;
|
||||
double xMin;
|
||||
double xMax;
|
||||
|
||||
if (fAspect < 1) {
|
||||
yMax = zMin * tan(fFov_rad * 0.5f);
|
||||
yMin = -yMax;
|
||||
xMin = yMin * fAspect;
|
||||
xMax = -xMin;
|
||||
}
|
||||
else {
|
||||
xMax = zMin * tan(fFov_rad * 0.5f);
|
||||
xMin = -xMax;
|
||||
yMin = xMin / fAspect;
|
||||
yMax = -yMin;
|
||||
}
|
||||
|
||||
unit_m4_db(mProjection);
|
||||
|
||||
mProjection[0][0] = (2.0f * zMin) / (xMax - xMin);
|
||||
mProjection[1][1] = (2.0f * zMin) / (yMax - yMin);
|
||||
mProjection[2][0] = (xMax + xMin) / (xMax - xMin);
|
||||
mProjection[2][1] = (yMax + yMin) / (yMax - yMin);
|
||||
mProjection[2][2] = -((zMax + zMin) / (zMax - zMin));
|
||||
mProjection[2][3] = -1.0f;
|
||||
mProjection[3][2] = -((2.0f * (zMax * zMin)) / (zMax - zMin));
|
||||
mProjection[3][3] = 0.0f;
|
||||
}
|
||||
void lineart_matrix_ortho_44d(double (*mProjection)[4],
|
||||
double xMin,
|
||||
double xMax,
|
||||
double yMin,
|
||||
double yMax,
|
||||
double zMin,
|
||||
double zMax)
|
||||
{
|
||||
unit_m4_db(mProjection);
|
||||
|
||||
mProjection[0][0] = 2.0f / (xMax - xMin);
|
||||
mProjection[1][1] = 2.0f / (yMax - yMin);
|
||||
mProjection[2][2] = -2.0f / (zMax - zMin);
|
||||
mProjection[3][0] = -((xMax + xMin) / (xMax - xMin));
|
||||
mProjection[3][1] = -((yMax + yMin) / (yMax - yMin));
|
||||
mProjection[3][2] = -((zMax + zMin) / (zMax - zMin));
|
||||
mProjection[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
void lineart_count_and_print_render_buffer_memory(LineartRenderBuffer *rb)
|
||||
{
|
||||
size_t total = 0;
|
||||
size_t sum_this = 0;
|
||||
size_t count_this = 0;
|
||||
|
||||
LISTBASE_FOREACH (LineartStaticMemPoolNode *, smpn, &rb->render_data_pool.pools) {
|
||||
count_this++;
|
||||
sum_this += LRT_MEMORY_POOL_64MB;
|
||||
}
|
||||
printf("LANPR Memory allocated %lu Standalone nodes, total %lu Bytes.\n", count_this, sum_this);
|
||||
total += sum_this;
|
||||
sum_this = 0;
|
||||
count_this = 0;
|
||||
|
||||
LISTBASE_FOREACH (LineartRenderElementLinkNode *, reln, &rb->line_buffer_pointers) {
|
||||
count_this++;
|
||||
sum_this += reln->element_count * sizeof(LineartRenderLine);
|
||||
}
|
||||
printf(" allocated %lu edge blocks, total %lu Bytes.\n", count_this, sum_this);
|
||||
total += sum_this;
|
||||
sum_this = 0;
|
||||
count_this = 0;
|
||||
|
||||
LISTBASE_FOREACH (LineartRenderElementLinkNode *, reln, &rb->triangle_buffer_pointers) {
|
||||
count_this++;
|
||||
sum_this += reln->element_count * rb->triangle_size;
|
||||
}
|
||||
printf(" allocated %lu triangle blocks, total %lu Bytes.\n", count_this, sum_this);
|
||||
total += sum_this;
|
||||
sum_this = 0;
|
||||
count_this = 0;
|
||||
}
|
@@ -85,6 +85,10 @@ if(WITH_FREESTYLE)
|
||||
add_definitions(-DWITH_FREESTYLE)
|
||||
endif()
|
||||
|
||||
if(WITH_LINEART)
|
||||
add_definitions(-DWITH_LINEART)
|
||||
endif()
|
||||
|
||||
if(WITH_BULLET)
|
||||
add_definitions(-DWITH_BULLET)
|
||||
endif()
|
||||
|
@@ -7746,7 +7746,7 @@ void MESH_OT_symmetry_snap(struct wmOperatorType *ot)
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef WITH_FREESTYLE
|
||||
#if (defined(WITH_FREESTYLE) || defined(WITH_LINEART))
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Mark Edge (Freestyle) Operator
|
||||
@@ -7906,7 +7906,7 @@ void MESH_OT_mark_freestyle_face(wmOperatorType *ot)
|
||||
|
||||
/** \} */
|
||||
|
||||
#endif /* WITH_FREESTYLE */
|
||||
#endif /* WITH_FREESTYLE || WITH_LINEART */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Loop Normals Editing Tools Modal Map
|
||||
|
@@ -267,7 +267,7 @@ void MESH_OT_paint_mask_slice(struct wmOperatorType *ot);
|
||||
|
||||
struct wmKeyMap *point_normals_modal_keymap(wmKeyConfig *keyconf);
|
||||
|
||||
#ifdef WITH_FREESTYLE
|
||||
#if (defined(WITH_FREESTYLE) || defined(WITH_LINEART))
|
||||
void MESH_OT_mark_freestyle_edge(struct wmOperatorType *ot);
|
||||
void MESH_OT_mark_freestyle_face(struct wmOperatorType *ot);
|
||||
#endif
|
||||
|
@@ -130,7 +130,7 @@ void ED_operatortypes_mesh(void)
|
||||
WM_operatortype_append(MESH_OT_loop_multi_select);
|
||||
WM_operatortype_append(MESH_OT_mark_seam);
|
||||
WM_operatortype_append(MESH_OT_mark_sharp);
|
||||
#ifdef WITH_FREESTYLE
|
||||
#if (defined(WITH_FREESTYLE) || defined(WITH_LINEART))
|
||||
WM_operatortype_append(MESH_OT_mark_freestyle_edge);
|
||||
#endif
|
||||
WM_operatortype_append(MESH_OT_vertices_smooth);
|
||||
|
@@ -86,6 +86,10 @@ if(WITH_INTERNATIONAL)
|
||||
add_definitions(-DWITH_INTERNATIONAL)
|
||||
endif()
|
||||
|
||||
if(WITH_LINEART)
|
||||
add_definitions(-DWITH_LINEART)
|
||||
endif()
|
||||
|
||||
if(WITH_EXPERIMENTAL_FEATURES)
|
||||
add_definitions(-DWITH_GEOMETRY_NODES)
|
||||
add_definitions(-DWITH_POINT_CLOUD)
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_gpencil_modifier_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_light_types.h"
|
||||
@@ -68,6 +69,7 @@
|
||||
#include "BKE_geometry_set.h"
|
||||
#include "BKE_gpencil_curve.h"
|
||||
#include "BKE_gpencil_geom.h"
|
||||
#include "BKE_gpencil_modifier.h"
|
||||
#include "BKE_hair.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_lattice.h"
|
||||
@@ -1305,7 +1307,7 @@ static bool object_gpencil_add_poll(bContext *C)
|
||||
|
||||
static int object_gpencil_add_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
Object *ob = CTX_data_active_object(C), *ob_orig = ob;
|
||||
bGPdata *gpd = (ob && (ob->type == OB_GPENCIL)) ? ob->data : NULL;
|
||||
|
||||
const int type = RNA_enum_get(op->ptr, "type");
|
||||
@@ -1333,6 +1335,13 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
|
||||
ob_name = "Stroke";
|
||||
break;
|
||||
}
|
||||
#ifdef WITH_LINEART
|
||||
case GP_LRT_OBJECT:
|
||||
case GP_LRT_COLLECTION: {
|
||||
ob_name = "Line Art";
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
@@ -1373,6 +1382,52 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
|
||||
ED_gpencil_create_monkey(C, ob, mat);
|
||||
break;
|
||||
}
|
||||
#ifdef WITH_LINEART
|
||||
case GP_LRT_SCENE:
|
||||
case GP_LRT_COLLECTION:
|
||||
case GP_LRT_OBJECT: {
|
||||
float radius = RNA_float_get(op->ptr, "radius");
|
||||
float mat[4][4];
|
||||
|
||||
ED_object_new_primitive_matrix(C, ob, loc, rot, mat);
|
||||
mul_v3_fl(mat[0], radius);
|
||||
mul_v3_fl(mat[1], radius);
|
||||
mul_v3_fl(mat[2], radius);
|
||||
|
||||
ED_gpencil_create_lineart(C, ob);
|
||||
|
||||
gpd = ob->data;
|
||||
|
||||
/* Add Line Art modifier */
|
||||
LineartGpencilModifierData *md = (LineartGpencilModifierData *)BKE_gpencil_modifier_new(
|
||||
eGpencilModifierType_Lineart);
|
||||
BLI_addtail(&ob->greasepencil_modifiers, md);
|
||||
BKE_gpencil_modifier_unique_name(&ob->greasepencil_modifiers, (GpencilModifierData *)md);
|
||||
|
||||
if (type == GP_LRT_COLLECTION) {
|
||||
md->source_type = LRT_SOURCE_COLLECTION;
|
||||
md->source_collection = CTX_data_collection(C);
|
||||
}
|
||||
else if (type == GP_LRT_OBJECT) {
|
||||
md->source_type = LRT_SOURCE_OBJECT;
|
||||
md->source_object = ob_orig;
|
||||
}
|
||||
else {
|
||||
/* Whole scene. */
|
||||
md->source_type = LRT_SOURCE_SCENE;
|
||||
}
|
||||
/* Only created one layer and one material. */
|
||||
strcpy(md->target_layer, ((bGPDlayer *)gpd->layers.first)->info);
|
||||
md->target_material = BKE_gpencil_material(ob, 1);
|
||||
|
||||
/* Stroke object is drawn in front of meshes by default. */
|
||||
ob->dtx |= OB_DRAW_IN_FRONT;
|
||||
|
||||
/* Turn on Line Art auto update to show the result. */
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
scene->lineart.flags |= LRT_AUTO_UPDATE;
|
||||
}
|
||||
#endif
|
||||
case GP_EMPTY:
|
||||
/* do nothing */
|
||||
break;
|
||||
@@ -1393,6 +1448,45 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static const EnumPropertyItem *object_gpencil_add_options(bContext *C,
|
||||
PointerRNA *UNUSED(ptr),
|
||||
PropertyRNA *UNUSED(prop),
|
||||
bool *r_free)
|
||||
{
|
||||
EnumPropertyItem *item = NULL, *item_ref = rna_enum_object_gpencil_type_items;
|
||||
int totitem = 0;
|
||||
int i = 0;
|
||||
int orig_count = RNA_enum_items_count(item_ref);
|
||||
|
||||
/* Default types. */
|
||||
for (i = 0; i < orig_count; i++) {
|
||||
if (item_ref[i].value == GP_LRT_OBJECT || item_ref[i].value == GP_LRT_COLLECTION ||
|
||||
item_ref[i].value == GP_LRT_SCENE) {
|
||||
#ifdef WITH_LINEART
|
||||
if (item_ref[i].value == GP_LRT_SCENE) {
|
||||
/* separator before line art types */
|
||||
RNA_enum_item_add_separator(&item, &totitem);
|
||||
}
|
||||
else if (item_ref[i].value == GP_LRT_OBJECT) {
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
if (!ob || ob->type != OB_MESH) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Don't show line art options when not compiled with one. */
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
RNA_enum_item_add(&item, &totitem, &item_ref[i]);
|
||||
}
|
||||
|
||||
RNA_enum_item_end(&item, &totitem);
|
||||
*r_free = true;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void OBJECT_OT_gpencil_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
@@ -1413,6 +1507,7 @@ void OBJECT_OT_gpencil_add(wmOperatorType *ot)
|
||||
ED_object_add_generic_props(ot, false);
|
||||
|
||||
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_object_gpencil_type_items, 0, "Type", "");
|
||||
RNA_def_enum_funcs(ot->prop, object_gpencil_add_options);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@@ -66,6 +66,10 @@ if(WITH_FREESTYLE)
|
||||
add_definitions(-DWITH_FREESTYLE)
|
||||
endif()
|
||||
|
||||
if(WITH_LINEART)
|
||||
add_definitions(-DWITH_LINEART)
|
||||
endif()
|
||||
|
||||
if(WITH_INTERNATIONAL)
|
||||
add_definitions(-DWITH_INTERNATIONAL)
|
||||
endif()
|
||||
|
@@ -56,6 +56,10 @@
|
||||
#include "ED_render.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#ifdef WITH_LINEART
|
||||
# include "ED_lineart.h"
|
||||
#endif
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
@@ -98,6 +102,15 @@ void ED_render_view3d_update(Depsgraph *depsgraph,
|
||||
CTX_wm_area_set(C, area);
|
||||
CTX_wm_region_set(C, region);
|
||||
|
||||
#ifdef WITH_LINEART
|
||||
/* TODO: Needs some specific flag in the render pipeline that marks line art for update, that
|
||||
* way we could avoid some unecessary updating.
|
||||
*/
|
||||
if (updated) {
|
||||
ED_lineart_post_frame_update_external(C, scene, depsgraph, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
engine->flag &= ~RE_ENGINE_DO_UPDATE;
|
||||
/* NOTE: Important to pass non-updated depsgraph, This is because this function is called
|
||||
* from inside dependency graph evaluation. Additionally, if we pass fully evaluated one
|
||||
|
@@ -58,4 +58,8 @@ set(LIB
|
||||
bf_editor_space_view3d
|
||||
)
|
||||
|
||||
if(WITH_LINEART)
|
||||
add_definitions(-DWITH_LINEART)
|
||||
endif()
|
||||
|
||||
blender_add_lib(bf_editor_space_api "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
@@ -68,6 +68,10 @@
|
||||
#include "ED_util.h"
|
||||
#include "ED_uvedit.h"
|
||||
|
||||
#ifdef WITH_LINEART
|
||||
# include "ED_lineart.h"
|
||||
#endif
|
||||
|
||||
#include "io_ops.h"
|
||||
|
||||
/* Only called once on startup. storage is global in BKE kernel listbase. */
|
||||
@@ -127,6 +131,10 @@ void ED_spacetypes_init(void)
|
||||
ED_operatortypes_view2d();
|
||||
ED_operatortypes_ui();
|
||||
|
||||
#ifdef WITH_LINEART
|
||||
ED_operatortypes_lineart();
|
||||
#endif
|
||||
|
||||
ED_screen_user_menu_register();
|
||||
|
||||
/* Gizmo types. */
|
||||
|
@@ -55,4 +55,8 @@ if(WITH_EXPERIMENTAL_FEATURES)
|
||||
add_definitions(-DWITH_HAIR_NODES)
|
||||
endif()
|
||||
|
||||
if(WITH_LINEART)
|
||||
add_definitions(-DWITH_LINEART)
|
||||
endif()
|
||||
|
||||
blender_add_lib(bf_editor_space_buttons "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_linestyle_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
@@ -153,6 +154,29 @@ static bool buttons_context_path_world(ButsContextPath *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool buttons_context_path_collection(ButsContextPath *path, wmWindow *window)
|
||||
{
|
||||
PointerRNA *ptr = &path->ptr[path->len - 1];
|
||||
|
||||
/* if we already have a (pinned) collection, we're done */
|
||||
if (RNA_struct_is_a(ptr->type, &RNA_Collection)) {
|
||||
return true;
|
||||
}
|
||||
/* if we have a view layer, use the view layer's active collection */
|
||||
else if (buttons_context_path_view_layer(path, window)) {
|
||||
ViewLayer *view_layer = path->ptr[path->len - 1].data;
|
||||
Collection *c = view_layer->active_collection->collection;
|
||||
if (c) {
|
||||
RNA_id_pointer_create(&c->id, &path->ptr[path->len]);
|
||||
path->len++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* no path to a collection possible */
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool buttons_context_path_linestyle(ButsContextPath *path, wmWindow *window)
|
||||
{
|
||||
PointerRNA *ptr = &path->ptr[path->len - 1];
|
||||
@@ -575,6 +599,13 @@ static bool buttons_context_path(
|
||||
case BCONTEXT_WORLD:
|
||||
found = buttons_context_path_world(path);
|
||||
break;
|
||||
case BCONTEXT_COLLECTION: /* This is for Line Art collection flags */
|
||||
#ifdef WITH_LINEART
|
||||
found = buttons_context_path_collection(path, window);
|
||||
#else
|
||||
BLI_assert(!"'WITH_LINEART' is off.");
|
||||
#endif
|
||||
break;
|
||||
case BCONTEXT_TOOL:
|
||||
found = true;
|
||||
break;
|
||||
@@ -858,6 +889,10 @@ int /*eContextResult*/ buttons_context(const bContext *C,
|
||||
set_pointer_type(path, result, &RNA_World);
|
||||
return CTX_RESULT_OK;
|
||||
}
|
||||
if (CTX_data_equals(member, "collection")) {
|
||||
set_pointer_type(path, result, &RNA_Collection);
|
||||
return 1;
|
||||
}
|
||||
if (CTX_data_equals(member, "object")) {
|
||||
set_pointer_type(path, result, &RNA_Object);
|
||||
return CTX_RESULT_OK;
|
||||
|
@@ -194,6 +194,10 @@ int ED_buttons_tabs_list(SpaceProperties *sbuts, short *context_tabs_array)
|
||||
context_tabs_array[length] = BCONTEXT_VIEW_LAYER;
|
||||
length++;
|
||||
}
|
||||
if (sbuts->pathflag & (1 << BCONTEXT_VIEW_LAYER)) {
|
||||
context_tabs_array[length] = BCONTEXT_COLLECTION;
|
||||
length++;
|
||||
}
|
||||
if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) {
|
||||
context_tabs_array[length] = BCONTEXT_SCENE;
|
||||
length++;
|
||||
@@ -271,6 +275,12 @@ static const char *buttons_main_region_context_string(const short mainb)
|
||||
return "view_layer";
|
||||
case BCONTEXT_WORLD:
|
||||
return "world";
|
||||
case BCONTEXT_COLLECTION:
|
||||
#ifdef WITH_LINEART
|
||||
return "collection";
|
||||
#else
|
||||
BLI_assert(!"'WITH_LINEART' is off.");
|
||||
#endif
|
||||
case BCONTEXT_OBJECT:
|
||||
return "object";
|
||||
case BCONTEXT_DATA:
|
||||
|
@@ -91,6 +91,10 @@ if(WITH_FREESTYLE)
|
||||
add_definitions(-DWITH_FREESTYLE)
|
||||
endif()
|
||||
|
||||
if(WITH_LINEART)
|
||||
add_definitions(-DWITH_LINEART)
|
||||
endif()
|
||||
|
||||
if(WITH_XR_OPENXR)
|
||||
add_definitions(-DWITH_XR_OPENXR)
|
||||
endif()
|
||||
|
@@ -1149,6 +1149,11 @@ static void view3d_main_region_message_subscribe(const wmRegionMessageSubscribeP
|
||||
}
|
||||
|
||||
WM_msg_subscribe_rna_anon_type(mbus, SceneEEVEE, &msg_sub_value_region_tag_redraw);
|
||||
|
||||
#ifdef WITH_LINEART
|
||||
WM_msg_subscribe_rna_anon_type(mbus, SceneLineArt, &msg_sub_value_region_tag_redraw);
|
||||
#endif
|
||||
|
||||
WM_msg_subscribe_rna_anon_type(mbus, SceneDisplay, &msg_sub_value_region_tag_redraw);
|
||||
WM_msg_subscribe_rna_anon_type(mbus, ObjectDisplay, &msg_sub_value_region_tag_redraw);
|
||||
|
||||
|
@@ -65,6 +65,7 @@ set(SRC
|
||||
../include/ED_keyframes_draw.h
|
||||
../include/ED_keyframes_edit.h
|
||||
../include/ED_keyframing.h
|
||||
../include/ED_lineart.h
|
||||
../include/ED_lattice.h
|
||||
../include/ED_markers.h
|
||||
../include/ED_mask.h
|
||||
@@ -114,6 +115,10 @@ if(WITH_INTERNATIONAL)
|
||||
add_definitions(-DWITH_INTERNATIONAL)
|
||||
endif()
|
||||
|
||||
if(WITH_LINEART)
|
||||
add_definitions(-DWITH_LINEART)
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON)
|
||||
add_definitions(-DWITH_PYTHON)
|
||||
list(APPEND INC
|
||||
|
@@ -50,6 +50,7 @@
|
||||
|
||||
#include "ED_armature.h"
|
||||
#include "ED_image.h"
|
||||
#include "ED_lineart.h"
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_paint.h"
|
||||
@@ -174,6 +175,11 @@ void ED_editors_init(bContext *C)
|
||||
|
||||
SWAP(int, reports->flag, reports_flag_prev);
|
||||
wm->op_undo_depth--;
|
||||
|
||||
/* Line Art data lock duing async calculation */
|
||||
#ifdef WITH_LINEART
|
||||
ED_lineart_init_locks();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* frees all editmode stuff */
|
||||
@@ -231,6 +237,11 @@ void ED_editors_exit(Main *bmain, bool do_undo_system)
|
||||
/* global in meshtools... */
|
||||
ED_mesh_mirror_spatial_table_end(NULL);
|
||||
ED_mesh_mirror_topo_table_end(NULL);
|
||||
|
||||
/* Line Art data*/
|
||||
#ifdef WITH_LINEART
|
||||
ED_lineart_destroy_render_data_external();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ED_editors_flush_edits_for_object_ex(Main *bmain,
|
||||
|
@@ -53,6 +53,7 @@ set(SRC
|
||||
intern/MOD_gpencilbuild.c
|
||||
intern/MOD_gpencilcolor.c
|
||||
intern/MOD_gpencilhook.c
|
||||
intern/MOD_gpencillineart.c
|
||||
intern/MOD_gpencillattice.c
|
||||
intern/MOD_gpencilmirror.c
|
||||
intern/MOD_gpencilmultiply.c
|
||||
@@ -79,6 +80,11 @@ if(WITH_INTERNATIONAL)
|
||||
add_definitions(-DWITH_INTERNATIONAL)
|
||||
endif()
|
||||
|
||||
if(WITH_LINEART)
|
||||
add_definitions(-DWITH_LINEART)
|
||||
endif()
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_gpencil_modifiers "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
||||
|
@@ -43,6 +43,7 @@ extern GpencilModifierTypeInfo modifierType_Gpencil_Armature;
|
||||
extern GpencilModifierTypeInfo modifierType_Gpencil_Time;
|
||||
extern GpencilModifierTypeInfo modifierType_Gpencil_Multiply;
|
||||
extern GpencilModifierTypeInfo modifierType_Gpencil_Texture;
|
||||
extern GpencilModifierTypeInfo modifierType_Gpencil_Lineart;
|
||||
|
||||
/* MOD_gpencil_util.c */
|
||||
void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[]);
|
||||
|
@@ -74,6 +74,7 @@ void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[])
|
||||
INIT_GP_TYPE(Time);
|
||||
INIT_GP_TYPE(Multiply);
|
||||
INIT_GP_TYPE(Texture);
|
||||
INIT_GP_TYPE(Lineart);
|
||||
#undef INIT_GP_TYPE
|
||||
}
|
||||
|
||||
|
@@ -179,7 +179,9 @@ static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
|
||||
return !mmd->object || mmd->object->type != OB_ARMATURE;
|
||||
}
|
||||
|
||||
static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
|
||||
static void updateDepsgraph(GpencilModifierData *md,
|
||||
const ModifierUpdateDepsgraphContext *ctx,
|
||||
const int UNUSED(mode))
|
||||
{
|
||||
ArmatureGpencilModifierData *lmd = (ArmatureGpencilModifierData *)md;
|
||||
if (lmd->object != NULL) {
|
||||
|
@@ -318,7 +318,9 @@ static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Objec
|
||||
generate_geometry(md, depsgraph, scene, ob);
|
||||
}
|
||||
|
||||
static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
|
||||
static void updateDepsgraph(GpencilModifierData *md,
|
||||
const ModifierUpdateDepsgraphContext *ctx,
|
||||
const int UNUSED(mode))
|
||||
{
|
||||
ArrayGpencilModifierData *lmd = (ArrayGpencilModifierData *)md;
|
||||
if (lmd->object != NULL) {
|
||||
|
@@ -330,7 +330,9 @@ static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
|
||||
return !mmd->object;
|
||||
}
|
||||
|
||||
static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
|
||||
static void updateDepsgraph(GpencilModifierData *md,
|
||||
const ModifierUpdateDepsgraphContext *ctx,
|
||||
const int UNUSED(mode))
|
||||
{
|
||||
HookGpencilModifierData *lmd = (HookGpencilModifierData *)md;
|
||||
if (lmd->object != NULL) {
|
||||
|
@@ -195,7 +195,9 @@ static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
|
||||
return !mmd->object || mmd->object->type != OB_LATTICE;
|
||||
}
|
||||
|
||||
static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
|
||||
static void updateDepsgraph(GpencilModifierData *md,
|
||||
const ModifierUpdateDepsgraphContext *ctx,
|
||||
const int UNUSED(mode))
|
||||
{
|
||||
LatticeGpencilModifierData *lmd = (LatticeGpencilModifierData *)md;
|
||||
if (lmd->object != NULL) {
|
||||
|
484
source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
Normal file
484
source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
Normal file
@@ -0,0 +1,484 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2017, Blender Foundation
|
||||
* This is a new part of Blender
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup modifiers
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_gpencil_modifier_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_lineart_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "ED_lineart.h"
|
||||
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_gpencil.h"
|
||||
#include "BKE_gpencil_modifier.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "BKE_modifier.h"
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "MOD_gpencil_modifiertypes.h"
|
||||
#include "MOD_gpencil_ui_common.h"
|
||||
#include "MOD_gpencil_util.h"
|
||||
|
||||
#include "ED_lineart.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
extern LineartSharedResource lineart_share;
|
||||
|
||||
static void initData(GpencilModifierData *md)
|
||||
{
|
||||
LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md;
|
||||
lmd->line_types = LRT_EDGE_FLAG_ALL_TYPE;
|
||||
lmd->thickness = 25;
|
||||
lmd->opacity = 1.0f;
|
||||
lmd->flags |= LRT_GPENCIL_MATCH_OUTPUT_VGROUP;
|
||||
}
|
||||
|
||||
static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
|
||||
{
|
||||
BKE_gpencil_modifier_copydata_generic(md, target);
|
||||
}
|
||||
|
||||
static void generate_strokes_actual(
|
||||
GpencilModifierData *md, Depsgraph *depsgraph, Object *ob, bGPDlayer *gpl, bGPDframe *gpf)
|
||||
{
|
||||
LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md;
|
||||
|
||||
if (G.debug_value == 4000) {
|
||||
printf("LRT: Generating from modifier.\n");
|
||||
}
|
||||
|
||||
ED_lineart_gpencil_generate_with_type(
|
||||
depsgraph,
|
||||
ob,
|
||||
gpl,
|
||||
gpf,
|
||||
lmd->source_type,
|
||||
lmd->source_type == LRT_SOURCE_OBJECT ? (void *)lmd->source_object :
|
||||
(void *)lmd->source_collection,
|
||||
lmd->level_start,
|
||||
lmd->use_multiple_levels ? lmd->level_end : lmd->level_start,
|
||||
lmd->target_material ? BKE_gpencil_object_material_index_get(ob, lmd->target_material) : 0,
|
||||
lmd->line_types,
|
||||
lmd->transparency_flags,
|
||||
lmd->transparency_mask,
|
||||
lmd->thickness,
|
||||
lmd->opacity,
|
||||
lmd->pre_sample_length,
|
||||
lmd->source_vertex_group,
|
||||
lmd->vgname,
|
||||
lmd->flags);
|
||||
}
|
||||
|
||||
static bool isModifierDisabled(GpencilModifierData *md)
|
||||
{
|
||||
LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md;
|
||||
|
||||
if ((lmd->target_layer[0] == '\0') || (lmd->target_material == NULL)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lmd->source_type == LRT_SOURCE_OBJECT && !lmd->source_object) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lmd->source_type == LRT_SOURCE_COLLECTION && !lmd->source_collection) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Object *ob)
|
||||
{
|
||||
LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md;
|
||||
bGPdata *gpd = ob->data;
|
||||
|
||||
Scene *s = DEG_get_evaluated_scene(depsgraph);
|
||||
if (!(s->lineart.flags & LRT_AUTO_UPDATE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Guard early, don't trigger calculation when no gpencil frame is present. Probably should
|
||||
* disable in the isModifierDisabled() function but we need addtional arg for depsgraph and
|
||||
* gpd. */
|
||||
bGPDlayer *gpl = BKE_gpencil_layer_get_by_name(gpd, lmd->target_layer, 1);
|
||||
if (gpl == NULL) {
|
||||
return;
|
||||
}
|
||||
/* Need to call this or we don't get active frame (user may haven't selected any one). */
|
||||
BKE_gpencil_frame_active_set(depsgraph, gpd);
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
if (gpf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
|
||||
|
||||
if (ED_lineart_modifier_sync_flag_check(LRT_SYNC_IGNORE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check all parameters required are filled. */
|
||||
if (isModifierDisabled(md)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ED_lineart_modifier_sync_flag_check(LRT_SYNC_IDLE)) {
|
||||
/* Update triggered when nothing's happening, means DG update, so we request a refresh on line
|
||||
* art cache, meanwhile waiting for result. Update will trigger again. */
|
||||
ED_lineart_modifier_sync_flag_set(LRT_SYNC_WAITING, true);
|
||||
/* Don't have data yet, update line art. Note: ED_lineart_post_frame_update_external will
|
||||
* automatically return when calculation is already in progress.*/
|
||||
if (is_render) {
|
||||
|
||||
if (G.debug_value == 4000) {
|
||||
printf("LRT: -------- Modifier calls for update when idle.\n");
|
||||
}
|
||||
ED_lineart_post_frame_update_external(
|
||||
NULL, DEG_get_evaluated_scene(depsgraph), depsgraph, true);
|
||||
while (!ED_lineart_modifier_sync_flag_check(LRT_SYNC_FRESH) ||
|
||||
!ED_lineart_calculation_flag_check(LRT_RENDER_FINISHED)) {
|
||||
/* Wait till it's done. */
|
||||
}
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (ED_lineart_modifier_sync_flag_check(LRT_SYNC_WAITING)) {
|
||||
if (G.debug_value == 4000) {
|
||||
printf("LRT: -------- Modifier is waiting for data in LRT_SYNC_WAITING.\n");
|
||||
}
|
||||
/* Calculation in process. */
|
||||
if (is_render) {
|
||||
while (!ED_lineart_modifier_sync_flag_check(LRT_SYNC_FRESH) ||
|
||||
!ED_lineart_calculation_flag_check(LRT_RENDER_FINISHED)) {
|
||||
/* Wait till it's done. */
|
||||
}
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (G.debug_value == 4000) {
|
||||
printf("(is_render == %d) ", is_render);
|
||||
}
|
||||
|
||||
/* If we reach here, means calculation is finished (LRT_SYNC_FRESH), we grab cache. flag reset is
|
||||
* done by calculation function.*/
|
||||
generate_strokes_actual(md, depsgraph, ob, gpl, gpf);
|
||||
|
||||
WM_main_add_notifier(NA_EDITED | NC_GPENCIL, NULL);
|
||||
}
|
||||
|
||||
static void bakeModifier(Main *UNUSED(bmain),
|
||||
Depsgraph *depsgraph,
|
||||
GpencilModifierData *md,
|
||||
Object *ob)
|
||||
{
|
||||
|
||||
bGPdata *gpd = ob->data;
|
||||
LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md;
|
||||
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||
|
||||
bGPDlayer *gpl = BKE_gpencil_layer_get_by_name(gpd, lmd->target_layer, 1);
|
||||
if (gpl == NULL) {
|
||||
return;
|
||||
}
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
if (gpf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (scene->lineart.flags & LRT_AUTO_UPDATE) {
|
||||
if (ED_lineart_modifier_sync_flag_check(LRT_SYNC_IDLE)) {
|
||||
/* Need to run it once again. */
|
||||
ED_lineart_modifier_sync_flag_set(LRT_SYNC_WAITING, true);
|
||||
BLI_spin_lock(&lineart_share.lock_loader);
|
||||
ED_lineart_compute_feature_lines_background(depsgraph, 1);
|
||||
/* Wait for loading finish. */
|
||||
BLI_spin_lock(&lineart_share.lock_loader);
|
||||
BLI_spin_unlock(&lineart_share.lock_loader);
|
||||
}
|
||||
while (!ED_lineart_modifier_sync_flag_check(LRT_SYNC_FRESH) ||
|
||||
!ED_lineart_calculation_flag_check(LRT_RENDER_FINISHED)) {
|
||||
/* Wait till it's done. */
|
||||
}
|
||||
}
|
||||
else if (!ED_lineart_modifier_sync_flag_check(LRT_SYNC_FRESH) ||
|
||||
!ED_lineart_modifier_sync_flag_check(LRT_SYNC_IDLE)) {
|
||||
/* If not auto updating, and the cache isn't available, then do not generate strokes. */
|
||||
return;
|
||||
}
|
||||
|
||||
generate_strokes_actual(md, depsgraph, ob, gpl, gpf);
|
||||
}
|
||||
|
||||
static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
|
||||
{
|
||||
return isModifierDisabled(md);
|
||||
}
|
||||
|
||||
static void updateDepsgraph(GpencilModifierData *md,
|
||||
const ModifierUpdateDepsgraphContext *ctx,
|
||||
const int mode)
|
||||
{
|
||||
DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Line Art Modifier");
|
||||
|
||||
LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md;
|
||||
if (lmd->source_type == LRT_SOURCE_OBJECT && lmd->source_object) {
|
||||
DEG_add_object_relation(
|
||||
ctx->node, lmd->source_object, DEG_OB_COMP_GEOMETRY, "Line Art Modifier");
|
||||
DEG_add_object_relation(
|
||||
ctx->node, lmd->source_object, DEG_OB_COMP_TRANSFORM, "Line Art Modifier");
|
||||
}
|
||||
else {
|
||||
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (ctx->scene->master_collection, ob, mode) {
|
||||
if (ob->type == OB_MESH || ob->type == OB_MBALL || ob->type == OB_CURVE ||
|
||||
ob->type == OB_SURF || ob->type == OB_FONT) {
|
||||
if (!(ob->lineart.usage & COLLECTION_LRT_EXCLUDE)) {
|
||||
DEG_add_object_relation(ctx->node, ob, DEG_OB_COMP_GEOMETRY, "Line Art Modifier");
|
||||
DEG_add_object_relation(ctx->node, ob, DEG_OB_COMP_TRANSFORM, "Line Art Modifier");
|
||||
}
|
||||
}
|
||||
}
|
||||
FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END;
|
||||
}
|
||||
DEG_add_object_relation(
|
||||
ctx->node, ctx->scene->camera, DEG_OB_COMP_TRANSFORM, "Line Art Modifier");
|
||||
}
|
||||
|
||||
static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
|
||||
{
|
||||
LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md;
|
||||
|
||||
walk(userData, ob, (ID **)&lmd->target_material, IDWALK_CB_USER);
|
||||
walk(userData, ob, (ID **)&lmd->source_collection, IDWALK_CB_NOP);
|
||||
|
||||
walk(userData, ob, (ID **)&lmd->source_object, IDWALK_CB_NOP);
|
||||
}
|
||||
|
||||
static void panel_draw(const bContext *C, Panel *panel)
|
||||
{
|
||||
uiLayout *layout = panel->layout;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
PointerRNA ob_ptr;
|
||||
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, &ob_ptr);
|
||||
|
||||
PointerRNA obj_data_ptr = RNA_pointer_get(&ob_ptr, "data");
|
||||
|
||||
int source_type = RNA_enum_get(ptr, "source_type");
|
||||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
|
||||
uiItemR(layout, ptr, "source_type", 0, NULL, ICON_NONE);
|
||||
|
||||
if (source_type == LRT_SOURCE_OBJECT) {
|
||||
uiItemR(layout, ptr, "source_object", 0, NULL, ICON_CUBE);
|
||||
}
|
||||
else if (source_type == LRT_SOURCE_COLLECTION) {
|
||||
uiItemR(layout, ptr, "source_collection", 0, NULL, ICON_OUTLINER_COLLECTION);
|
||||
}
|
||||
|
||||
if (scene->lineart.flags & LRT_EVERYTHING_AS_CONTOUR) {
|
||||
uiItemL(layout, "Line types are fuzzy", ICON_NONE);
|
||||
}
|
||||
else {
|
||||
uiLayout *column = uiLayoutColumn(layout, true);
|
||||
if (scene->lineart.line_types & LRT_EDGE_FLAG_CONTOUR) {
|
||||
uiItemR(column, ptr, "use_contour", 0, NULL, ICON_NONE);
|
||||
}
|
||||
if (scene->lineart.line_types & LRT_EDGE_FLAG_CREASE) {
|
||||
uiItemR(column, ptr, "use_crease", 0, "Crease", ICON_NONE);
|
||||
}
|
||||
if (scene->lineart.line_types & LRT_EDGE_FLAG_MATERIAL) {
|
||||
uiItemR(column, ptr, "use_material", 0, "Material", ICON_NONE);
|
||||
}
|
||||
if (scene->lineart.line_types & LRT_EDGE_FLAG_EDGE_MARK) {
|
||||
uiItemR(column, ptr, "use_edge_mark", 0, "Edge Marks", ICON_NONE);
|
||||
}
|
||||
if (scene->lineart.flags & LRT_INTERSECTION_AS_CONTOUR) {
|
||||
uiItemL(column, "Intersection is fuzzy", ICON_NONE);
|
||||
}
|
||||
else {
|
||||
if (scene->lineart.line_types & LRT_EDGE_FLAG_INTERSECTION) {
|
||||
uiItemR(column, ptr, "use_intersection", 0, "Intersection", ICON_NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uiItemPointerR(layout, ptr, "target_layer", &obj_data_ptr, "layers", NULL, ICON_GREASEPENCIL);
|
||||
uiItemPointerR(
|
||||
layout, ptr, "target_material", &obj_data_ptr, "materials", NULL, ICON_SHADING_TEXTURE);
|
||||
|
||||
gpencil_modifier_panel_end(layout, ptr);
|
||||
}
|
||||
|
||||
static void style_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
||||
{
|
||||
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
|
||||
|
||||
uiLayout *layout = panel->layout;
|
||||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
|
||||
uiLayout *column = uiLayoutColumn(layout, true);
|
||||
|
||||
uiItemR(column, ptr, "thickness", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
|
||||
|
||||
uiItemR(column, ptr, "opacity", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
|
||||
|
||||
uiItemR(column, ptr, "pre_sample_length", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
static void occlusion_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
||||
{
|
||||
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
|
||||
|
||||
uiLayout *layout = panel->layout;
|
||||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
|
||||
bool use_multiple_levels = RNA_boolean_get(ptr, "use_multiple_levels");
|
||||
bool use_transparency = RNA_boolean_get(ptr, "use_transparency");
|
||||
|
||||
uiItemR(layout, ptr, "use_multiple_levels", 0, "Multiple Levels", ICON_NONE);
|
||||
|
||||
if (use_multiple_levels) {
|
||||
uiLayout *col = uiLayoutColumn(layout, true);
|
||||
uiItemR(col, ptr, "level_start", 0, NULL, ICON_NONE);
|
||||
uiItemR(col, ptr, "level_end", 0, NULL, ICON_NONE);
|
||||
}
|
||||
else {
|
||||
uiItemR(layout, ptr, "level_start", 0, "Level", ICON_NONE);
|
||||
}
|
||||
|
||||
uiItemR(layout, ptr, "use_transparency", 0, "Transparency", ICON_NONE);
|
||||
|
||||
uiLayout *column = uiLayoutColumn(layout, true);
|
||||
|
||||
if (use_transparency) {
|
||||
uiItemR(column, ptr, "transparency_match", 0, "Match", ICON_NONE);
|
||||
}
|
||||
|
||||
if (use_transparency) {
|
||||
uiLayout *row = uiLayoutRow(column, true);
|
||||
uiItemR(row, ptr, "transparency_mask_0", UI_ITEM_R_TOGGLE, "0", ICON_NONE);
|
||||
uiItemR(row, ptr, "transparency_mask_1", UI_ITEM_R_TOGGLE, "1", ICON_NONE);
|
||||
uiItemR(row, ptr, "transparency_mask_2", UI_ITEM_R_TOGGLE, "2", ICON_NONE);
|
||||
uiItemR(row, ptr, "transparency_mask_3", UI_ITEM_R_TOGGLE, "3", ICON_NONE);
|
||||
uiItemR(row, ptr, "transparency_mask_4", UI_ITEM_R_TOGGLE, "4", ICON_NONE);
|
||||
uiItemR(row, ptr, "transparency_mask_5", UI_ITEM_R_TOGGLE, "5", ICON_NONE);
|
||||
uiItemR(row, ptr, "transparency_mask_6", UI_ITEM_R_TOGGLE, "6", ICON_NONE);
|
||||
uiItemR(row, ptr, "transparency_mask_7", UI_ITEM_R_TOGGLE, "7", ICON_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
static void vgroup_panel_draw(const bContext *UNUSED(C), Panel *panel)
|
||||
{
|
||||
PointerRNA ob_ptr;
|
||||
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, &ob_ptr);
|
||||
|
||||
uiLayout *layout = panel->layout, *row;
|
||||
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
|
||||
uiLayout *column = uiLayoutColumn(layout, true);
|
||||
|
||||
row = uiLayoutRow(column, true);
|
||||
uiItemR(row, ptr, "source_vertex_group", 0, "Filter Source", ICON_GROUP_VERTEX);
|
||||
uiItemR(row, ptr, "invert_source_vertex_group", UI_ITEM_R_TOGGLE, "", ICON_ARROW_LEFTRIGHT);
|
||||
|
||||
uiItemR(column, ptr, "match_output_vertex_group", 0, NULL, ICON_NONE);
|
||||
|
||||
bool match_output = RNA_boolean_get(ptr, "match_output_vertex_group");
|
||||
if (!match_output) {
|
||||
uiItemPointerR(column, ptr, "vertex_group", &ob_ptr, "vertex_groups", "Target", ICON_NONE);
|
||||
}
|
||||
|
||||
uiItemR(layout, ptr, "soft_selection", 0, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
static void panelRegister(ARegionType *region_type)
|
||||
{
|
||||
PanelType *panel_type = gpencil_modifier_panel_register(
|
||||
region_type, eGpencilModifierType_Lineart, panel_draw);
|
||||
|
||||
gpencil_modifier_subpanel_register(
|
||||
region_type, "style", "Style", NULL, style_panel_draw, panel_type);
|
||||
gpencil_modifier_subpanel_register(
|
||||
region_type, "occlusion", "Occlusion", NULL, occlusion_panel_draw, panel_type);
|
||||
gpencil_modifier_subpanel_register(
|
||||
region_type, "vgroup", "Vertex Weight Transfer", NULL, vgroup_panel_draw, panel_type);
|
||||
}
|
||||
|
||||
GpencilModifierTypeInfo modifierType_Gpencil_Lineart = {
|
||||
/* name. */ "Line Art",
|
||||
/* structName. */ "LineartGpencilModifierData",
|
||||
/* structSize. */ sizeof(LineartGpencilModifierData),
|
||||
/* type. */ eGpencilModifierTypeType_Gpencil,
|
||||
/* flags. */ eGpencilModifierTypeFlag_SupportsEditmode,
|
||||
|
||||
/* copyData. */ copyData,
|
||||
|
||||
/* deformStroke. */ NULL,
|
||||
/* generateStrokes. */ generateStrokes,
|
||||
/* bakeModifier. */ bakeModifier,
|
||||
/* remapTime. */ NULL,
|
||||
|
||||
/* initData. */ initData,
|
||||
/* freeData. */ NULL,
|
||||
/* isDisabled. */ isDisabled,
|
||||
/* updateDepsgraph. */ updateDepsgraph,
|
||||
/* dependsOnTime. */ NULL,
|
||||
/* foreachIDLink. */ foreachIDLink,
|
||||
/* foreachTexLink. */ NULL,
|
||||
/* panelRegister. */ panelRegister,
|
||||
};
|
@@ -207,7 +207,9 @@ static bool isDisabled(GpencilModifierData *UNUSED(md), int UNUSED(userRenderPar
|
||||
return false;
|
||||
}
|
||||
|
||||
static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
|
||||
static void updateDepsgraph(GpencilModifierData *md,
|
||||
const ModifierUpdateDepsgraphContext *ctx,
|
||||
const int UNUSED(mode))
|
||||
{
|
||||
MirrorGpencilModifierData *lmd = (MirrorGpencilModifierData *)md;
|
||||
if (lmd->object != NULL) {
|
||||
|
@@ -311,7 +311,9 @@ static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
|
||||
return !mmd->object;
|
||||
}
|
||||
|
||||
static void updateDepsgraph(GpencilModifierData *md, const ModifierUpdateDepsgraphContext *ctx)
|
||||
static void updateDepsgraph(GpencilModifierData *md,
|
||||
const ModifierUpdateDepsgraphContext *ctx,
|
||||
const int UNUSED(mode))
|
||||
{
|
||||
TintGpencilModifierData *lmd = (TintGpencilModifierData *)md;
|
||||
if (lmd->object != NULL) {
|
||||
|
@@ -46,6 +46,14 @@ typedef struct CollectionChild {
|
||||
struct Collection *collection;
|
||||
} CollectionChild;
|
||||
|
||||
enum CollectionFeatureLine_Usage {
|
||||
COLLECTION_LRT_INCLUDE = 0,
|
||||
COLLECTION_LRT_OCCLUSION_ONLY = (1 << 0),
|
||||
COLLECTION_LRT_EXCLUDE = (1 << 1),
|
||||
COLLECTION_LRT_INTERSECTION_ONLY = (1 << 2),
|
||||
COLLECTION_LRT_NO_INTERSECTION = (1 << 3),
|
||||
};
|
||||
|
||||
typedef struct Collection {
|
||||
ID id;
|
||||
|
||||
@@ -63,8 +71,10 @@ typedef struct Collection {
|
||||
/* Runtime-only, always cleared on file load. */
|
||||
short tag;
|
||||
|
||||
/** Line Art engine specific */
|
||||
short lineart_usage;
|
||||
|
||||
int16_t color_tag;
|
||||
char _pad[2];
|
||||
|
||||
/* Runtime. Cache of objects in this collection and all its
|
||||
* children. This is created on demand when e.g. some physics
|
||||
@@ -72,6 +82,9 @@ typedef struct Collection {
|
||||
* collections due to memory usage reasons. */
|
||||
ListBase object_cache;
|
||||
|
||||
/* Need this for line art sub-collection selections. */
|
||||
ListBase object_cache_instanced;
|
||||
|
||||
/* Runtime. List of collections that are a parent of this
|
||||
* datablock. */
|
||||
ListBase parents;
|
||||
@@ -89,6 +102,7 @@ enum {
|
||||
COLLECTION_RESTRICT_RENDER = (1 << 3), /* Disable in renders. */
|
||||
COLLECTION_HAS_OBJECT_CACHE = (1 << 4), /* Runtime: object_cache is populated. */
|
||||
COLLECTION_IS_MASTER = (1 << 5), /* Is master collection embedded in the scene. */
|
||||
COLLECTION_HAS_OBJECT_CACHE_INSTANCED = (1 << 6), /* for object_cache_instanced. */
|
||||
};
|
||||
|
||||
/* Collection->tag */
|
||||
|
@@ -53,6 +53,7 @@ typedef enum GpencilModifierType {
|
||||
eGpencilModifierType_Time = 16,
|
||||
eGpencilModifierType_Multiply = 17,
|
||||
eGpencilModifierType_Texture = 18,
|
||||
eGpencilModifierType_Lineart = 19,
|
||||
/* Keep last. */
|
||||
NUM_GREASEPENCIL_MODIFIER_TYPES,
|
||||
} GpencilModifierType;
|
||||
@@ -809,6 +810,59 @@ typedef enum eTextureGpencil_Mode {
|
||||
STROKE_AND_FILL = 2,
|
||||
} eTextureGpencil_Mode;
|
||||
|
||||
typedef enum eLineartGpencilModifierSource {
|
||||
LRT_SOURCE_COLLECTION = 0,
|
||||
LRT_SOURCE_OBJECT = 1,
|
||||
LRT_SOURCE_SCENE = 2,
|
||||
} eLineartGpencilModifierSource;
|
||||
|
||||
typedef enum eLineArtGPencilModifierFlags {
|
||||
LRT_GPENCIL_INVERT_SOURCE_VGROUP = (1 << 0),
|
||||
LRT_GPENCIL_MATCH_OUTPUT_VGROUP = (1 << 1),
|
||||
LRT_GPENCIL_SOFT_SELECTION = (1 << 2),
|
||||
} eLineArtGPencilModifierFlags;
|
||||
|
||||
typedef enum eLineartGpencilTransparencyFlags {
|
||||
LRT_GPENCIL_TRANSPARENCY_ENABLE = (1 << 0),
|
||||
/** Set to true means using "and" instead of "or" logic on mask bits. */
|
||||
LRT_GPENCIL_TRANSPARENCY_MATCH = (1 << 1),
|
||||
} eLineartGpencilTransparencyFlags;
|
||||
|
||||
typedef struct LineartGpencilModifierData {
|
||||
GpencilModifierData modifier;
|
||||
|
||||
short line_types; /* line type enable flags, bits in eLineartEdgeFlag */
|
||||
|
||||
char source_type; /* Object or Collection, from eLineartGpencilModifierSource */
|
||||
|
||||
char use_multiple_levels;
|
||||
short level_start;
|
||||
short level_end;
|
||||
|
||||
struct Object *source_object;
|
||||
struct Collection *source_collection;
|
||||
|
||||
struct Material *target_material;
|
||||
char target_layer[64];
|
||||
|
||||
/** These two variables are to pass on vertex group information from mesh to strokes.
|
||||
* vgname specifies which vertex groups our strokes from source_vertex_group will go to. */
|
||||
char source_vertex_group[64];
|
||||
char vgname[64];
|
||||
|
||||
float opacity;
|
||||
short thickness;
|
||||
|
||||
unsigned char transparency_flags; /* eLineartGpencilTransparencyFlags */
|
||||
unsigned char transparency_mask;
|
||||
|
||||
float pre_sample_length;
|
||||
|
||||
/* Additional Switches */
|
||||
int flags;
|
||||
|
||||
} LineartGpencilModifierData;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -412,6 +412,8 @@ typedef enum eGPDframe_Flag {
|
||||
GP_FRAME_PAINT = (1 << 0),
|
||||
/* for editing in Action Editor */
|
||||
GP_FRAME_SELECT = (1 << 1),
|
||||
/* Line Art generation */
|
||||
GP_FRAME_LRT_CLEARED = (1 << 2),
|
||||
} eGPDframe_Flag;
|
||||
|
||||
/* ***************************************** */
|
||||
|
70
source/blender/makesdna/DNA_lineart_types.h
Normal file
70
source/blender/makesdna/DNA_lineart_types.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2010 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef __DNA_LRT_TYPES_H__
|
||||
#define __DNA_LRT_TYPES_H__
|
||||
|
||||
/** \file DNA_lineart_types.h
|
||||
* \ingroup DNA
|
||||
*/
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
struct Object;
|
||||
struct Material;
|
||||
|
||||
/* Notice that we need to have this file although no struct defines.
|
||||
* Edge flags and usage flags are used by with scene/object/gpencil modifier bits, and those values
|
||||
* needs to stay consistent throughout. */
|
||||
|
||||
typedef enum eLineartEdgeFlag {
|
||||
LRT_EDGE_FLAG_EDGE_MARK = (1 << 0),
|
||||
LRT_EDGE_FLAG_CONTOUR = (1 << 1),
|
||||
LRT_EDGE_FLAG_CREASE = (1 << 2),
|
||||
LRT_EDGE_FLAG_MATERIAL = (1 << 3),
|
||||
LRT_EDGE_FLAG_INTERSECTION = (1 << 4),
|
||||
/** floating edge, unimplemented yet */
|
||||
LRT_EDGE_FLAG_FLOATING = (1 << 5),
|
||||
/** also used as discarded line mark */
|
||||
LRT_EDGE_FLAG_CHAIN_PICKED = (1 << 6),
|
||||
LRT_EDGE_FLAG_CLIPPED = (1 << 7),
|
||||
/* Maxed out for 8 bits, DON'T ADD ANYMORE until improvements on the data structure. */
|
||||
} eLineartEdgeFlag;
|
||||
|
||||
#define LRT_EDGE_FLAG_ALL_TYPE 0x3f
|
||||
|
||||
typedef enum eLineartModeFlags {
|
||||
LRT_LINE_LAYER_USE_SAME_STYLE = (1 << 0), /* Share with object lineart flags */
|
||||
LRT_LINE_LAYER_USE_MULTIPLE_LEVELS = (1 << 1), /* Share with object lineart flags */
|
||||
LRT_LINE_LAYER_NORMAL_ENABLED = (1 << 2),
|
||||
LRT_LINE_LAYER_NORMAL_INVERSE = (1 << 3),
|
||||
LRT_LINE_LAYER_REPLACE_STROKES = (1 << 4),
|
||||
LRT_LINE_LAYER_COLLECTION_FORCE = (1 << 5),
|
||||
} eLineartModeFlags;
|
||||
|
||||
#endif
|
@@ -145,6 +145,16 @@ typedef enum eMaterialGPencilStyle_Mode {
|
||||
GP_MATERIAL_MODE_SQUARE = 2,
|
||||
} eMaterialGPencilStyle_Mode;
|
||||
|
||||
typedef struct MaterialLineArt {
|
||||
int flags; /* eMaterialLineArtFlags */
|
||||
unsigned char transparency_mask;
|
||||
unsigned char _pad[3];
|
||||
} MaterialLineArt;
|
||||
|
||||
typedef enum eMaterialLineArtFlags {
|
||||
LRT_MATERIAL_TRANSPARENCY_ENABLED = (1 << 0),
|
||||
} eMaterialLineArtFlags;
|
||||
|
||||
typedef struct Material {
|
||||
ID id;
|
||||
/** Animation data (must be immediately after id for utilities to use it). */
|
||||
@@ -210,6 +220,7 @@ typedef struct Material {
|
||||
|
||||
/** Grease pencil color. */
|
||||
struct MaterialGPencilStyle *gp_style;
|
||||
struct MaterialLineArt lineart;
|
||||
} Material;
|
||||
|
||||
/* **************** MATERIAL ********************* */
|
||||
|
@@ -66,6 +66,7 @@
|
||||
.preview = NULL, \
|
||||
.duplicator_visibility_flag = OB_DUPLI_FLAG_VIEWPORT | OB_DUPLI_FLAG_RENDER, \
|
||||
.pc_ids = {NULL, NULL}, \
|
||||
.lineart = { .crease_threshold = DEG2RAD(140.0f) }, \
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@@ -26,6 +26,11 @@
|
||||
|
||||
#include "DNA_object_enums.h"
|
||||
|
||||
#include "DNA_customdata_types.h"
|
||||
#include "DNA_defs.h"
|
||||
#include "DNA_lineart_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_action_types.h" /* bAnimVizSettings */
|
||||
#include "DNA_customdata_types.h"
|
||||
@@ -200,6 +205,27 @@ typedef struct Object_Runtime {
|
||||
short _pad2[3];
|
||||
} Object_Runtime;
|
||||
|
||||
typedef struct ObjectLineArt {
|
||||
short usage;
|
||||
short flags;
|
||||
|
||||
/** if OBJECT_LRT_OWN_CREASE is set */
|
||||
float crease_threshold;
|
||||
} ObjectLineArt;
|
||||
|
||||
enum ObjectFeatureLine_Usage {
|
||||
OBJECT_LRT_INHERENT = 0,
|
||||
OBJECT_LRT_INCLUDE = (1 << 0),
|
||||
OBJECT_LRT_OCCLUSION_ONLY = (1 << 1),
|
||||
OBJECT_LRT_EXCLUDE = (1 << 2),
|
||||
OBJECT_LRT_INTERSECTION_ONLY = (1 << 3),
|
||||
OBJECT_LRT_NO_INTERSECTION = (1 << 4),
|
||||
};
|
||||
|
||||
enum ObjectFeatureLine_Flags {
|
||||
OBJECT_LRT_OWN_CREASE = (1 << 0),
|
||||
};
|
||||
|
||||
typedef struct Object {
|
||||
ID id;
|
||||
/** Animation data (must be immediately after id for utilities to use it). */
|
||||
@@ -405,6 +431,8 @@ typedef struct Object {
|
||||
|
||||
struct PreviewImage *preview;
|
||||
|
||||
ObjectLineArt lineart;
|
||||
|
||||
/** Runtime evaluation data (keep last). */
|
||||
Object_Runtime runtime;
|
||||
} Object;
|
||||
@@ -595,6 +623,9 @@ enum {
|
||||
GP_EMPTY = 0,
|
||||
GP_STROKE = 1,
|
||||
GP_MONKEY = 2,
|
||||
GP_LRT_SCENE = 3,
|
||||
GP_LRT_OBJECT = 4,
|
||||
GP_LRT_COLLECTION = 5,
|
||||
};
|
||||
|
||||
/* boundtype */
|
||||
|
@@ -238,6 +238,17 @@
|
||||
SCE_EEVEE_GTAO_BOUNCE | SCE_EEVEE_TAA_REPROJECTION | \
|
||||
SCE_EEVEE_SSR_HALF_RESOLUTION | SCE_EEVEE_SHADOW_SOFT, \
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define _DNA_DEFAULT_SceneLineArt \
|
||||
{ \
|
||||
.crease_threshold = DEG2RAD(140.0f),\
|
||||
.angle_splitting_threshold = DEG2RAD(60.0f),\
|
||||
.chaining_geometry_threshold = 0.001f,\
|
||||
.chaining_image_threshold = 0.001f,\
|
||||
}
|
||||
|
||||
|
||||
#define _DNA_DEFAULT_Scene \
|
||||
{ \
|
||||
@@ -252,6 +263,7 @@
|
||||
.safe_areas = _DNA_DEFAULT_DisplaySafeAreas, \
|
||||
\
|
||||
.eevee = _DNA_DEFAULT_SceneEEVEE, \
|
||||
.lineart = _DNA_DEFAULT_SceneLineArt, \
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "DNA_color_types.h" /* color management */
|
||||
#include "DNA_customdata_types.h" /* Scene's runtime cddata masks. */
|
||||
#include "DNA_layer_types.h"
|
||||
#include "DNA_lineart_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_vec_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
@@ -1658,6 +1659,62 @@ typedef struct SceneEEVEE {
|
||||
float light_threshold;
|
||||
} SceneEEVEE;
|
||||
|
||||
/* Line Art Global Settings */
|
||||
|
||||
typedef enum eLineartPostProcessingStatus {
|
||||
LRT_POST_PROCESSING_DISABLED = 0,
|
||||
LRT_POST_PROCESSING_ENABLED = 1,
|
||||
} eLineartPostProcessingStatus;
|
||||
|
||||
typedef enum eLineartMainFlags {
|
||||
LRT_ENABLED = (1 << 0), /* Deprecated right now. */
|
||||
/* For Line Art->GP and viewport to update automatically. */
|
||||
LRT_AUTO_UPDATE = (1 << 1),
|
||||
LRT_SAME_TAPER = (1 << 2),
|
||||
/* Edge split modifier will cause problems in Line Art. */
|
||||
LRT_DISABLE_EDGE_SPLITS = (1 << 3),
|
||||
LRT_USE_CHAINING = (1 << 4), /* Deprecated */
|
||||
LRT_USE_INTERSECTIONS = (1 << 5), /* Deprecated, use flags in line_types */
|
||||
/* Overwrite existing strokes in this frame. */
|
||||
LRT_GPENCIL_OVERWRITE = (1 << 6),
|
||||
LRT_INTERSECTION_AS_CONTOUR = (1 << 7),
|
||||
LRT_EVERYTHING_AS_CONTOUR = (1 << 8),
|
||||
LRT_ALLOW_DUPLI_OBJECTS = (1 << 9),
|
||||
LRT_ALLOW_OVERLAPPING_EDGES = (1 << 10),
|
||||
LRT_ALLOW_CLIPPING_BOUNDARIES = (1 << 11),
|
||||
LRT_BAKING_FINAL_RANGE = (1 << 12),
|
||||
LRT_BAKING_KEYFRAMES_ONLY = (1 << 13),
|
||||
LRT_REMOVE_DOUBLES = (1 << 14),
|
||||
} eLineartMainFlags;
|
||||
|
||||
typedef struct SceneLineArt {
|
||||
int flags;
|
||||
|
||||
/** line_types is used to select line types in global scope, especially when Fuzzy chaining is
|
||||
* enabled. See DNA_lineart_types.h for edge flags.
|
||||
*/
|
||||
int line_types;
|
||||
|
||||
/* Shared */
|
||||
/** Reserved for suggestive contour */
|
||||
float contour_fade;
|
||||
|
||||
/** 0-1 range for cosine angle */
|
||||
float crease_threshold;
|
||||
|
||||
/** 0-PI angle, for splitting strokes at sharp points */
|
||||
float angle_splitting_threshold;
|
||||
|
||||
/* CPU mode */
|
||||
float chaining_geometry_threshold;
|
||||
float chaining_image_threshold;
|
||||
|
||||
/* Baking */
|
||||
int baking_preview_start;
|
||||
int baking_preview_end;
|
||||
int baking_skip; /* 0 for every frame, 1 for every other frame and so on. */
|
||||
} SceneLineArt;
|
||||
|
||||
typedef struct SceneGpencil {
|
||||
float smaa_threshold;
|
||||
char _pad[4];
|
||||
@@ -1795,6 +1852,7 @@ typedef struct Scene {
|
||||
struct SceneDisplay display;
|
||||
struct SceneEEVEE eevee;
|
||||
struct SceneGpencil grease_pencil_settings;
|
||||
struct SceneLineArt lineart;
|
||||
} Scene;
|
||||
|
||||
/* **************** RENDERDATA ********************* */
|
||||
|
@@ -225,6 +225,7 @@ typedef enum eSpaceButtons_Context {
|
||||
BCONTEXT_TOOL = 14,
|
||||
BCONTEXT_SHADERFX = 15,
|
||||
BCONTEXT_OUTPUT = 16,
|
||||
BCONTEXT_COLLECTION = 17,
|
||||
|
||||
/* Keep last. */
|
||||
BCONTEXT_TOT,
|
||||
|
@@ -84,6 +84,7 @@ static const char *includefiles[] = {
|
||||
"DNA_mesh_types.h",
|
||||
"DNA_meshdata_types.h",
|
||||
"DNA_modifier_types.h",
|
||||
"DNA_lineart_types.h",
|
||||
"DNA_lattice_types.h",
|
||||
"DNA_object_types.h",
|
||||
"DNA_object_force_types.h",
|
||||
@@ -1558,6 +1559,7 @@ int main(int argc, char **argv)
|
||||
#include "DNA_layer_types.h"
|
||||
#include "DNA_light_types.h"
|
||||
#include "DNA_lightprobe_types.h"
|
||||
#include "DNA_lineart_types.h"
|
||||
#include "DNA_linestyle_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_mask_types.h"
|
||||
|
@@ -454,6 +454,7 @@ extern StructRNA RNA_NormalEditModifier;
|
||||
extern StructRNA RNA_Object;
|
||||
extern StructRNA RNA_ObjectBase;
|
||||
extern StructRNA RNA_ObjectDisplay;
|
||||
extern StructRNA RNA_ObjectLineArt;
|
||||
extern StructRNA RNA_OceanModifier;
|
||||
extern StructRNA RNA_OceanTexData;
|
||||
extern StructRNA RNA_OffsetGpencilModifier;
|
||||
@@ -515,6 +516,7 @@ extern StructRNA RNA_SPHFluidSettings;
|
||||
extern StructRNA RNA_Scene;
|
||||
extern StructRNA RNA_SceneDisplay;
|
||||
extern StructRNA RNA_SceneEEVEE;
|
||||
extern StructRNA RNA_SceneLineArt;
|
||||
extern StructRNA RNA_SceneObjects;
|
||||
extern StructRNA RNA_SceneRenderLayer;
|
||||
extern StructRNA RNA_SceneSequence;
|
||||
|
@@ -331,6 +331,10 @@ if(WITH_FREESTYLE)
|
||||
add_definitions(-DWITH_FREESTYLE)
|
||||
endif()
|
||||
|
||||
if(WITH_LINEART)
|
||||
add_definitions(-DWITH_LINEART)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV)
|
||||
list(APPEND INC
|
||||
../../../../intern/opensubdiv
|
||||
@@ -443,6 +447,13 @@ set(LIB
|
||||
bf_editor_undo
|
||||
)
|
||||
|
||||
if(WITH_LINEART)
|
||||
list(APPEND LIB
|
||||
bf_editor_lineart
|
||||
)
|
||||
endif()
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(bf_rna "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
||||
|
@@ -22,8 +22,12 @@
|
||||
|
||||
#include "DNA_collection_types.h"
|
||||
|
||||
#include "DNA_lineart_types.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
@@ -517,6 +521,31 @@ void RNA_def_collections(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Disable in Renders", "Globally disable in renders");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_Collection_flag_update");
|
||||
|
||||
static const EnumPropertyItem rna_collection_lineart_usage[] = {
|
||||
{COLLECTION_LRT_INCLUDE, "INCLUDE", 0, "Include", "Collection will produce feature lines"},
|
||||
{COLLECTION_LRT_OCCLUSION_ONLY,
|
||||
"OCCLUSION_ONLY",
|
||||
0,
|
||||
"Occlusion Only",
|
||||
"Only use the collection to produce occlusion"},
|
||||
{COLLECTION_LRT_EXCLUDE, "EXCLUDE", 0, "Exclude", "Don't use this collection in LRT"},
|
||||
{COLLECTION_LRT_INTERSECTION_ONLY,
|
||||
"INTERSECTION_ONLY",
|
||||
0,
|
||||
"Intersection Only",
|
||||
"Only generate intersection lines with this collection"},
|
||||
{COLLECTION_LRT_NO_INTERSECTION,
|
||||
"NO_INTERSECTION",
|
||||
0,
|
||||
"No Intersection",
|
||||
"Do not generate intersection lines for this collection"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
prop = RNA_def_property(srna, "lineart_usage", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_collection_lineart_usage);
|
||||
RNA_def_property_ui_text(prop, "Usage", "How to use this collection in LRT");
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "color_tag", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "color_tag");
|
||||
RNA_def_property_enum_funcs(
|
||||
|
@@ -88,6 +88,11 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = {
|
||||
ICON_MOD_SUBSURF,
|
||||
"Subdivide",
|
||||
"Subdivide stroke adding more control points"},
|
||||
{eGpencilModifierType_Lineart,
|
||||
"GP_LINEART",
|
||||
ICON_MOD_EDGESPLIT,
|
||||
"Line Art",
|
||||
"Generate Line Art strokes from selected source"},
|
||||
{0, "", 0, N_("Deform"), ""},
|
||||
{eGpencilModifierType_Armature,
|
||||
"GP_ARMATURE",
|
||||
@@ -241,6 +246,8 @@ static StructRNA *rna_GpencilModifier_refine(struct PointerRNA *ptr)
|
||||
return &RNA_MultiplyGpencilModifier;
|
||||
case eGpencilModifierType_Texture:
|
||||
return &RNA_TextureGpencilModifier;
|
||||
case eGpencilModifierType_Lineart:
|
||||
return &RNA_LineartGpencilModifier;
|
||||
/* Default */
|
||||
case eGpencilModifierType_None:
|
||||
case NUM_GREASEPENCIL_MODIFIER_TYPES:
|
||||
@@ -307,10 +314,11 @@ RNA_GP_MOD_VGROUP_NAME_SET(Opacity, vgname);
|
||||
RNA_GP_MOD_VGROUP_NAME_SET(Lattice, vgname);
|
||||
RNA_GP_MOD_VGROUP_NAME_SET(Smooth, vgname);
|
||||
RNA_GP_MOD_VGROUP_NAME_SET(Hook, vgname);
|
||||
RNA_GP_MOD_VGROUP_NAME_SET(Tint, vgname);
|
||||
RNA_GP_MOD_VGROUP_NAME_SET(Offset, vgname);
|
||||
RNA_GP_MOD_VGROUP_NAME_SET(Armature, vgname);
|
||||
RNA_GP_MOD_VGROUP_NAME_SET(Texture, vgname);
|
||||
RNA_GP_MOD_VGROUP_NAME_SET(Tint, vgname);
|
||||
RNA_GP_MOD_VGROUP_NAME_SET(Lineart, vgname);
|
||||
|
||||
# undef RNA_GP_MOD_VGROUP_NAME_SET
|
||||
|
||||
@@ -2305,6 +2313,220 @@ static void rna_def_modifier_gpenciltexture(BlenderRNA *brna)
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update");
|
||||
}
|
||||
|
||||
static void rna_def_modifier_gpencillineart(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static const EnumPropertyItem modifier_lineart_source_type[] = {
|
||||
{LRT_SOURCE_COLLECTION, "COLLECTION", 0, "Collection", ""},
|
||||
{LRT_SOURCE_OBJECT, "OBJECT", 0, "Object", ""},
|
||||
{LRT_SOURCE_SCENE, "SCENE", 0, "Scene", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "LineartGpencilModifier", "GpencilModifier");
|
||||
RNA_def_struct_ui_text(
|
||||
srna, "Line Art Modifier", "Genreate Line Art strokes from selected source");
|
||||
RNA_def_struct_sdna(srna, "LineartGpencilModifierData");
|
||||
RNA_def_struct_ui_icon(srna, ICON_MOD_EDGESPLIT);
|
||||
|
||||
prop = RNA_def_property(srna, "source_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, modifier_lineart_source_type);
|
||||
RNA_def_property_ui_text(prop, "Source Type", "Lineart stroke source type");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update");
|
||||
|
||||
prop = RNA_def_property(srna, "source_object", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
|
||||
RNA_def_property_struct_type(prop, "Object");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Source Object", "Source object that this modifier grabs data from");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update");
|
||||
|
||||
prop = RNA_def_property(srna, "source_collection", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
|
||||
RNA_def_property_struct_type(prop, "Collection");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Source Collection", "Source collection that this modifier uses data from");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_dependency_update");
|
||||
|
||||
/* types */
|
||||
prop = RNA_def_property(srna, "use_contour", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "line_types", LRT_EDGE_FLAG_CONTOUR);
|
||||
RNA_def_property_ui_text(prop, "Use Contour", "Include contour lines in the result");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_crease", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "line_types", LRT_EDGE_FLAG_CREASE);
|
||||
RNA_def_property_ui_text(prop, "Use Crease", "Include sharp edges in the result");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_material", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "line_types", LRT_EDGE_FLAG_MATERIAL);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Use Material", "Include material separation lines in the result");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_edge_mark", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "line_types", LRT_EDGE_FLAG_EDGE_MARK);
|
||||
RNA_def_property_ui_text(prop, "Use Edge Mark", "Include freestyle edge marks in the result");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_intersection", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "line_types", LRT_EDGE_FLAG_INTERSECTION);
|
||||
RNA_def_property_ui_text(prop, "Use Intersection", "Include intersection lines in the result");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_multiple_levels", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "use_multiple_levels", 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Use Multiple Levels", "Select lines from multiple occlusion levels");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "level_start", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_default(prop, 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Level Start", "Minimum level of occlusion level that gets selected");
|
||||
RNA_def_property_range(prop, 0, 128);
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "level_end", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_default(prop, 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Level End", "Maximum level of occlusion level that gets selected");
|
||||
RNA_def_property_range(prop, 0, 128);
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "target_material", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
|
||||
RNA_def_property_struct_type(prop, "Material");
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Target Material", "Grease Pencil material assigned to the generated strokes");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "target_layer", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Target Layer", "Grease Pencil layer assigned to the generated strokes");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "source_vertex_group", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Source Vertex Group",
|
||||
"Matches the beginning of vertex group names from mesh objects, match all when left empty");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "vgname");
|
||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_LineartGpencilModifier_vgname_set");
|
||||
RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for selected strokes");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "invert_source_vertex_group", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_GPENCIL_INVERT_SOURCE_VGROUP);
|
||||
RNA_def_property_ui_text(prop, "Invert Source", "Invert source vertex group values");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "match_output_vertex_group", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 1);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_GPENCIL_MATCH_OUTPUT_VGROUP);
|
||||
RNA_def_property_ui_text(prop, "Match Output", "Match output vertex group");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "soft_selection", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 1);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_GPENCIL_SOFT_SELECTION);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Soft selection", "Preserve original vertex weight instead of clipping to 0/1");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "thickness", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_default(prop, 20);
|
||||
RNA_def_property_ui_text(prop, "Thickness", "The thickness that used to generate strokes");
|
||||
RNA_def_property_ui_range(prop, 1, 100, 1, 1);
|
||||
RNA_def_property_range(prop, 1, 200);
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "opacity", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_default(prop, 0.1f);
|
||||
RNA_def_property_ui_text(prop, "Opacity", "The strength value used to generate strokes");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.01f, 2);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "pre_sample_length", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_default(prop, 0.0f);
|
||||
RNA_def_property_ui_text(prop, "Pre Sample Length", "Sample strokes before sending out");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.01f, 2);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_transparency", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_flags", LRT_GPENCIL_TRANSPARENCY_ENABLE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Use Transparency", "Use transparency mask from this material in Line Art");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_match", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_flags", LRT_GPENCIL_TRANSPARENCY_MATCH);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_ui_text(prop, "Match Transparency", "Match all transparency bits");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_0", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 0);
|
||||
RNA_def_property_ui_text(prop, "Mask 0", "Mask bit 0");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_1", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 1);
|
||||
RNA_def_property_ui_text(prop, "Mask 1", "Mask bit 1");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_2", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 2);
|
||||
RNA_def_property_ui_text(prop, "Mask 2", "Mask bit 2");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_3", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 3);
|
||||
RNA_def_property_ui_text(prop, "Mask 3", "Mask bit 3");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_4", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 4);
|
||||
RNA_def_property_ui_text(prop, "Mask 4", "Mask bit 4");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_5", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 5);
|
||||
RNA_def_property_ui_text(prop, "Mask 5", "Mask bit 5");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_6", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 6);
|
||||
RNA_def_property_ui_text(prop, "mask 6", "Mask bit 6");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_7", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 7);
|
||||
RNA_def_property_ui_text(prop, "Mask 7", "Mask bit 7");
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
|
||||
}
|
||||
|
||||
void RNA_def_greasepencil_modifier(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -2379,6 +2601,7 @@ void RNA_def_greasepencil_modifier(BlenderRNA *brna)
|
||||
rna_def_modifier_gpencilarmature(brna);
|
||||
rna_def_modifier_gpencilmultiply(brna);
|
||||
rna_def_modifier_gpenciltexture(brna);
|
||||
rna_def_modifier_gpencillineart(brna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -87,6 +87,7 @@ const EnumPropertyItem rna_enum_ramp_blend_items[] = {
|
||||
|
||||
# include "ED_gpencil.h"
|
||||
# include "ED_image.h"
|
||||
# include "ED_lineart.h"
|
||||
# include "ED_node.h"
|
||||
# include "ED_screen.h"
|
||||
|
||||
@@ -127,6 +128,14 @@ static void rna_MaterialGpencil_update(Main *bmain, Scene *scene, PointerRNA *pt
|
||||
WM_main_add_notifier(NC_GPENCIL | ND_DATA, ma);
|
||||
}
|
||||
|
||||
static void rna_MaterialLineArt_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
rna_Material_update(bmain, scene, ptr);
|
||||
if (ED_lineart_modifier_sync_flag_check(LRT_SYNC_IDLE)) {
|
||||
ED_lineart_modifier_sync_flag_set(LRT_SYNC_WAITING, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_Material_draw_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
{
|
||||
Material *ma = (Material *)ptr->owner_id;
|
||||
@@ -671,6 +680,70 @@ static void rna_def_material_greasepencil(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Is Fill Visible", "True when opacity of fill is set high enough to be visible");
|
||||
}
|
||||
static void rna_def_material_lineart(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "MaterialLineArt", NULL);
|
||||
RNA_def_struct_sdna(srna, "MaterialLineArt");
|
||||
RNA_def_struct_ui_text(srna, "Material Line Art", "");
|
||||
|
||||
prop = RNA_def_property(srna, "use_transparency", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_MATERIAL_TRANSPARENCY_ENABLED);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Use Transparency", "Use transparency mask from this material in Line Art");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_0", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 0);
|
||||
RNA_def_property_ui_text(prop, "Mask 0", "Mask bit 0");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_1", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 1);
|
||||
RNA_def_property_ui_text(prop, "Mask 1", "Mask bit 1");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_2", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 2);
|
||||
RNA_def_property_ui_text(prop, "Mask 2", "Mask bit 2");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_3", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 3);
|
||||
RNA_def_property_ui_text(prop, "Mask 3", "Mask bit 3");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_4", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 4);
|
||||
RNA_def_property_ui_text(prop, "Mask 4", "Mask bit 4");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_5", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 5);
|
||||
RNA_def_property_ui_text(prop, "Mask 5", "Mask bit 5");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_6", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 6);
|
||||
RNA_def_property_ui_text(prop, "mask 6", "Mask bit 6");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
|
||||
prop = RNA_def_property(srna, "transparency_mask_7", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "transparency_mask", 1 << 7);
|
||||
RNA_def_property_ui_text(prop, "Mask 7", "Mask bit 7");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialLineArt_update");
|
||||
}
|
||||
|
||||
void RNA_def_material(BlenderRNA *brna)
|
||||
{
|
||||
@@ -836,7 +909,13 @@ void RNA_def_material(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Is Grease Pencil", "True if this material has grease pencil data");
|
||||
|
||||
/* line art */
|
||||
prop = RNA_def_property(srna, "lineart", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "lineart");
|
||||
RNA_def_property_ui_text(prop, "Line Art Settings", "Line Art settings for material");
|
||||
|
||||
rna_def_material_greasepencil(brna);
|
||||
rna_def_material_lineart(brna);
|
||||
|
||||
RNA_api_material(srna);
|
||||
}
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "DNA_shader_fx_types.h"
|
||||
#include "DNA_workspace_types.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
@@ -159,6 +160,21 @@ const EnumPropertyItem rna_enum_object_gpencil_type_items[] = {
|
||||
{GP_EMPTY, "EMPTY", ICON_EMPTY_AXIS, "Blank", "Create an empty grease pencil object"},
|
||||
{GP_STROKE, "STROKE", ICON_STROKE, "Stroke", "Create a simple stroke with basic colors"},
|
||||
{GP_MONKEY, "MONKEY", ICON_MONKEY, "Monkey", "Construct a Suzanne grease pencil object"},
|
||||
{GP_LRT_SCENE,
|
||||
"LRT_SCENE",
|
||||
ICON_SCENE,
|
||||
"Scene Line Art",
|
||||
"Quickly set up Line Art for the whole scene"},
|
||||
{GP_LRT_COLLECTION,
|
||||
"LRT_COLLECTION",
|
||||
ICON_OUTLINER_COLLECTION,
|
||||
"Collection Line Art",
|
||||
"Quickly set up Line Art for active collection"},
|
||||
{GP_LRT_OBJECT,
|
||||
"LRT_OBJECT",
|
||||
ICON_CUBE,
|
||||
"Object Line Art",
|
||||
"Quickly set up Line Art for active collection"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static const EnumPropertyItem parent_type_items[] = {
|
||||
@@ -2083,6 +2099,12 @@ int rna_Object_use_dynamic_topology_sculpting_get(PointerRNA *ptr)
|
||||
return (ss && ss->bm);
|
||||
}
|
||||
|
||||
static void rna_object_lineart_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
{
|
||||
DEG_id_tag_update(ptr->owner_id, ID_RECALC_GEOMETRY);
|
||||
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ptr->owner_id);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void rna_def_vertex_group(BlenderRNA *brna)
|
||||
@@ -2644,6 +2666,58 @@ static void rna_def_object_display(BlenderRNA *brna)
|
||||
|
||||
RNA_define_lib_overridable(false);
|
||||
}
|
||||
static void rna_def_object_lineart(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static EnumPropertyItem prop_feature_line_usage_items[] = {
|
||||
{OBJECT_LRT_INHERENT,
|
||||
"INHEREIT",
|
||||
0,
|
||||
"Inhereit",
|
||||
"Follow settings from the parent collection"},
|
||||
{OBJECT_LRT_INCLUDE, "INCLUDE", 0, "Include", "Include this object into LRT calculation"},
|
||||
{OBJECT_LRT_OCCLUSION_ONLY,
|
||||
"OCCLUSION_ONLY",
|
||||
0,
|
||||
"Occlusion Only",
|
||||
"Don't produce lines, only used as occlusion object"},
|
||||
{OBJECT_LRT_EXCLUDE, "EXCLUDE", 0, "Exclude", "Don't use this object for LRT rendering"},
|
||||
{OBJECT_LRT_INTERSECTION_ONLY,
|
||||
"INTERSECTION_ONLY",
|
||||
0,
|
||||
"Intersection Only",
|
||||
"Only to generate intersection lines with this object"},
|
||||
{OBJECT_LRT_NO_INTERSECTION,
|
||||
"NO_INTERSECTION",
|
||||
0,
|
||||
"No Intersection",
|
||||
"Include this object but do not generate intersection lines"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "ObjectLineArt", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Object Line Art", "Object lineart settings");
|
||||
RNA_def_struct_sdna(srna, "ObjectLineArt");
|
||||
|
||||
prop = RNA_def_property(srna, "usage", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, prop_feature_line_usage_items);
|
||||
RNA_def_property_ui_text(prop, "Usage", "How to use this object in line art calculation");
|
||||
RNA_def_property_update(prop, 0, "rna_object_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_crease_override", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", OBJECT_LRT_OWN_CREASE);
|
||||
RNA_def_property_ui_text(prop, "Own Crease", "Use own crease setting to overwrite scene global");
|
||||
RNA_def_property_update(prop, 0, "rna_object_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "crease_threshold", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_range(prop, 0, DEG2RAD(180.0f));
|
||||
RNA_def_property_ui_range(prop, 0.0f, DEG2RAD(180.0f), 0.01f, 1);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Own Crease", "Angles smaller than this will be treated as creases");
|
||||
RNA_def_property_update(prop, 0, "rna_object_lineart_update");
|
||||
}
|
||||
|
||||
static void rna_def_object(BlenderRNA *brna)
|
||||
{
|
||||
@@ -3414,6 +3488,11 @@ static void rna_def_object(BlenderRNA *brna)
|
||||
RNA_def_property_pointer_funcs(prop, "rna_Object_display_get", NULL, NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Object Display", "Object display settings for 3D viewport");
|
||||
|
||||
/* Line Art */
|
||||
prop = RNA_def_property(srna, "lineart", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "ObjectLineArt");
|
||||
RNA_def_property_ui_text(prop, "Line Art", "Line Art settings for the object");
|
||||
|
||||
RNA_define_lib_overridable(false);
|
||||
|
||||
/* anim */
|
||||
@@ -3434,6 +3513,7 @@ void RNA_def_object(BlenderRNA *brna)
|
||||
rna_def_face_map(brna);
|
||||
rna_def_material_slot(brna);
|
||||
rna_def_object_display(brna);
|
||||
rna_def_object_lineart(brna);
|
||||
RNA_define_animate_sdna(true);
|
||||
}
|
||||
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_layer_types.h"
|
||||
#include "DNA_lineart_types.h"
|
||||
#include "DNA_linestyle_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
@@ -47,6 +48,7 @@
|
||||
#include "BKE_volume.h"
|
||||
|
||||
#include "ED_gpencil.h"
|
||||
#include "ED_lineart.h"
|
||||
#include "ED_object.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
@@ -2596,6 +2598,29 @@ static char *rna_UnitSettings_path(PointerRNA *UNUSED(ptr))
|
||||
return BLI_strdup("unit_settings");
|
||||
}
|
||||
|
||||
/* lineart */
|
||||
|
||||
static void rna_lineart_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
|
||||
{
|
||||
if (ED_lineart_modifier_sync_flag_check(LRT_SYNC_IDLE)) {
|
||||
ED_lineart_modifier_sync_flag_set(LRT_SYNC_WAITING, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void rna_lineart_auto_update_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
SceneLineArt *data = (SceneLineArt *)ptr->data;
|
||||
|
||||
if (value) {
|
||||
data->flags |= LRT_AUTO_UPDATE;
|
||||
}
|
||||
else {
|
||||
data->flags &= (~LRT_AUTO_UPDATE);
|
||||
ED_lineart_calculation_flag_set(LRT_RENDER_CANCELING);
|
||||
ED_lineart_destroy_render_data_external();
|
||||
}
|
||||
}
|
||||
|
||||
static char *rna_FFmpegSettings_path(PointerRNA *UNUSED(ptr))
|
||||
{
|
||||
return BLI_strdup("render.ffmpeg");
|
||||
@@ -7468,6 +7493,177 @@ static void rna_def_scene_gpencil(BlenderRNA *brna)
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
}
|
||||
|
||||
static void rna_def_scene_lineart(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "SceneLineArt", NULL);
|
||||
RNA_def_struct_sdna(srna, "SceneLineArt");
|
||||
RNA_def_struct_ui_text(srna, "Scene Line Art Config", "Line Art global settings");
|
||||
|
||||
prop = RNA_def_property(srna, "auto_update", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_AUTO_UPDATE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Auto Update", "Automatically update Line Art cache when frame changes");
|
||||
|
||||
RNA_def_property_boolean_funcs(prop, NULL, "rna_lineart_auto_update_set");
|
||||
/* Also use this update callback to trigger the modifier to clear the frame. */
|
||||
RNA_def_property_update(prop, NC_SCENE, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "gpencil_overwrite", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_GPENCIL_OVERWRITE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"GPencil Overwrite",
|
||||
"Overwrite existing strokes in existing frames of target GPencil objects");
|
||||
|
||||
prop = RNA_def_property(srna, "fuzzy_intersections", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_INTERSECTION_AS_CONTOUR);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Intersection As Contour",
|
||||
"Treat intersection lines as contour so those lines can be chained together");
|
||||
RNA_def_property_update(prop, NC_SCENE, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "fuzzy_everything", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_EVERYTHING_AS_CONTOUR);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"All Lines As Contour",
|
||||
"Treat all lines as contour so those lines can be chained together");
|
||||
RNA_def_property_update(prop, NC_SCENE, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "allow_duplication", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_ALLOW_DUPLI_OBJECTS);
|
||||
RNA_def_property_boolean_default(prop, 1);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Instanced Objects",
|
||||
"Allow particle objects and face/vertiex duplication to show in line art");
|
||||
RNA_def_property_update(prop, NC_SCENE, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "allow_overlapping_edges", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_ALLOW_OVERLAPPING_EDGES);
|
||||
RNA_def_property_boolean_default(prop, 1);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Handle Overlapping Edges",
|
||||
"Allow lines from edge split to show properly, may run slower");
|
||||
RNA_def_property_update(prop, NC_SCENE, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "allow_clipping_boundaries", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_ALLOW_CLIPPING_BOUNDARIES);
|
||||
RNA_def_property_boolean_default(prop, 1);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Clipping Boundaries", "Allow lines on near/far clipping plane to be shown");
|
||||
RNA_def_property_update(prop, NC_SCENE, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "crease_threshold", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_range(prop, 0, DEG2RAD(180.0f));
|
||||
RNA_def_property_ui_range(prop, 0.0f, DEG2RAD(180.0f), 0.01f, 1);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Crease Threshold", "Angles smaller than this will be treated as creases");
|
||||
RNA_def_property_update(prop, NC_SCENE, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "angle_splitting_threshold", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_float_default(prop, DEG2RAD(60.0f));
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Angle Splitting", "Angle in screen space below which a stroke is split in two");
|
||||
/* Don't allow value very close to PI, or we get a lot of small segments.*/
|
||||
RNA_def_property_ui_range(prop, 0.0f, DEG2RAD(179.5f), 0.01f, 1);
|
||||
RNA_def_property_range(prop, 0.0f, DEG2RAD(180.0f));
|
||||
RNA_def_property_update(prop, NC_SCENE, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "remove_doubles", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_REMOVE_DOUBLES);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Remove Doubles", "Remove doubles when line art is loading geometries");
|
||||
RNA_def_property_update(prop, NC_SCENE, "rna_lineart_update");
|
||||
|
||||
/* types */
|
||||
prop = RNA_def_property(srna, "use_contour", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "line_types", LRT_EDGE_FLAG_CONTOUR);
|
||||
RNA_def_property_boolean_default(prop, true);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Use Contour", "Include lines from object silhouettes in the result");
|
||||
RNA_def_property_update(prop, 0, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_crease", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "line_types", LRT_EDGE_FLAG_CREASE);
|
||||
RNA_def_property_boolean_default(prop, true);
|
||||
RNA_def_property_ui_text(prop, "Use Crease", "Include sharp edges in the result");
|
||||
RNA_def_property_update(prop, 0, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_material", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "line_types", LRT_EDGE_FLAG_MATERIAL);
|
||||
RNA_def_property_boolean_default(prop, true);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Use Material", "Include material separation lines in the result");
|
||||
RNA_def_property_update(prop, 0, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_edge_mark", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "line_types", LRT_EDGE_FLAG_EDGE_MARK);
|
||||
RNA_def_property_boolean_default(prop, true);
|
||||
RNA_def_property_ui_text(prop, "Use Edge Mark", "Include freestyle edge marks in the result");
|
||||
RNA_def_property_update(prop, 0, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_intersections", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "line_types", LRT_EDGE_FLAG_INTERSECTION);
|
||||
RNA_def_property_boolean_default(prop, true);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Calculate Intersections", "Calculate intersections lines when enabled");
|
||||
RNA_def_property_update(prop, NC_SCENE, "rna_lineart_update");
|
||||
|
||||
/* Below these two are only for grease pencil, thus no viewport updates. */
|
||||
|
||||
prop = RNA_def_property(srna, "chaining_geometry_threshold", PROP_FLOAT, PROP_DISTANCE);
|
||||
RNA_def_property_float_default(prop, 0.01f);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Geometry Threshold",
|
||||
"Segments where their geometric distance between them lower than this "
|
||||
"will be chained together");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 0.5f, 0.001f, 3);
|
||||
RNA_def_property_range(prop, 0.0f, 0.5f);
|
||||
RNA_def_property_update(prop, NC_SCENE, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "chaining_image_threshold", PROP_FLOAT, PROP_DISTANCE);
|
||||
RNA_def_property_float_default(prop, 0.01f);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Image Threshold",
|
||||
"Segments with an image distance smaller than this will be chained together");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 0.3f, 0.001f, 4);
|
||||
RNA_def_property_range(prop, 0.0f, 0.3f);
|
||||
RNA_def_property_update(prop, NC_SCENE, "rna_lineart_update");
|
||||
|
||||
prop = RNA_def_property(srna, "baking_final_range", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_BAKING_FINAL_RANGE);
|
||||
RNA_def_property_boolean_default(prop, 1);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Final Range", "Bake with the scene frame range instead of a preview range");
|
||||
|
||||
prop = RNA_def_property(srna, "baking_keyframes_only", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LRT_BAKING_KEYFRAMES_ONLY);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_ui_text(prop, "Keyframes Only", "Only fill in existing gpencil key frames");
|
||||
|
||||
prop = RNA_def_property(srna, "baking_preview_start", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Preview start", "First frame to be baked in preview");
|
||||
RNA_def_property_range(prop, 0, MAXFRAME);
|
||||
|
||||
prop = RNA_def_property(srna, "baking_preview_end", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Preview end", "Last frame to be baked in preview");
|
||||
RNA_def_property_range(prop, 0, MAXFRAME);
|
||||
|
||||
prop = RNA_def_property(srna, "baking_skip", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Skip", "Number of frames to skip per baked frame");
|
||||
RNA_def_property_ui_range(prop, 0, 100, 1, 1);
|
||||
}
|
||||
|
||||
void RNA_def_scene(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -7943,6 +8139,11 @@ void RNA_def_scene(BlenderRNA *brna)
|
||||
RNA_def_property_struct_type(prop, "SceneEEVEE");
|
||||
RNA_def_property_ui_text(prop, "Eevee", "Eevee settings for the scene");
|
||||
|
||||
/* Line Art */
|
||||
prop = RNA_def_property(srna, "lineart", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "SceneLineArt");
|
||||
RNA_def_property_ui_text(prop, "Line Art", "Line Art settings for the scene");
|
||||
|
||||
/* Grease Pencil */
|
||||
prop = RNA_def_property(srna, "grease_pencil_settings", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "SceneGpencil");
|
||||
@@ -7966,6 +8167,7 @@ void RNA_def_scene(BlenderRNA *brna)
|
||||
rna_def_display_safe_areas(brna);
|
||||
rna_def_scene_display(brna);
|
||||
rna_def_scene_eevee(brna);
|
||||
rna_def_scene_lineart(brna);
|
||||
rna_def_view_layer_aov(brna);
|
||||
rna_def_view_layer_eevee(brna);
|
||||
rna_def_scene_gpencil(brna);
|
||||
|
@@ -453,13 +453,14 @@ static const EnumPropertyItem buttons_context_items[] = {
|
||||
{BCONTEXT_OUTPUT, "OUTPUT", ICON_OUTPUT, "Output", "Output Properties"},
|
||||
{BCONTEXT_VIEW_LAYER, "VIEW_LAYER", ICON_RENDER_RESULT, "View Layer", "View Layer Properties"},
|
||||
{BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World Properties"},
|
||||
{BCONTEXT_COLLECTION, "COLLECTION", ICON_GROUP, "Collection", "Collection Properties"},
|
||||
{BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object Properties"},
|
||||
{BCONTEXT_CONSTRAINT,
|
||||
"CONSTRAINT",
|
||||
ICON_CONSTRAINT,
|
||||
"Constraints",
|
||||
"Object Constraint Properties"},
|
||||
{BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Modifier Properties"},
|
||||
{BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Modifiers Properties"},
|
||||
{BCONTEXT_DATA, "DATA", ICON_NONE, "Data", "Object Data Properties"},
|
||||
{BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone Properties"},
|
||||
{BCONTEXT_BONE_CONSTRAINT,
|
||||
|
@@ -209,6 +209,10 @@ if(WITH_FREESTYLE)
|
||||
add_definitions(-DWITH_FREESTYLE)
|
||||
endif()
|
||||
|
||||
if(WITH_LINEART)
|
||||
add_definitions(-DWITH_LINEART)
|
||||
endif()
|
||||
|
||||
if(WITH_IMAGE_CINEON)
|
||||
add_definitions(-DWITH_CINEON)
|
||||
endif()
|
||||
|
@@ -36,6 +36,7 @@ static PyStructSequence_Field app_builtopts_info_fields[] = {
|
||||
{"cycles", NULL},
|
||||
{"cycles_osl", NULL},
|
||||
{"freestyle", NULL},
|
||||
{"lineart", NULL},
|
||||
{"image_cineon", NULL},
|
||||
{"image_dds", NULL},
|
||||
{"image_hdr", NULL},
|
||||
@@ -133,6 +134,12 @@ static PyObject *make_builtopts_info(void)
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LINEART
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
SetObjIncref(Py_False);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CINEON
|
||||
SetObjIncref(Py_True);
|
||||
#else
|
||||
|
Submodule source/tools updated: b66c22e1fb...5cf2fc3e5d
Reference in New Issue
Block a user