Compare commits
199 Commits
xr-dev
...
temp-lanpr
Author | SHA1 | Date | |
---|---|---|---|
a2cb7ffa66 | |||
af0378aa4a | |||
d1b7ab3333 | |||
a2caf8297a | |||
8757454fbc | |||
ea253238ac | |||
11416446ba | |||
aebaf3c88c | |||
9e6351076c | |||
f8e255759f | |||
e5c30df7d5 | |||
e064aa2560 | |||
6b1771645e | |||
b64fca4cd0 | |||
911450be0e | |||
c42a6b77b5 | |||
9bfccd1854 | |||
36f81b54de | |||
![]() |
6c6211a99d | ||
bc97c0d8b9 | |||
e5513dfe04 | |||
1c6dd9fe99 | |||
2e101de47f | |||
7d0a55fb7c | |||
196effe82c | |||
a586114402 | |||
d918becba1 | |||
ae078c265b | |||
4421598fca | |||
71d482bdee | |||
5334b0439c | |||
49e9d7d8f3 | |||
bb3dac4634 | |||
![]() |
6ff42dbffa | ||
![]() |
f8233e05f5 | ||
c1c27a2c39 | |||
10f70ea73a | |||
e24cb83e31 | |||
2700d8dafd | |||
86d6d3595a | |||
d1cfd94423 | |||
62a9e414dc | |||
20d86c8c6c | |||
d183e2ffc9 | |||
d0b0bc2a0b | |||
3f2ae8f4bd | |||
2d39de7922 | |||
2da63c0405 | |||
7af75482c6 | |||
9987170ab3 | |||
59c608a665 | |||
0e448678ee | |||
e708e4cfeb | |||
9207169175 | |||
fb4ae7c229 | |||
86d18527e2 | |||
3a0789b3fb | |||
542885a2c4 | |||
![]() |
2c7adb2c4d | ||
![]() |
8573045404 | ||
b9252e63fa | |||
d5a484a1fe | |||
![]() |
775ff3b20d | ||
4442e060ba | |||
b12aaf1262 | |||
cf6f3d120e | |||
aa7dfd73bd | |||
![]() |
c1cc9f94ed | ||
afcbcc0e29 | |||
2113c01da2 | |||
daa295fc5f | |||
eeb91051f6 | |||
ba1527f827 | |||
edc7c3bc33 | |||
d1353c8a52 | |||
b4f92d9707 | |||
59794a82cc | |||
74c447d9d7 | |||
![]() |
95d9ec6a37 | ||
f5d493dd48 | |||
4afacf55f6 | |||
a15de692a7 | |||
b27eb93ea7 | |||
a49481a93a | |||
![]() |
db9428c9ae | ||
33e1fe12f5 | |||
7abf095e6c | |||
de525a249d | |||
a9816ec802 | |||
2b36ebb457 | |||
f02e64556f | |||
57ac8fed67 | |||
0f21360520 | |||
3a8184dc8f | |||
2c73c78820 | |||
![]() |
cfc345c31e | ||
023a7fada8 | |||
![]() |
13194fc36a | ||
1a0aa336cb | |||
![]() |
7e14b9807b | ||
a4d4673892 | |||
6226f299be | |||
![]() |
4ac9c3e135 | ||
c5de8120c0 | |||
93f940db25 | |||
cdf5891cca | |||
![]() |
760841c293 | ||
![]() |
e5ae229649 | ||
f6c0ae9ae5 | |||
9b9f99fa41 | |||
9942470466 | |||
c92c753a2f | |||
610c11e33a | |||
![]() |
50db4b3801 | ||
![]() |
627b07ad7c | ||
![]() |
c1ad518d56 | ||
f3553ff144 | |||
f8cbace82e | |||
9a2e290c1f | |||
8650f854ef | |||
6cde30681c | |||
0380f37746 | |||
2e2f68c6b3 | |||
b92acee177 | |||
f80b47e715 | |||
5e5dbcfcd2 | |||
1b3014f2f4 | |||
e21939965a | |||
c5f28aa0d7 | |||
![]() |
a98d38b688 | ||
aedb784407 | |||
7795cfead6 | |||
53459c7889 | |||
73e4648477 | |||
bd4f3a1449 | |||
a41f20ec79 | |||
![]() |
d8fbeeb8e7 | ||
![]() |
086a206ddc | ||
2a7388c491 | |||
![]() |
322fa8e200 | ||
989557c9d5 | |||
abdfdf400a | |||
9f71529e4f | |||
d4dbbf4f6f | |||
dcd66e79f7 | |||
5fb93df76f | |||
![]() |
a1a7fc91c1 | ||
7dc87257d6 | |||
e151c8e6f4 | |||
615e11d8b9 | |||
5396e17fb8 | |||
4f1928c2ae | |||
7fb8ff3b27 | |||
e80480ad41 | |||
d4561c2468 | |||
8b9131bd75 | |||
eefab053f2 | |||
2752870406 | |||
ebce8d65d4 | |||
7206254d92 | |||
b8cb26eff9 | |||
f601a0e4b5 | |||
1d43f5b5f2 | |||
dc5389f514 | |||
c122d1b818 | |||
628fe8b635 | |||
72c0abbd28 | |||
d543acbdf7 | |||
88fc7e401a | |||
9fe7a6035f | |||
e7a21545ee | |||
49640c7881 | |||
a7bab3bd22 | |||
686ddc842c | |||
c676b74c84 | |||
4bdac5da75 | |||
b13f8aa442 | |||
da74aa3973 | |||
2c9dc87fc1 | |||
58d2a01f6f | |||
de8b4ef217 | |||
5fd4af1589 | |||
f7e3efa4a2 | |||
9ec72374c3 | |||
60f5cdaee9 | |||
d515b4e205 | |||
ccc113deba | |||
33d3dcdb00 | |||
255048842f | |||
b790e32ded | |||
875beb5f92 | |||
17656a6e1f | |||
ddb78ea43b | |||
01369f1400 | |||
cfd060147b | |||
e21a36b69a | |||
05b54a99ef | |||
6bd4ea0c2f | |||
f04a173d7b |
Submodule release/datafiles/locale updated: 1f6ec7f7a1...ad82c4ce43
Submodule release/scripts/addons updated: eb9bab0e71...8e6f485cf5
Submodule release/scripts/addons_contrib updated: 23b744fa47...7077ff0738
@@ -32,6 +32,7 @@ _modules = [
|
||||
"constraint",
|
||||
"file",
|
||||
"image",
|
||||
"lanpr",
|
||||
"mask",
|
||||
"mesh",
|
||||
"node",
|
||||
|
41
release/scripts/startup/bl_operators/lanpr.py
Normal file
41
release/scripts/startup/bl_operators/lanpr.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# ##### 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>
|
||||
|
||||
import bpy
|
||||
import string
|
||||
|
||||
class LANPR_reset_object_transfromations(bpy.types.Operator):
|
||||
"""Reset Transformations"""
|
||||
bl_idname = "lanpr.reset_object_transfromations"
|
||||
bl_label = "Reset Transformations"
|
||||
|
||||
obj = bpy.props.StringProperty(name="Target Object")
|
||||
|
||||
def execute(self, context):
|
||||
print(self.obj)
|
||||
ob = bpy.data.objects[self.obj]
|
||||
ob.location.zero()
|
||||
ob.rotation_euler.zero()
|
||||
ob.scale.xyz=[1,1,1]
|
||||
return {'FINISHED'}
|
||||
|
||||
classes=(
|
||||
LANPR_reset_object_transfromations,
|
||||
)
|
@@ -65,6 +65,8 @@ _modules = [
|
||||
"properties_scene",
|
||||
"properties_texture",
|
||||
"properties_world",
|
||||
"properties_collection",
|
||||
"properties_lanpr",
|
||||
|
||||
# Generic Space Modules
|
||||
#
|
||||
|
129
release/scripts/startup/bl_ui/properties_collection.py
Normal file
129
release/scripts/startup/bl_ui/properties_collection.py
Normal file
@@ -0,0 +1,129 @@
|
||||
# ##### 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
|
||||
from bpy import data
|
||||
from mathutils import Vector
|
||||
|
||||
|
||||
class CollectionButtonsPanel:
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "collection"
|
||||
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
|
||||
def lanpr_make_line_type_entry(col, line_type, text_disp, expand, search_from):
|
||||
col.prop(line_type, "use", text=text_disp)
|
||||
if expand:
|
||||
col.prop_search(line_type, "layer", search_from, "layers")
|
||||
col.prop_search(line_type, "material", search_from, "materials")
|
||||
|
||||
class COLLECTION_PT_collection_flags(CollectionButtonsPanel, Panel):
|
||||
bl_label = "Collection Flags"
|
||||
|
||||
def draw(self, context):
|
||||
layout=self.layout
|
||||
collection=context.collection
|
||||
vl = context.view_layer
|
||||
vlc = vl.active_layer_collection
|
||||
if vlc.name == 'Master Collection':
|
||||
row = layout.row()
|
||||
row.label(text="This is the master collection")
|
||||
return
|
||||
|
||||
row = layout.row()
|
||||
col = row.column(align=True)
|
||||
col.prop(vlc,"hide_viewport")
|
||||
col.prop(vlc,"holdout")
|
||||
col.prop(vlc,"indirect_only")
|
||||
row = layout.row()
|
||||
col = row.column(align=True)
|
||||
col.prop(collection,"hide_select")
|
||||
col.prop(collection,"hide_viewport")
|
||||
col.prop(collection,"hide_render")
|
||||
|
||||
def is_unit_transformation(ob):
|
||||
if ob.scale.xyz==Vector((1,1,1)) and ob.location.xyz==Vector((0,0,0)) and \
|
||||
ob.rotation_euler.x == 0.0 and ob.rotation_euler.y == 0.0 and ob.rotation_euler.z == 0.0:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class COLLECTION_PT_lanpr_collection(CollectionButtonsPanel, Panel):
|
||||
bl_label = "Collection LANPR"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.render.engine == 'BLENDER_LANPR' or context.scene.lanpr.enabled
|
||||
|
||||
def draw(self,context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
collection = context.collection
|
||||
lanpr = collection.lanpr
|
||||
row = layout.row()
|
||||
row.prop(lanpr,"usage")
|
||||
if lanpr.usage!='INCLUDE':
|
||||
layout.prop(lanpr,"force")
|
||||
else:
|
||||
layout.prop(lanpr,"target")
|
||||
|
||||
if lanpr.target:
|
||||
|
||||
if not is_unit_transformation(lanpr.target):
|
||||
layout.label(text = "Target GP has self transformations.")
|
||||
layout.operator("lanpr.reset_object_transfromations").obj=lanpr.target.name
|
||||
|
||||
layout.prop(lanpr,'use_multiple_levels', text="Multiple Levels")
|
||||
|
||||
if lanpr.use_multiple_levels:
|
||||
col = layout.column(align=True)
|
||||
col.prop(lanpr,'level_start',text="Level Begin")
|
||||
col.prop(lanpr,'level_end',text="End")
|
||||
else:
|
||||
layout.prop(lanpr,'level_start',text="Level")
|
||||
|
||||
layout.prop(lanpr, "use_same_style")
|
||||
|
||||
if lanpr.use_same_style:
|
||||
layout.prop_search(lanpr, 'target_layer', lanpr.target.data, "layers", icon='GREASEPENCIL')
|
||||
layout.prop_search(lanpr, 'target_material', lanpr.target.data, "materials", icon='SHADING_TEXTURE')
|
||||
|
||||
expand = not lanpr.use_same_style
|
||||
lanpr_make_line_type_entry(layout, lanpr.contour, "Contour", expand, lanpr.target.data)
|
||||
lanpr_make_line_type_entry(layout, lanpr.crease, "Crease", expand, lanpr.target.data)
|
||||
lanpr_make_line_type_entry(layout, lanpr.material, "Material", expand, lanpr.target.data)
|
||||
lanpr_make_line_type_entry(layout, lanpr.edge_mark, "Edge Mark", expand, lanpr.target.data)
|
||||
lanpr_make_line_type_entry(layout, lanpr.intersection, "Intersection", expand, lanpr.target.data)
|
||||
|
||||
classes = (
|
||||
COLLECTION_PT_collection_flags,
|
||||
COLLECTION_PT_lanpr_collection,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
from bpy.utils import register_class
|
||||
for cls in classes:
|
||||
register_class(cls)
|
105
release/scripts/startup/bl_ui/properties_lanpr.py
Normal file
105
release/scripts/startup/bl_ui/properties_lanpr.py
Normal file
@@ -0,0 +1,105 @@
|
||||
# ##### 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
|
||||
from bpy import data
|
||||
from mathutils import Vector
|
||||
|
||||
|
||||
class LanprButtonsPanel:
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = "lanpr"
|
||||
# COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
||||
def lanpr_make_line_type_entry(col, line_type, text_disp, expand, search_from):
|
||||
col.prop(line_type, "use", text=text_disp)
|
||||
if expand:
|
||||
col.prop_search(line_type, "layer", search_from, "layers")
|
||||
col.prop_search(line_type, "material", search_from, "materials")
|
||||
|
||||
class OBJECT_PT_lanpr_settings(LanprButtonsPanel, Panel):
|
||||
bl_label = "LANPR settings"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ob = context.object
|
||||
obl = ob.lanpr
|
||||
return (context.scene.render.engine == 'BLENDER_LANPR' or context.scene.lanpr.enabled) and\
|
||||
obl.usage == 'INCLUDE' and obl.target
|
||||
|
||||
def draw(self,context):
|
||||
collection = context.collection
|
||||
lanpr = collection.lanpr
|
||||
ob = context.object
|
||||
obl = ob.lanpr
|
||||
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
layout.prop(obl,'use_multiple_levels', text="Multiple Levels")
|
||||
if obl.use_multiple_levels:
|
||||
col = layout.column(align=True)
|
||||
col.prop(obl,'level_start')
|
||||
col.prop(obl,'level_end', text="End")
|
||||
else:
|
||||
layout.prop(obl,'level_start', text="Level")
|
||||
|
||||
layout.prop(obl,'use_same_style')
|
||||
if obl.use_same_style:
|
||||
layout.prop_search(obl, 'target_layer', obl.target.data, "layers", icon='GREASEPENCIL')
|
||||
layout.prop_search(obl, 'target_material', obl.target.data, "materials", icon='SHADING_TEXTURE')
|
||||
|
||||
expand = not obl.use_same_style
|
||||
lanpr_make_line_type_entry(layout, obl.contour, "Contour", expand, obl.target.data)
|
||||
lanpr_make_line_type_entry(layout, obl.crease, "Crease", expand, obl.target.data)
|
||||
lanpr_make_line_type_entry(layout, obl.material, "Material", expand, obl.target.data)
|
||||
lanpr_make_line_type_entry(layout, obl.edge_mark, "Edge Mark", expand, obl.target.data)
|
||||
|
||||
|
||||
class OBJECT_PT_lanpr(LanprButtonsPanel, Panel):
|
||||
bl_label = "Usage"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.render.engine == 'BLENDER_LANPR' or context.scene.lanpr.enabled
|
||||
|
||||
def draw(self, context):
|
||||
layout=self.layout
|
||||
lanpr = context.object.lanpr
|
||||
if context.object.type == 'MESH':
|
||||
layout.prop(lanpr,'usage')
|
||||
if lanpr.usage == 'INCLUDE':
|
||||
layout.prop(lanpr, "target")
|
||||
|
||||
|
||||
classes = (
|
||||
OBJECT_PT_lanpr,
|
||||
OBJECT_PT_lanpr_settings,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
from bpy.utils import register_class
|
||||
for cls in classes:
|
||||
register_class(cls)
|
@@ -67,14 +67,14 @@ class MaterialButtonsPanel:
|
||||
class MATERIAL_PT_preview(MaterialButtonsPanel, Panel):
|
||||
bl_label = "Preview"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_LANPR'}
|
||||
|
||||
def draw(self, context):
|
||||
self.layout.template_preview(context.material)
|
||||
|
||||
|
||||
class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_LANPR'}
|
||||
_context_path = "material"
|
||||
_property_type = bpy.types.Material
|
||||
|
||||
@@ -83,7 +83,7 @@ class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
|
||||
bl_label = ""
|
||||
bl_context = "material"
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_LANPR'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -162,7 +162,7 @@ def panel_node_draw(layout, ntree, _output_type, input_name):
|
||||
class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel):
|
||||
bl_label = "Surface"
|
||||
bl_context = "material"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_LANPR'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
@@ -18,12 +18,15 @@
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
from bpy.types import Panel
|
||||
from bl_ui.space_view3d import (
|
||||
VIEW3D_PT_shading_lighting,
|
||||
VIEW3D_PT_shading_color,
|
||||
VIEW3D_PT_shading_options,
|
||||
)
|
||||
from bpy.types import (
|
||||
Panel,
|
||||
UIList,
|
||||
)
|
||||
|
||||
|
||||
class RenderButtonsPanel:
|
||||
@@ -64,7 +67,7 @@ class RENDER_PT_color_management(RenderButtonsPanel, Panel):
|
||||
bl_label = "Color Management"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_order = 100
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_LANPR'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -97,7 +100,7 @@ class RENDER_PT_color_management_curves(RenderButtonsPanel, Panel):
|
||||
bl_label = "Use Curves"
|
||||
bl_parent_id = "RENDER_PT_color_management"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_LANPR'}
|
||||
|
||||
def draw_header(self, context):
|
||||
|
||||
@@ -461,7 +464,7 @@ class RENDER_PT_eevee_indirect_lighting_display(RenderButtonsPanel, Panel):
|
||||
class RENDER_PT_eevee_film(RenderButtonsPanel, Panel):
|
||||
bl_label = "Film"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_LANPR'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -685,6 +688,435 @@ class RENDER_PT_simplify_greasepencil(RenderButtonsPanel, Panel):
|
||||
sub.prop(rd, "simplify_gpencil_remove_lines", text="Lines")
|
||||
|
||||
|
||||
class LANPR_UL_linesets(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
layout.prop(item,"name", text="", emboss=False)
|
||||
|
||||
class RENDER_PT_lanpr(RenderButtonsPanel, Panel):
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_LANPR', 'BLENDER_OPENGL', 'BLENDER_EEVEE'}
|
||||
bl_label = "LANPR"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
||||
def draw_header(self, context):
|
||||
if context.scene.render.engine != 'BLENDER_LANPR':
|
||||
self.layout.prop(context.scene.lanpr, "enabled", text="")
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
active_layer = lanpr.layers.active_layer
|
||||
mode = lanpr.master_mode
|
||||
|
||||
layout = self.layout
|
||||
layout.active = scene.render.engine=="BLENDER_LANPR" or lanpr.enabled
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False # No animation.
|
||||
|
||||
col = layout.column()
|
||||
|
||||
if scene.render.engine=="BLENDER_LANPR":
|
||||
col.prop(lanpr, "master_mode")
|
||||
else:
|
||||
mode = "SOFTWARE"
|
||||
|
||||
if mode == "DPIX" and lanpr.shader_error:
|
||||
layout.label(text="DPIX transform shader compile error!")
|
||||
return
|
||||
|
||||
layout.prop(lanpr, "crease_threshold", slider=True)
|
||||
|
||||
if not scene.camera:
|
||||
has_camera=False
|
||||
col.label(text="No active camera.")
|
||||
else:
|
||||
has_camera=True
|
||||
|
||||
c=col.column()
|
||||
c.enabled = has_camera
|
||||
|
||||
if scene.render.engine=="BLENDER_LANPR":
|
||||
c.prop(lanpr,'auto_update', text='Auto Update')
|
||||
txt = "Update" if mode == "SOFTWARE" else "Intersection Cache"
|
||||
if not lanpr.auto_update:
|
||||
c.operator("scene.lanpr_calculate", icon='FILE_REFRESH', text=txt)
|
||||
|
||||
if mode == "DPIX" and len(lanpr.layers)==0:
|
||||
layout.label(text="You don't have a layer to display.")
|
||||
layout.operator("scene.lanpr_add_line_layer");
|
||||
|
||||
if scene.render.engine=="BLENDER_LANPR" and mode == "SOFTWARE":
|
||||
layout.operator("scene.lanpr_auto_create_line_layer", text = "Default", icon = "ADD")
|
||||
row=layout.row()
|
||||
row.template_list("LANPR_UL_linesets", "", lanpr, "layers", lanpr.layers, "active_layer_index", rows=4)
|
||||
col=row.column(align=True)
|
||||
if active_layer:
|
||||
col.operator("scene.lanpr_add_line_layer", icon="ADD", text='')
|
||||
col.operator("scene.lanpr_delete_line_layer", icon="REMOVE", text='')
|
||||
col.separator()
|
||||
col.operator("scene.lanpr_move_line_layer",icon='TRIA_UP', text='').direction = "UP"
|
||||
col.operator("scene.lanpr_move_line_layer",icon='TRIA_DOWN', text='').direction = "DOWN"
|
||||
col.separator()
|
||||
col.operator("scene.lanpr_rebuild_all_commands",icon="FILE_REFRESH", text='')
|
||||
else:
|
||||
col.operator("scene.lanpr_add_line_layer", icon="ADD", text='')
|
||||
|
||||
def lanpr_make_line_type(expand,layout,line_type,label):
|
||||
layout.prop(line_type, "use", text=label)
|
||||
if expand and line_type.use:
|
||||
c = layout.column(align=True)
|
||||
c.prop(line_type, "color", text="Color")
|
||||
c.prop(line_type, "thickness", slider=True)
|
||||
|
||||
class RENDER_PT_lanpr_layer_settings(RenderButtonsPanel, Panel):
|
||||
bl_label = "Layer Settings"
|
||||
bl_parent_id = "RENDER_PT_lanpr"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_LANPR', 'BLENDER_OPENGL', 'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
active_layer = lanpr.layers.active_layer
|
||||
return scene.render.engine=="BLENDER_LANPR" and active_layer
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
active_layer = lanpr.layers.active_layer
|
||||
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False # No animation.
|
||||
|
||||
mode = lanpr.master_mode
|
||||
if scene.render.engine!="BLENDER_LANPR" and mode != "SOFTWARE":
|
||||
mode = "SOFTWARE"
|
||||
|
||||
if active_layer and mode == "DPIX":
|
||||
active_layer = lanpr.layers[0]
|
||||
|
||||
if mode == "SOFTWARE":
|
||||
layout.prop(active_layer, "use_multiple_levels", text="Multiple Levels")
|
||||
col = layout.column(align=True)
|
||||
col.prop(active_layer, "level_start", text='Level Start')
|
||||
if active_layer.use_multiple_levels:
|
||||
col.prop(active_layer, "level_end", text='End')
|
||||
|
||||
layout.prop(active_layer,"use_same_style")
|
||||
|
||||
expand = not active_layer.use_same_style
|
||||
|
||||
col = layout.column(align=True)
|
||||
if not expand:
|
||||
col.prop(active_layer, "color")
|
||||
col.prop(active_layer, "thickness", text="Main Thickness")
|
||||
|
||||
lanpr_make_line_type(expand,layout,active_layer.contour,"Contour")
|
||||
lanpr_make_line_type(expand,layout,active_layer.crease,"Crease")
|
||||
lanpr_make_line_type(expand,layout,active_layer.edge_mark,"EdgeMark")
|
||||
lanpr_make_line_type(expand,layout,active_layer.material_separate,"Material")
|
||||
|
||||
if lanpr.use_intersections:
|
||||
lanpr_make_line_type(expand,layout,active_layer.intersection,"Intersection")
|
||||
else:
|
||||
layout.label(text= "Intersection calculation disabled.")
|
||||
|
||||
class RENDER_PT_lanpr_line_components(RenderButtonsPanel, Panel):
|
||||
bl_label = "Including"
|
||||
bl_parent_id = "RENDER_PT_lanpr"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_LANPR', 'BLENDER_OPENGL', 'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
active_layer = lanpr.layers.active_layer
|
||||
return scene.render.engine=="BLENDER_LANPR" and active_layer and not lanpr.enable_chaining
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
active_layer = lanpr.layers.active_layer
|
||||
|
||||
layout.operator("scene.lanpr_add_line_component")#, icon = "ZOOMIN")
|
||||
|
||||
i=0
|
||||
for c in active_layer.components:
|
||||
split = layout.split(factor=0.85)
|
||||
col = split.column()
|
||||
sp2 = col.split(factor=0.4)
|
||||
cl = sp2.column()
|
||||
cl.prop(c,"component_mode", text = "")
|
||||
cl = sp2.column()
|
||||
if c.component_mode == "OBJECT":
|
||||
cl.prop(c,"object_select", text = "")
|
||||
elif c.component_mode == "MATERIAL":
|
||||
cl.prop(c,"material_select", text = "")
|
||||
elif c.component_mode == "COLLECTION":
|
||||
cl.prop(c,"collection_select", text = "")
|
||||
col = split.column()
|
||||
col.operator("scene.lanpr_delete_line_component", text="").index=i
|
||||
i=i+1
|
||||
|
||||
|
||||
class RENDER_PT_lanpr_line_normal_effects(RenderButtonsPanel, Panel):
|
||||
bl_label = "Normal Based Line Weight"
|
||||
bl_parent_id = "RENDER_PT_lanpr"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_LANPR', 'BLENDER_OPENGL', 'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
active_layer = lanpr.layers.active_layer
|
||||
return scene.render.engine=="BLENDER_LANPR" and active_layer
|
||||
|
||||
def draw_header(self, context):
|
||||
active_layer = context.scene.lanpr.layers.active_layer
|
||||
self.layout.prop(active_layer, "normal_enabled", text="")
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
active_layer = lanpr.layers.active_layer
|
||||
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
layout.prop(active_layer,"normal_mode", text="Mode")
|
||||
if active_layer.normal_mode != "DISABLED":
|
||||
layout.prop(active_layer,"normal_control_object")
|
||||
layout.prop(active_layer,"normal_effect_inverse")
|
||||
col = layout.column(align=True)
|
||||
col.prop(active_layer,"normal_ramp_begin")
|
||||
col.prop(active_layer,"normal_ramp_end", text="End")
|
||||
col = layout.column(align=True)
|
||||
col.prop(active_layer,"normal_thickness_start", slider=True)
|
||||
col.prop(active_layer,"normal_thickness_end", slider=True, text="End")
|
||||
|
||||
class RENDER_PT_lanpr_line_gpu_effects(RenderButtonsPanel, Panel):
|
||||
bl_label = "Effects"
|
||||
bl_parent_id = "RENDER_PT_lanpr"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_LANPR', 'BLENDER_OPENGL', 'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
active_layer = lanpr.layers.active_layer
|
||||
return scene.render.engine=="BLENDER_LANPR" and active_layer and lanpr.master_mode == "DPIX"
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
active_layer = lanpr.layers.active_layer
|
||||
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
col = layout.column(align = True)
|
||||
col.prop(lanpr, "crease_threshold")
|
||||
col.prop(lanpr, "crease_fade_threshold", text="Fade")
|
||||
col = layout.column(align = True)
|
||||
col.prop(lanpr, "depth_width_influence")
|
||||
col.prop(lanpr, "depth_width_curve", text="Curve")
|
||||
col = layout.column(align = True)
|
||||
col.prop(lanpr, "depth_alpha_influence")
|
||||
col.prop(lanpr, "depth_alpha_curve", text="Curve")
|
||||
|
||||
|
||||
class RENDER_PT_lanpr_snake_sobel_parameters(RenderButtonsPanel, Panel):
|
||||
bl_label = "Sobel Parameters"
|
||||
bl_parent_id = "RENDER_PT_lanpr"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_LANPR', 'BLENDER_OPENGL', 'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
return scene.render.engine=="BLENDER_LANPR" and lanpr.master_mode == "SNAKE"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
layout.prop(lanpr, "depth_clamp")
|
||||
layout.prop(lanpr, "depth_strength")
|
||||
layout.prop(lanpr, "normal_clamp")
|
||||
layout.prop(lanpr, "normal_strength")
|
||||
if lanpr.enable_vector_trace == "DISABLED":
|
||||
layout.prop(lanpr, "display_thinning_result")
|
||||
|
||||
class RENDER_PT_lanpr_snake_settings(RenderButtonsPanel, Panel):
|
||||
bl_label = "Snake Settings"
|
||||
bl_parent_id = "RENDER_PT_lanpr"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_LANPR', 'BLENDER_OPENGL', 'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
return scene.render.engine=="BLENDER_LANPR" and lanpr.master_mode == "SNAKE" and lanpr.enable_vector_trace == "ENABLED"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.prop(lanpr, "background_color")
|
||||
col = split.column()
|
||||
col.prop(lanpr, "line_color")
|
||||
|
||||
layout.prop(lanpr, "line_thickness")
|
||||
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.prop(lanpr, "depth_width_influence")
|
||||
col.prop(lanpr, "depth_alpha_influence")
|
||||
col = split.column()
|
||||
col.prop(lanpr, "depth_width_curve")
|
||||
col.prop(lanpr, "depth_alpha_curve")
|
||||
|
||||
layout.label(text="Taper:")
|
||||
layout.prop(lanpr, "use_same_taper", expand = True)
|
||||
if lanpr.use_same_taper == "DISABLED":
|
||||
split = layout.split()
|
||||
col = split.column(align = True)
|
||||
col.label(text="Left:")
|
||||
col.prop(lanpr,"taper_left_distance")
|
||||
col.prop(lanpr,"taper_left_strength", text="Strength")
|
||||
col = split.column(align = True)
|
||||
col.label(text="Right:")
|
||||
col.prop(lanpr,"taper_right_distance")
|
||||
col.prop(lanpr,"taper_right_strength", text="Strength")
|
||||
else:
|
||||
split = layout.split()
|
||||
col = split.column(align = True)
|
||||
col.prop(lanpr,"taper_left_distance")
|
||||
col.prop(lanpr,"taper_left_strength")
|
||||
|
||||
layout.label(text="Tip Extend:")
|
||||
layout.prop(lanpr, "enable_tip_extend", expand = True)
|
||||
if lanpr.enable_tip_extend == "ENABLED":
|
||||
layout.label(text="---INOP---")
|
||||
layout.prop(lanpr,"extend_length")
|
||||
|
||||
class RENDER_PT_lanpr_gpencil(RenderButtonsPanel, Panel):
|
||||
bl_label = "Grease Pencil"
|
||||
bl_parent_id = "RENDER_PT_lanpr"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_LANPR', 'BLENDER_OPENGL', 'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
return scene.render.engine!='BLENDER_LANPR'
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
if not scene.camera:
|
||||
has_camera=False
|
||||
layout.label(text="No active camera.")
|
||||
else:
|
||||
has_camera=True
|
||||
|
||||
layout.enabled=has_camera
|
||||
layout.prop(lanpr,"auto_update", text='Auto Update')
|
||||
layout.prop(lanpr,"gpencil_overwrite", text='Overwrite')
|
||||
if not lanpr.auto_update:
|
||||
layout.operator("scene.lanpr_update_gp_strokes", icon='FILE_REFRESH', text='Update Grease Pencil Targets')
|
||||
layout.operator("scene.lanpr_bake_gp_strokes", icon='RENDER_ANIMATION', text='Bake All Frames')
|
||||
|
||||
class RENDER_PT_lanpr_software_chain_styles(RenderButtonsPanel, Panel):
|
||||
bl_label = "Chaining"
|
||||
bl_parent_id = "RENDER_PT_lanpr"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_LANPR', 'BLENDER_OPENGL', 'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
return lanpr.enable_chaining and not (scene.render.engine=='BLENDER_LANPR' and lanpr.master_mode=='DPIX')
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
layout.prop(lanpr, "chaining_geometry_threshold")
|
||||
layout.prop(lanpr, "chaining_image_threshold")
|
||||
|
||||
if scene.render.engine=="BLENDER_LANPR":
|
||||
layout.prop(lanpr, "use_same_taper", text="Taper Tips")
|
||||
if lanpr.use_same_taper == "DISABLED":
|
||||
col = layout.column(align = True)
|
||||
col.prop(lanpr,"taper_left_distance")
|
||||
col.prop(lanpr,"taper_left_strength", text="Strength")
|
||||
col = layout.column(align = True)
|
||||
col.prop(lanpr,"taper_right_distance")
|
||||
col.prop(lanpr,"taper_right_strength", text="Strength")
|
||||
else:
|
||||
col = layout.column(align = True)
|
||||
col.prop(lanpr,"taper_left_distance", text="Distance")
|
||||
col.prop(lanpr,"taper_left_strength", text="Strength")
|
||||
|
||||
class RENDER_PT_lanpr_options(RenderButtonsPanel, Panel):
|
||||
bl_label = "Settings"
|
||||
bl_parent_id = "RENDER_PT_lanpr"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_LANPR', 'BLENDER_OPENGL', 'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return True
|
||||
|
||||
def draw(self, context):
|
||||
scene = context.scene
|
||||
lanpr = scene.lanpr
|
||||
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
mode = lanpr.master_mode
|
||||
if scene.render.engine!="BLENDER_LANPR":
|
||||
mode = "SOFTWARE"
|
||||
|
||||
if mode == "DPIX":
|
||||
layout.prop(lanpr,"gpu_cache_size")
|
||||
|
||||
layout.prop(lanpr,"use_intersections")
|
||||
|
||||
if scene.render.engine=='BLENDER_LANPR' and lanpr.master_mode=='SOFTWARE':
|
||||
layout.prop(lanpr,"enable_chaining", text = "Chained Lines")
|
||||
|
||||
|
||||
classes = (
|
||||
RENDER_PT_context,
|
||||
RENDER_PT_eevee_sampling,
|
||||
@@ -714,6 +1146,16 @@ classes = (
|
||||
RENDER_PT_simplify_viewport,
|
||||
RENDER_PT_simplify_render,
|
||||
RENDER_PT_simplify_greasepencil,
|
||||
RENDER_PT_lanpr,
|
||||
RENDER_PT_lanpr_layer_settings,
|
||||
RENDER_PT_lanpr_gpencil,
|
||||
RENDER_PT_lanpr_line_normal_effects,
|
||||
RENDER_PT_lanpr_line_gpu_effects,
|
||||
RENDER_PT_lanpr_snake_sobel_parameters,
|
||||
RENDER_PT_lanpr_snake_settings,
|
||||
RENDER_PT_lanpr_software_chain_styles,
|
||||
RENDER_PT_lanpr_options,
|
||||
LANPR_UL_linesets,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
@@ -3462,7 +3462,7 @@ 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:
|
||||
if render.use_freestyle or scene.lanpr.enabled or render.engine=="BLENDER_LANPR":
|
||||
col.separator()
|
||||
|
||||
col.operator("mesh.mark_freestyle_edge").clear = False
|
||||
@@ -3653,11 +3653,11 @@ class VIEW3D_MT_edit_mesh_edges_data(Menu):
|
||||
props.use_verts = True
|
||||
props.clear = True
|
||||
|
||||
if render.use_freestyle:
|
||||
if scene.lanpr.enabled or render.engine=="BLENDER_LANPR":
|
||||
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_lanpr_edge").clear = False
|
||||
layout.operator("mesh.mark_lanpr_edge", text="Clear Freestyle Edge").clear = True
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_edges(Menu):
|
||||
@@ -3713,8 +3713,8 @@ class VIEW3D_MT_edit_mesh_edges(Menu):
|
||||
if with_freestyle:
|
||||
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_lanpr_edge").clear = False
|
||||
layout.operator("mesh.mark_lanpr_edge", text="Clear Freestyle Edge").clear = True
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_faces_data(Menu):
|
||||
@@ -3735,11 +3735,11 @@ class VIEW3D_MT_edit_mesh_faces_data(Menu):
|
||||
layout.operator("mesh.uvs_rotate")
|
||||
layout.operator("mesh.uvs_reverse")
|
||||
|
||||
layout.separator()
|
||||
if scene.lanpr.enabled or render.engine=="BLENDER_LANPR":
|
||||
layout.separator()
|
||||
|
||||
if with_freestyle:
|
||||
layout.operator("mesh.mark_freestyle_face").clear = False
|
||||
layout.operator("mesh.mark_freestyle_face", text="Clear Freestyle Face").clear = True
|
||||
layout.operator("mesh.mark_lanpr_face").clear = False
|
||||
layout.operator("mesh.mark_lanpr_cface", text="Clear Freestyle Face").clear = True
|
||||
|
||||
|
||||
class VIEW3D_MT_edit_mesh_faces(Menu):
|
||||
|
@@ -149,6 +149,10 @@ struct bGPDframe *BKE_gpencil_layer_getframe(struct bGPDlayer *gpl,
|
||||
struct bGPDframe *BKE_gpencil_layer_find_frame(struct bGPDlayer *gpl, int cframe);
|
||||
bool BKE_gpencil_layer_delframe(struct bGPDlayer *gpl, struct bGPDframe *gpf);
|
||||
|
||||
struct bGPDlayer *BKE_gpencil_layer_get_by_name(struct bGPdata *gpd,
|
||||
char *name,
|
||||
int first_if_not_found);
|
||||
|
||||
struct bGPDlayer *BKE_gpencil_layer_getactive(struct bGPdata *gpd);
|
||||
void BKE_gpencil_layer_setactive(struct bGPdata *gpd, struct bGPDlayer *active);
|
||||
void BKE_gpencil_layer_delete(struct bGPdata *gpd, struct bGPDlayer *gpl);
|
||||
@@ -174,6 +178,8 @@ struct Material *BKE_gpencil_object_material_new(struct Main *bmain,
|
||||
|
||||
int BKE_gpencil_object_material_get_index(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_get_from_brush(struct Object *ob,
|
||||
struct Brush *brush);
|
||||
int BKE_gpencil_object_material_get_index_from_brush(struct Object *ob, struct Brush *brush);
|
||||
|
@@ -255,6 +255,11 @@ void BKE_scene_cursor_from_mat4(struct View3DCursor *cursor,
|
||||
*/
|
||||
void BKE_scene_eval_sequencer_sequences(struct Depsgraph *depsgraph, struct Scene *scene);
|
||||
|
||||
/* LANPR */
|
||||
|
||||
void BKE_lanpr_copy_data(const struct Scene *from, struct Scene *to);
|
||||
void BKE_lanpr_free_everything(struct Scene *s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -991,6 +991,31 @@ bGPDlayer *BKE_gpencil_layer_getactive(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 */
|
||||
void BKE_gpencil_layer_setactive(bGPdata *gpd, bGPDlayer *active)
|
||||
{
|
||||
@@ -2125,6 +2150,21 @@ int BKE_gpencil_object_material_get_index(Object *ob, Material *ma)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int BKE_gpencil_object_material_get_index_name(Object *ob, char *name)
|
||||
{
|
||||
short *totcol = give_totcolp(ob);
|
||||
Material *read_ma = NULL;
|
||||
for (short i = 0; i < *totcol; i++) {
|
||||
read_ma = give_current_material(ob, i + 1);
|
||||
/* Material names are like "MAMaterial.001" */
|
||||
if (STREQ(name, &read_ma->id.name[2])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get points of stroke always flat to view not affected by camera view or view position */
|
||||
void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points,
|
||||
int totpoints,
|
||||
|
@@ -493,6 +493,8 @@ static void library_foreach_ID_link(Main *bmain,
|
||||
CALLBACK_INVOKE(child->collection, IDWALK_CB_USER);
|
||||
}
|
||||
|
||||
CALLBACK_INVOKE(scene->master_collection->lanpr.target, IDWALK_CB_USER);
|
||||
|
||||
ViewLayer *view_layer;
|
||||
for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
|
||||
CALLBACK_INVOKE(view_layer->mat_override, IDWALK_CB_USER);
|
||||
|
@@ -107,6 +107,7 @@
|
||||
|
||||
const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
|
||||
const char *RE_engine_id_BLENDER_WORKBENCH = "BLENDER_WORKBENCH";
|
||||
const char *RE_engine_id_BLENDER_LANPR = "BLENDER_LANPR";
|
||||
const char *RE_engine_id_CYCLES = "CYCLES";
|
||||
|
||||
void free_avicodecdata(AviCodecData *acd)
|
||||
@@ -227,6 +228,32 @@ void BKE_toolsettings_free(ToolSettings *toolsettings)
|
||||
MEM_freeN(toolsettings);
|
||||
}
|
||||
|
||||
void BKE_lanpr_copy_data(const Scene *from, Scene *to)
|
||||
{
|
||||
const SceneLANPR *lanpr = &from->lanpr;
|
||||
LANPR_LineLayer *ll, *new_ll;
|
||||
LANPR_LineLayerComponent *llc, *new_llc;
|
||||
|
||||
to->lanpr.line_layers.first = to->lanpr.line_layers.last = NULL;
|
||||
memset(&to->lanpr.line_layers, 0, sizeof(ListBase));
|
||||
|
||||
for (ll = lanpr->line_layers.first; ll; ll = ll->next) {
|
||||
new_ll = MEM_callocN(sizeof(LANPR_LineLayer), "Copied Line Layer");
|
||||
memcpy(new_ll, ll, sizeof(LANPR_LineLayer));
|
||||
memset(&new_ll->components, 0, sizeof(ListBase));
|
||||
new_ll->next = new_ll->prev = NULL;
|
||||
BLI_addtail(&to->lanpr.line_layers, new_ll);
|
||||
for (llc = ll->components.first; llc; llc = llc->next) {
|
||||
new_llc = MEM_callocN(sizeof(LANPR_LineLayerComponent), "Copied Line Layer Component");
|
||||
memcpy(new_llc, llc, sizeof(LANPR_LineLayerComponent));
|
||||
new_llc->next = new_llc->prev = NULL;
|
||||
BLI_addtail(&new_ll->components, new_llc);
|
||||
}
|
||||
}
|
||||
|
||||
/* render_buffer now only accessible from lanpr_share */
|
||||
}
|
||||
|
||||
/**
|
||||
* Only copy internal data of Scene ID from source
|
||||
* to already allocated/initialized destination.
|
||||
@@ -342,6 +369,10 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
|
||||
sce_dst->eevee.light_cache = NULL;
|
||||
sce_dst->eevee.light_cache_info[0] = '\0';
|
||||
/* TODO Copy the cache. */
|
||||
|
||||
/* lanpr data */
|
||||
|
||||
BKE_lanpr_copy_data(sce_src, sce_dst);
|
||||
}
|
||||
|
||||
Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
|
||||
@@ -478,6 +509,20 @@ void BKE_scene_make_local(Main *bmain, Scene *sce, const bool lib_local)
|
||||
BKE_id_make_local_generic(bmain, &sce->id, true, lib_local);
|
||||
}
|
||||
|
||||
void BKE_lanpr_free_everything(Scene *s)
|
||||
{
|
||||
SceneLANPR *lanpr = &s->lanpr;
|
||||
LANPR_LineLayer *ll;
|
||||
LANPR_LineLayerComponent *llc;
|
||||
|
||||
while ((ll = BLI_pophead(&lanpr->line_layers)) != NULL) {
|
||||
while ((llc = BLI_pophead(&ll->components)) != NULL) {
|
||||
MEM_freeN(llc);
|
||||
}
|
||||
MEM_freeN(ll);
|
||||
}
|
||||
}
|
||||
|
||||
/** Free (or release) any data used by this scene (does not free the scene itself). */
|
||||
void BKE_scene_free_ex(Scene *sce, const bool do_id_user)
|
||||
{
|
||||
@@ -733,6 +778,19 @@ void BKE_scene_init(Scene *sce)
|
||||
sce->master_collection = BKE_collection_master_add();
|
||||
|
||||
BKE_view_layer_add(sce, "View Layer");
|
||||
|
||||
/* SceneLANPR */
|
||||
|
||||
sce->lanpr.crease_threshold = 0.7;
|
||||
|
||||
sce->lanpr.line_color[0] = 1;
|
||||
sce->lanpr.line_color[1] = 1;
|
||||
sce->lanpr.line_color[2] = 1;
|
||||
sce->lanpr.line_color[3] = 1;
|
||||
|
||||
sce->lanpr.flags |= (LANPR_USE_CHAINING | LANPR_USE_INTERSECTIONS);
|
||||
sce->lanpr.chaining_image_threshold = 0.01;
|
||||
sce->lanpr.chaining_geometry_threshold = 0.1;
|
||||
}
|
||||
|
||||
Scene *BKE_scene_add(Main *bmain, const char *name)
|
||||
|
@@ -78,6 +78,7 @@
|
||||
#include "DNA_packedFile_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
#include "DNA_lightprobe_types.h"
|
||||
#include "DNA_lanpr_types.h"
|
||||
#include "DNA_rigidbody_types.h"
|
||||
#include "DNA_text_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
@@ -6246,6 +6247,8 @@ static void lib_link_collection_data(FileData *fd, Library *lib, Collection *col
|
||||
child->collection = newlibadr_us(fd, lib, child->collection);
|
||||
}
|
||||
|
||||
collection->lanpr.target = newlibadr_us(fd, lib, collection->lanpr.target);
|
||||
|
||||
BKE_collection_parent_relations_rebuild(collection);
|
||||
}
|
||||
|
||||
@@ -6558,6 +6561,16 @@ static void lib_link_scene(FileData *fd, Main *main)
|
||||
fls->group = newlibadr_us(fd, sce->id.lib, fls->group);
|
||||
}
|
||||
}
|
||||
|
||||
for (LANPR_LineLayer *ll = sce->lanpr.line_layers.first; ll; ll = ll->next) {
|
||||
for (LANPR_LineLayerComponent *llc = ll->components.first; llc; llc = llc->next) {
|
||||
llc->object_select = newlibadr_us(fd, sce->id.lib, llc->object_select);
|
||||
llc->material_select = newlibadr_us(fd, sce->id.lib, llc->material_select);
|
||||
llc->collection_select = newlibadr_us(fd, sce->id.lib, llc->collection_select);
|
||||
}
|
||||
ll->normal_control_object = newlibadr_us(fd, sce->id.lib, ll->normal_control_object);
|
||||
}
|
||||
|
||||
/* Motion Tracking */
|
||||
sce->clip = newlibadr_us(fd, sce->id.lib, sce->clip);
|
||||
|
||||
@@ -6995,6 +7008,21 @@ static void direct_link_scene(FileData *fd, Scene *sce)
|
||||
}
|
||||
}
|
||||
|
||||
/* LANPR things */
|
||||
sce->lanpr.active_layer = newdataadr(fd, sce->lanpr.active_layer);
|
||||
link_list(fd, &sce->lanpr.line_layers);
|
||||
for (LANPR_LineLayer *ll = sce->lanpr.line_layers.first; ll; ll = ll->next) {
|
||||
link_list(fd, &ll->components);
|
||||
for (LANPR_LineLayerComponent *llc = ll->components.first; llc; llc = llc->next) {
|
||||
// llc->object_select = newlibadr(fd, sce->id.lib, llc->object_select);
|
||||
// llc->material_select = newlibadr(fd, sce->id.lib, llc->material_select);
|
||||
// llc->collection_select = newlibadr(fd, sce->id.lib, llc->collection_select);
|
||||
}
|
||||
ll->batch = NULL;
|
||||
ll->shgrp = NULL;
|
||||
// ll->normal_control_object = newlibadr(fd, sce->id.lib, ll->normal_control_object);
|
||||
}
|
||||
|
||||
direct_link_view3dshading(fd, &sce->display.shading);
|
||||
|
||||
sce->layer_properties = newdataadr(fd, sce->layer_properties);
|
||||
@@ -10323,6 +10351,8 @@ static void expand_collection(FileData *fd, Main *mainvar, Collection *collectio
|
||||
expand_doit(fd, mainvar, child->collection);
|
||||
}
|
||||
|
||||
expand_doit(fd, mainvar, collection->lanpr.target);
|
||||
|
||||
#ifdef USE_COLLECTION_COMPAT_28
|
||||
if (collection->collection != NULL) {
|
||||
expand_scene_collection(fd, mainvar, collection->collection);
|
||||
@@ -10780,10 +10810,22 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
|
||||
}
|
||||
}
|
||||
|
||||
if (sce->gpd) {
|
||||
expand_doit(fd, mainvar, sce->gpd);
|
||||
for (LANPR_LineLayer *ll = sce->lanpr.line_layers.first; ll; ll = ll->next) {
|
||||
for (LANPR_LineLayerComponent *llc = ll->components.first; llc; llc = llc->next) {
|
||||
if (llc->object_select)
|
||||
expand_doit(fd, mainvar, llc->object_select);
|
||||
if (llc->material_select)
|
||||
expand_doit(fd, mainvar, llc->material_select);
|
||||
if (llc->collection_select)
|
||||
expand_doit(fd, mainvar, llc->collection_select);
|
||||
}
|
||||
if (ll->normal_control_object)
|
||||
expand_doit(fd, mainvar, ll->normal_control_object);
|
||||
}
|
||||
|
||||
if (sce->gpd)
|
||||
expand_doit(fd, mainvar, sce->gpd);
|
||||
|
||||
if (sce->ed) {
|
||||
Sequence *seq;
|
||||
|
||||
|
@@ -1799,7 +1799,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
||||
|
||||
scene->eevee.flag = SCE_EEVEE_VOLUMETRIC_LIGHTS | SCE_EEVEE_GTAO_BENT_NORMALS |
|
||||
SCE_EEVEE_GTAO_BOUNCE | SCE_EEVEE_TAA_REPROJECTION |
|
||||
SCE_EEVEE_SSR_HALF_RESOLUTION;
|
||||
SCE_EEVEE_SSR_HALF_RESOLUTION | SCE_EEVEE_SHADOW_SOFT;
|
||||
|
||||
/* If the file is pre-2.80 move on. */
|
||||
if (scene->layer_properties == NULL) {
|
||||
@@ -1928,6 +1928,20 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
||||
}
|
||||
}
|
||||
|
||||
if (!DNA_struct_find(fd->filesdna, "SceneLANPR")) {
|
||||
for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
|
||||
|
||||
scene->lanpr.crease_threshold = 0.7;
|
||||
|
||||
scene->lanpr.flags |= (LANPR_USE_CHAINING | LANPR_USE_INTERSECTIONS);
|
||||
|
||||
scene->lanpr.line_color[0] = 0.39;
|
||||
scene->lanpr.line_color[1] = 0.12;
|
||||
scene->lanpr.line_color[2] = 0.04;
|
||||
scene->lanpr.line_color[3] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 280, 15)) {
|
||||
for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
|
||||
scene->display.matcap_ssao_distance = 0.2f;
|
||||
@@ -3630,6 +3644,22 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
||||
do_versions_seq_alloc_transform_and_crop(&scene->ed->seqbase);
|
||||
}
|
||||
}
|
||||
for (Scene *sce = bmain->scenes.first; sce; sce = sce->id.next) {
|
||||
sce->lanpr.crease_threshold = 0.7;
|
||||
|
||||
zero_v4(sce->lanpr.line_color);
|
||||
|
||||
sce->lanpr.flags |= (LANPR_USE_CHAINING | LANPR_USE_INTERSECTIONS);
|
||||
sce->lanpr.chaining_image_threshold = 0.01f;
|
||||
sce->lanpr.chaining_geometry_threshold = 0.0f;
|
||||
}
|
||||
for (Collection *co = bmain->collections.first; co; co = co->id.next) {
|
||||
co->lanpr.contour.use = 1;
|
||||
co->lanpr.crease.use = 1;
|
||||
co->lanpr.material.use = 1;
|
||||
co->lanpr.edge_mark.use = 1;
|
||||
co->lanpr.intersection.use = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 280, 75)) {
|
||||
|
@@ -121,6 +121,7 @@
|
||||
#include "DNA_packedFile_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
#include "DNA_lightprobe_types.h"
|
||||
#include "DNA_lanpr_types.h"
|
||||
#include "DNA_rigidbody_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_sdna_types.h"
|
||||
@@ -2691,6 +2692,14 @@ static void write_scene(WriteData *wd, Scene *sce)
|
||||
write_lightcache(wd, sce->eevee.light_cache);
|
||||
}
|
||||
|
||||
/* LANPR Line Layers */
|
||||
for (LANPR_LineLayer *ll = sce->lanpr.line_layers.first; ll; ll = ll->next) {
|
||||
writestruct(wd, DATA, LANPR_LineLayer, 1, ll);
|
||||
for (LANPR_LineLayerComponent *llc = ll->components.first; llc; llc = llc->next) {
|
||||
writestruct(wd, DATA, LANPR_LineLayerComponent, 1, llc);
|
||||
}
|
||||
}
|
||||
|
||||
write_view3dshading(wd, &sce->display.shading);
|
||||
|
||||
/* Freed on doversion. */
|
||||
|
@@ -133,6 +133,10 @@ set(SRC
|
||||
engines/gpencil/gpencil_engine.h
|
||||
engines/gpencil/gpencil_render.c
|
||||
engines/gpencil/gpencil_shader_fx.c
|
||||
engines/lanpr/lanpr_dpix.c
|
||||
engines/lanpr/lanpr_engine.c
|
||||
engines/lanpr/lanpr_cpu.c
|
||||
engines/lanpr/lanpr_chain_draw.c
|
||||
engines/select/select_draw_utils.c
|
||||
engines/select/select_engine.c
|
||||
|
||||
@@ -161,6 +165,7 @@ set(SRC
|
||||
engines/external/external_engine.h
|
||||
engines/workbench/workbench_engine.h
|
||||
engines/workbench/workbench_private.h
|
||||
engines/lanpr/lanpr_all.h
|
||||
engines/select/select_engine.h
|
||||
engines/select/select_private.h
|
||||
)
|
||||
@@ -259,6 +264,21 @@ data_to_c_simple(engines/workbench/shaders/workbench_volume_vert.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_volume_frag.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_world_light_lib.glsl SRC)
|
||||
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_dpix_preview_geom.glsl SRC)
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_dpix_preview_frag.glsl SRC)
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_dpix_project_clip_frag.glsl SRC)
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_dpix_project_passthrough_vert.glsl SRC)
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_snake_image_peel_frag.glsl SRC)
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_snake_line_connection_vert.glsl SRC)
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_snake_line_connection_geom.glsl SRC)
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_snake_line_connection_frag.glsl SRC)
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_snake_edge_frag.glsl SRC)
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_snake_multichannel_frag.glsl SRC)
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_software_line_chain_geom.glsl SRC)
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_software_passthrough_vert.glsl SRC)
|
||||
data_to_c_simple(engines/lanpr/shaders/lanpr_software_chain_geom.glsl SRC)
|
||||
|
||||
|
||||
data_to_c_simple(modes/shaders/common_colormanagement_lib.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/common_globals_lib.glsl SRC)
|
||||
data_to_c_simple(modes/shaders/common_hair_lib.glsl SRC)
|
||||
|
266
source/blender/draw/engines/lanpr/lanpr_all.h
Normal file
266
source/blender/draw/engines/lanpr/lanpr_all.h
Normal file
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#ifndef __LANPR_ALL_H__
|
||||
#define __LANPR_ALL_H__
|
||||
|
||||
#include "BLI_mempool.h"
|
||||
#include "BLI_threads.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_lanpr_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "ED_lanpr.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_immediate_util.h"
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_texture.h"
|
||||
#include "GPU_uniformbuffer.h"
|
||||
#include "GPU_viewport.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
#define LANPR_ENGINE "BLENDER_LANPR"
|
||||
|
||||
#define deg(r) r / M_PI * 180.0
|
||||
#define rad(d) d *M_PI / 180.0
|
||||
|
||||
#define tMatDist2v(p1, p2) \
|
||||
sqrt(((p1)[0] - (p2)[0]) * ((p1)[0] - (p2)[0]) + ((p1)[1] - (p2)[1]) * ((p1)[1] - (p2)[1]))
|
||||
|
||||
extern struct RenderEngineType DRW_engine_viewport_lanpr_type;
|
||||
extern struct DrawEngineType draw_engine_lanpr_type;
|
||||
|
||||
typedef struct LANPR_RenderBuffer LANPR_RenderBuffer;
|
||||
|
||||
typedef struct LANPR_PassList {
|
||||
/* Image filtering */
|
||||
struct DRWPass *depth_pass;
|
||||
struct DRWPass *color_pass;
|
||||
struct DRWPass *normal_pass;
|
||||
struct DRWPass *edge_intermediate;
|
||||
struct DRWPass *edge_thinning;
|
||||
struct DRWPass *snake_pass;
|
||||
|
||||
/* GPU */
|
||||
struct DRWPass *dpix_transform_pass;
|
||||
struct DRWPass *dpix_preview_pass;
|
||||
|
||||
/* SOFTWARE */
|
||||
struct DRWPass *software_pass;
|
||||
|
||||
} LANPR_PassList;
|
||||
|
||||
typedef struct LANPR_FramebufferList {
|
||||
|
||||
/* CPU */
|
||||
struct GPUFrameBuffer *passes;
|
||||
struct GPUFrameBuffer *edge_intermediate;
|
||||
struct GPUFrameBuffer *edge_thinning;
|
||||
|
||||
/* GPU */
|
||||
struct GPUFrameBuffer *dpix_transform;
|
||||
struct GPUFrameBuffer *dpix_preview;
|
||||
|
||||
/* Image filtering */
|
||||
struct GPUFrameBuffer *software_ms;
|
||||
|
||||
} LANPR_FramebufferList;
|
||||
|
||||
typedef struct LANPR_TextureList {
|
||||
|
||||
struct GPUTexture *color;
|
||||
struct GPUTexture *normal;
|
||||
struct GPUTexture *depth;
|
||||
struct GPUTexture *edge_intermediate;
|
||||
|
||||
struct GPUTexture *dpix_in_pl;
|
||||
struct GPUTexture *dpix_in_pr;
|
||||
struct GPUTexture *dpix_in_nl;
|
||||
struct GPUTexture *dpix_in_nr;
|
||||
|
||||
/** RGBA texture format,
|
||||
* R:Material, G: Freestyle Edge Mark,
|
||||
* BA:Reserved for future usages */
|
||||
struct GPUTexture *dpix_in_edge_mask;
|
||||
|
||||
struct GPUTexture *dpix_out_pl;
|
||||
struct GPUTexture *dpix_out_pr;
|
||||
struct GPUTexture *dpix_out_length;
|
||||
|
||||
/** Multisample resolve */
|
||||
struct GPUTexture *ms_resolve_depth;
|
||||
struct GPUTexture *ms_resolve_color;
|
||||
|
||||
} LANPR_TextureList;
|
||||
|
||||
typedef struct LANPR_PrivateData {
|
||||
DRWShadingGroup *multipass_shgrp;
|
||||
DRWShadingGroup *edge_detect_shgrp;
|
||||
DRWShadingGroup *edge_thinning_shgrp;
|
||||
DRWShadingGroup *snake_shgrp;
|
||||
|
||||
DRWShadingGroup *dpix_transform_shgrp;
|
||||
DRWShadingGroup *dpix_preview_shgrp;
|
||||
|
||||
DRWShadingGroup *debug_shgrp;
|
||||
|
||||
/* Image filtering */
|
||||
|
||||
float normal_clamp;
|
||||
float normal_strength;
|
||||
float depth_clamp;
|
||||
float depth_strength;
|
||||
|
||||
float zfar;
|
||||
float znear;
|
||||
|
||||
/** Thinning stage */
|
||||
int stage;
|
||||
|
||||
float *line_result;
|
||||
unsigned char *line_result_8bit;
|
||||
|
||||
/** If not match then recreate buffer. */
|
||||
int width, height;
|
||||
void **sample_table;
|
||||
|
||||
ListBase pending_samples;
|
||||
ListBase erased_samples;
|
||||
ListBase line_strips;
|
||||
|
||||
/* dpix data */
|
||||
|
||||
void *atlas_pl;
|
||||
void *atlas_pr;
|
||||
void *atlas_nl;
|
||||
void *atlas_nr;
|
||||
void *atlas_edge_mask;
|
||||
|
||||
int begin_index;
|
||||
|
||||
int dpix_sample_step;
|
||||
int dpix_is_perspective;
|
||||
float dpix_viewport[4];
|
||||
float output_viewport[4];
|
||||
int dpix_buffer_width;
|
||||
float dpix_depth_offset;
|
||||
|
||||
float dpix_znear;
|
||||
float dpix_zfar;
|
||||
|
||||
/* drawing */
|
||||
|
||||
unsigned v_buf;
|
||||
unsigned i_buf;
|
||||
unsigned l_buf;
|
||||
|
||||
GPUVertFormat snake_gwn_format;
|
||||
GPUBatch *snake_batch;
|
||||
} LANPR_PrivateData;
|
||||
|
||||
typedef struct LANPR_StorageList {
|
||||
LANPR_PrivateData *g_data;
|
||||
} LANPR_StorageList;
|
||||
|
||||
typedef struct LANPR_BatchItem {
|
||||
Link item;
|
||||
GPUBatch *dpix_transform_batch;
|
||||
GPUBatch *dpix_preview_batch;
|
||||
Object *ob;
|
||||
} LANPR_BatchItem;
|
||||
|
||||
typedef struct LANPR_Data {
|
||||
void *engine_type;
|
||||
LANPR_FramebufferList *fbl;
|
||||
LANPR_TextureList *txl;
|
||||
LANPR_PassList *psl;
|
||||
LANPR_StorageList *stl;
|
||||
} LANPR_Data;
|
||||
|
||||
/* functions */
|
||||
|
||||
void lanpr_init_atlas_inputs(void *ved);
|
||||
void lanpr_destroy_atlas(void *ved);
|
||||
int lanpr_feed_atlas_data_obj(void *vedata,
|
||||
float *AtlasPointsL,
|
||||
float *AtlasPointsR,
|
||||
float *AtlasFaceNormalL,
|
||||
float *AtlasFaceNormalR,
|
||||
float *AtlasEdgeMask,
|
||||
Object *ob,
|
||||
int begin_index);
|
||||
|
||||
int lanpr_feed_atlas_data_intersection_cache(void *vedata,
|
||||
float *AtlasPointsL,
|
||||
float *AtlasPointsR,
|
||||
float *AtlasFaceNormalL,
|
||||
float *AtlasFaceNormalR,
|
||||
float *AtlasEdgeMask,
|
||||
int begin_index);
|
||||
|
||||
int lanpr_feed_atlas_trigger_preview_obj(void *vedata, Object *ob, int begin_index);
|
||||
void lanpr_create_atlas_intersection_preview(void *vedata, int begin_index);
|
||||
|
||||
void lanpr_dpix_draw_scene(LANPR_TextureList *txl,
|
||||
LANPR_FramebufferList *fbl,
|
||||
LANPR_PassList *psl,
|
||||
LANPR_PrivateData *pd,
|
||||
SceneLANPR *lanpr,
|
||||
GPUFrameBuffer *DefaultFB,
|
||||
int is_render);
|
||||
|
||||
void lanpr_snake_draw_scene(LANPR_TextureList *txl,
|
||||
LANPR_FramebufferList *fbl,
|
||||
LANPR_PassList *psl,
|
||||
LANPR_PrivateData *pd,
|
||||
SceneLANPR *lanpr,
|
||||
GPUFrameBuffer *DefaultFB,
|
||||
int is_render);
|
||||
|
||||
void lanpr_software_draw_scene(void *vedata, GPUFrameBuffer *dfb, int is_render);
|
||||
|
||||
int lanpr_dpix_texture_size(SceneLANPR *lanpr);
|
||||
|
||||
void lanpr_chain_generate_draw_command(struct LANPR_RenderBuffer *rb);
|
||||
|
||||
#endif
|
196
source/blender/draw/engines/lanpr/lanpr_chain_draw.c
Normal file
196
source/blender/draw/engines/lanpr/lanpr_chain_draw.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_lanpr_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "DRW_engine.h"
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_immediate_util.h"
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_uniformbuffer.h"
|
||||
#include "GPU_viewport.h"
|
||||
|
||||
#include "lanpr_all.h"
|
||||
#include "bmesh.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
static float ED_lanpr_compute_chain_length_draw(LANPR_RenderLineChain *rlc,
|
||||
float *lengths,
|
||||
int begin_index)
|
||||
{
|
||||
LANPR_RenderLineChainItem *rlci;
|
||||
int i = 0;
|
||||
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;
|
||||
lengths[begin_index + i] = offset_accum;
|
||||
copy_v2_v2(last_point, rlci->pos);
|
||||
i++;
|
||||
}
|
||||
return offset_accum;
|
||||
}
|
||||
|
||||
static int lanpr_get_gpu_line_type(LANPR_RenderLineChainItem *rlci)
|
||||
{
|
||||
switch (rlci->line_type) {
|
||||
case LANPR_EDGE_FLAG_CONTOUR:
|
||||
return 0;
|
||||
case LANPR_EDGE_FLAG_CREASE:
|
||||
return 1;
|
||||
case LANPR_EDGE_FLAG_MATERIAL:
|
||||
return 2;
|
||||
case LANPR_EDGE_FLAG_EDGE_MARK:
|
||||
return 3;
|
||||
case LANPR_EDGE_FLAG_INTERSECTION:
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void lanpr_chain_generate_draw_command(LANPR_RenderBuffer *rb)
|
||||
{
|
||||
LANPR_RenderLineChain *rlc;
|
||||
LANPR_RenderLineChainItem *rlci;
|
||||
int vert_count = 0;
|
||||
int i = 0;
|
||||
int arg;
|
||||
float total_length;
|
||||
float *lengths;
|
||||
float length_target[2];
|
||||
|
||||
static GPUVertFormat format = {0};
|
||||
static struct {
|
||||
uint pos, uvs, normal, type, level;
|
||||
} attr_id;
|
||||
if (format.attr_len == 0) {
|
||||
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
attr_id.uvs = GPU_vertformat_attr_add(&format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
attr_id.normal = GPU_vertformat_attr_add(&format, "normal", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
attr_id.type = GPU_vertformat_attr_add(&format, "type", GPU_COMP_I32, 1, GPU_FETCH_INT);
|
||||
attr_id.level = GPU_vertformat_attr_add(&format, "level", GPU_COMP_I32, 1, GPU_FETCH_INT);
|
||||
}
|
||||
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
|
||||
for (rlc = rb->chains.first; rlc; rlc = rlc->next) {
|
||||
int count = ED_lanpr_count_chain(rlc);
|
||||
/* printf("seg contains %d verts\n", count); */
|
||||
vert_count += count;
|
||||
}
|
||||
|
||||
GPU_vertbuf_data_alloc(vbo, vert_count + 1); /* serve as end point's adj. */
|
||||
|
||||
lengths = MEM_callocN(sizeof(float) * vert_count, "chain lengths");
|
||||
|
||||
GPUIndexBufBuilder elb;
|
||||
GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINES_ADJ, vert_count * 4, vert_count);
|
||||
|
||||
for (rlc = rb->chains.first; rlc; rlc = rlc->next) {
|
||||
|
||||
total_length = ED_lanpr_compute_chain_length_draw(rlc, lengths, i);
|
||||
|
||||
for (rlci = rlc->chain.first; rlci; rlci = rlci->next) {
|
||||
|
||||
length_target[0] = lengths[i];
|
||||
length_target[1] = total_length - lengths[i];
|
||||
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.pos, i, rlci->pos);
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.normal, i, rlci->normal);
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.uvs, i, length_target);
|
||||
|
||||
arg = lanpr_get_gpu_line_type(rlci);
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.type, i, &arg);
|
||||
|
||||
arg = (int)rlci->occlusion;
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.level, i, &arg);
|
||||
|
||||
if (rlci == rlc->chain.last) {
|
||||
if (rlci->prev == rlc->chain.first) {
|
||||
length_target[1] = total_length;
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.uvs, i, length_target);
|
||||
}
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rlci == rlc->chain.first) {
|
||||
if (rlci->next == rlc->chain.last) {
|
||||
GPU_indexbuf_add_line_adj_verts(&elb, vert_count, i, i + 1, vert_count);
|
||||
}
|
||||
else {
|
||||
GPU_indexbuf_add_line_adj_verts(&elb, vert_count, i, i + 1, i + 2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rlci->next == rlc->chain.last) {
|
||||
GPU_indexbuf_add_line_adj_verts(&elb, i - 1, i, i + 1, vert_count);
|
||||
}
|
||||
else {
|
||||
GPU_indexbuf_add_line_adj_verts(&elb, i - 1, i, i + 1, i + 2);
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
/* set end point flag value. */
|
||||
length_target[0] = 3e30f;
|
||||
length_target[1] = 3e30f;
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.pos, vert_count, length_target);
|
||||
|
||||
MEM_freeN(lengths);
|
||||
|
||||
if (rb->chain_draw_batch) {
|
||||
GPU_BATCH_DISCARD_SAFE(rb->chain_draw_batch);
|
||||
}
|
||||
rb->chain_draw_batch = GPU_batch_create_ex(GPU_PRIM_LINES_ADJ,
|
||||
vbo,
|
||||
GPU_indexbuf_build(&elb),
|
||||
GPU_USAGE_DYNAMIC | GPU_BATCH_OWNS_VBO |
|
||||
GPU_BATCH_OWNS_INDEX);
|
||||
}
|
514
source/blender/draw/engines/lanpr/lanpr_cpu.c
Normal file
514
source/blender/draw/engines/lanpr/lanpr_cpu.c
Normal file
@@ -0,0 +1,514 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_lanpr_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_text_types.h"
|
||||
|
||||
#include "DRW_engine.h"
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "ED_lanpr.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_gpencil.h"
|
||||
#include "BKE_gpencil_modifier.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_text.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_immediate_util.h"
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_uniformbuffer.h"
|
||||
#include "GPU_viewport.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh_class.h"
|
||||
#include "bmesh_tools.h"
|
||||
|
||||
#include "lanpr_all.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
extern LANPR_SharedResource lanpr_share;
|
||||
extern const char *RE_engine_id_BLENDER_LANPR;
|
||||
|
||||
static void lanpr_rebuild_render_draw_command(LANPR_RenderBuffer *rb, LANPR_LineLayer *ll)
|
||||
{
|
||||
int Count = 0;
|
||||
float *v, *tv, *N, *tn;
|
||||
int i;
|
||||
int vertCount;
|
||||
|
||||
static GPUVertFormat format = {0};
|
||||
static struct {
|
||||
uint pos, normal;
|
||||
} attr_id;
|
||||
if (format.attr_len == 0) {
|
||||
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
attr_id.normal = GPU_vertformat_attr_add(&format, "normal", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
||||
}
|
||||
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
|
||||
if (ll->contour.use) {
|
||||
Count += ED_lanpr_count_leveled_edge_segment_count(&rb->contours, ll);
|
||||
}
|
||||
if (ll->crease.use) {
|
||||
Count += ED_lanpr_count_leveled_edge_segment_count(&rb->crease_lines, ll);
|
||||
}
|
||||
if (ll->intersection.use) {
|
||||
Count += ED_lanpr_count_leveled_edge_segment_count(&rb->intersection_lines, ll);
|
||||
}
|
||||
if (ll->edge_mark.use) {
|
||||
Count += ED_lanpr_count_leveled_edge_segment_count(&rb->edge_marks, ll);
|
||||
}
|
||||
if (ll->material_separate.use) {
|
||||
Count += ED_lanpr_count_leveled_edge_segment_count(&rb->material_lines, ll);
|
||||
}
|
||||
|
||||
vertCount = Count * 2;
|
||||
|
||||
if (!vertCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
GPU_vertbuf_data_alloc(vbo, vertCount);
|
||||
|
||||
tv = v = MEM_callocN(sizeof(float) * 6 * Count, "temp v data");
|
||||
tn = N = MEM_callocN(sizeof(float) * 6 * Count, "temp n data");
|
||||
|
||||
if (ll->contour.use) {
|
||||
tv = ED_lanpr_make_leveled_edge_vertex_array(rb, &rb->contours, tv, tn, &tn, ll, 1.0f);
|
||||
}
|
||||
if (ll->crease.use) {
|
||||
tv = ED_lanpr_make_leveled_edge_vertex_array(rb, &rb->crease_lines, tv, tn, &tn, ll, 2.0f);
|
||||
}
|
||||
if (ll->material_separate.use) {
|
||||
tv = ED_lanpr_make_leveled_edge_vertex_array(rb, &rb->material_lines, tv, tn, &tn, ll, 3.0f);
|
||||
}
|
||||
if (ll->edge_mark.use) {
|
||||
tv = ED_lanpr_make_leveled_edge_vertex_array(rb, &rb->edge_marks, tv, tn, &tn, ll, 4.0f);
|
||||
}
|
||||
if (ll->intersection.use) {
|
||||
tv = ED_lanpr_make_leveled_edge_vertex_array(
|
||||
rb, &rb->intersection_lines, tv, tn, &tn, ll, 5.0f);
|
||||
}
|
||||
|
||||
for (i = 0; i < vertCount; i++) {
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.pos, i, &v[i * 3]);
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.normal, i, &N[i * 3]);
|
||||
}
|
||||
|
||||
MEM_freeN(v);
|
||||
MEM_freeN(N);
|
||||
|
||||
ll->batch = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, 0, GPU_USAGE_DYNAMIC | GPU_BATCH_OWNS_VBO);
|
||||
}
|
||||
void ED_lanpr_rebuild_all_command(SceneLANPR *lanpr)
|
||||
{
|
||||
LANPR_LineLayer *ll;
|
||||
if (!lanpr || !lanpr_share.render_buffer_shared) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (lanpr->flags & LANPR_USE_CHAINING) {
|
||||
lanpr_chain_generate_draw_command(lanpr_share.render_buffer_shared);
|
||||
}
|
||||
else {
|
||||
for (ll = lanpr->line_layers.first; ll; ll = ll->next) {
|
||||
if (ll->batch) {
|
||||
GPU_batch_discard(ll->batch);
|
||||
}
|
||||
lanpr_rebuild_render_draw_command(lanpr_share.render_buffer_shared, ll);
|
||||
}
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&lanpr_share.render_buffer_shared->scene->id, ID_RECALC_COPY_ON_WRITE);
|
||||
}
|
||||
|
||||
void ED_lanpr_calculate_normal_object_vector(LANPR_LineLayer *ll, float *normal_object_direction)
|
||||
{
|
||||
Object *ob;
|
||||
if (!(ll->flags & LANPR_LINE_LAYER_NORMAL_ENABLED)) {
|
||||
return;
|
||||
}
|
||||
switch (ll->normal_mode) {
|
||||
case LANPR_NORMAL_DIRECTIONAL:
|
||||
if (!(ob = ll->normal_control_object)) {
|
||||
normal_object_direction[0] = 0;
|
||||
normal_object_direction[1] = 0;
|
||||
normal_object_direction[2] = 1; /* default z up direction */
|
||||
}
|
||||
else {
|
||||
float dir[3] = {0, 0, 1};
|
||||
float mat[3][3];
|
||||
copy_m3_m4(mat, ob->obmat);
|
||||
mul_v3_m3v3(normal_object_direction, mat, dir);
|
||||
normalize_v3(normal_object_direction);
|
||||
}
|
||||
return;
|
||||
case LANPR_NORMAL_POINT:
|
||||
if (!(ob = ll->normal_control_object)) {
|
||||
normal_object_direction[0] = 0;
|
||||
normal_object_direction[1] = 0;
|
||||
normal_object_direction[2] = 0; /* default origin position */
|
||||
}
|
||||
else {
|
||||
normal_object_direction[0] = ob->obmat[3][0];
|
||||
normal_object_direction[1] = ob->obmat[3][1];
|
||||
normal_object_direction[2] = ob->obmat[3][2];
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void lanpr_software_draw_scene(void *vedata, GPUFrameBuffer *dfb, int is_render)
|
||||
{
|
||||
LANPR_LineLayer *ll;
|
||||
LANPR_PassList *psl = ((LANPR_Data *)vedata)->psl;
|
||||
LANPR_TextureList *txl = ((LANPR_Data *)vedata)->txl;
|
||||
LANPR_StorageList *stl = ((LANPR_Data *)vedata)->stl;
|
||||
LANPR_FramebufferList *fbl = ((LANPR_Data *)vedata)->fbl;
|
||||
LANPR_PrivateData *pd = stl->g_data;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Scene *scene = DEG_get_evaluated_scene(draw_ctx->depsgraph);
|
||||
SceneLANPR *lanpr = &scene->lanpr;
|
||||
View3D *v3d = draw_ctx->v3d;
|
||||
float indentity_mat[4][4];
|
||||
static float normal_object_direction[3] = {0, 0, 1};
|
||||
float use_background_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
static float camdx, camdy, camzoom;
|
||||
|
||||
if (is_render) {
|
||||
ED_lanpr_rebuild_all_command(lanpr);
|
||||
}
|
||||
|
||||
float clear_depth = 1.0f;
|
||||
uint clear_stencil = 0xFF;
|
||||
eGPUFrameBufferBits clear_bits = GPU_DEPTH_BIT | GPU_COLOR_BIT;
|
||||
static int zero_value = 0;
|
||||
|
||||
copy_v3_v3(use_background_color, &scene->world->horr);
|
||||
use_background_color[3] = scene->r.alphamode ? 0.0f : 1.0f;
|
||||
|
||||
GPU_framebuffer_bind(fbl->software_ms);
|
||||
GPU_framebuffer_clear(
|
||||
fbl->software_ms, clear_bits, use_background_color, clear_depth, clear_stencil);
|
||||
|
||||
if (lanpr_share.render_buffer_shared) {
|
||||
|
||||
int texw = GPU_texture_width(txl->ms_resolve_color),
|
||||
texh = GPU_texture_height(txl->ms_resolve_color);
|
||||
;
|
||||
pd->output_viewport[2] = scene->r.xsch;
|
||||
pd->output_viewport[3] = scene->r.ysch;
|
||||
pd->dpix_viewport[2] = texw;
|
||||
pd->dpix_viewport[3] = texh;
|
||||
|
||||
unit_m4(indentity_mat);
|
||||
|
||||
DRWView *view = DRW_view_create(indentity_mat, indentity_mat, NULL, NULL, NULL);
|
||||
if (is_render) {
|
||||
DRW_view_default_set(view);
|
||||
}
|
||||
else {
|
||||
DRW_view_set_active(view);
|
||||
}
|
||||
|
||||
RegionView3D *rv3d = v3d ? draw_ctx->rv3d : NULL;
|
||||
if (rv3d) {
|
||||
camdx = rv3d->camdx;
|
||||
camdy = rv3d->camdy;
|
||||
camzoom = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
|
||||
}
|
||||
else {
|
||||
camdx = camdy = 0.0f;
|
||||
camzoom = 1.0f;
|
||||
}
|
||||
|
||||
if ((lanpr->flags & LANPR_USE_CHAINING) &&
|
||||
lanpr_share.render_buffer_shared->chain_draw_batch) {
|
||||
for (ll = lanpr->line_layers.last; ll; ll = ll->prev) {
|
||||
LANPR_RenderBuffer *rb;
|
||||
psl->software_pass = DRW_pass_create("Software Render Preview",
|
||||
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
|
||||
DRW_STATE_DEPTH_LESS_EQUAL);
|
||||
rb = lanpr_share.render_buffer_shared;
|
||||
rb->ChainShgrp = DRW_shgroup_create(lanpr_share.software_chaining_shader,
|
||||
psl->software_pass);
|
||||
|
||||
ED_lanpr_calculate_normal_object_vector(ll, normal_object_direction);
|
||||
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp, "camdx", &camdx, 1);
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp, "camdy", &camdy, 1);
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp, "camzoom", &camzoom, 1);
|
||||
|
||||
DRW_shgroup_uniform_vec4(rb->ChainShgrp,
|
||||
"contour_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color :
|
||||
ll->contour.color,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(rb->ChainShgrp,
|
||||
"crease_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color :
|
||||
ll->crease.color,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(rb->ChainShgrp,
|
||||
"material_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
ll->color :
|
||||
ll->material_separate.color,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(
|
||||
rb->ChainShgrp,
|
||||
"edge_mark_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color : ll->edge_mark.color,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(
|
||||
rb->ChainShgrp,
|
||||
"intersection_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color : ll->intersection.color,
|
||||
1);
|
||||
static float unit_thickness = 1.0f;
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp, "thickness", &ll->thickness, 1);
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp,
|
||||
"thickness_contour",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
&unit_thickness :
|
||||
&ll->contour.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp,
|
||||
"thickness_crease",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
&unit_thickness :
|
||||
&ll->crease.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp,
|
||||
"thickness_material",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
&unit_thickness :
|
||||
&ll->material_separate.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp,
|
||||
"thickness_edge_mark",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
&unit_thickness :
|
||||
&ll->edge_mark.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp,
|
||||
"thickness_intersection",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
&unit_thickness :
|
||||
&ll->intersection.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_int(rb->ChainShgrp, "use_contour", &ll->contour.use, 1);
|
||||
DRW_shgroup_uniform_int(rb->ChainShgrp, "use_crease", &ll->crease.use, 1);
|
||||
DRW_shgroup_uniform_int(rb->ChainShgrp, "use_material", &ll->material_separate.use, 1);
|
||||
DRW_shgroup_uniform_int(rb->ChainShgrp, "use_edge_mark", &ll->edge_mark.use, 1);
|
||||
DRW_shgroup_uniform_int(rb->ChainShgrp, "use_intersection", &ll->intersection.use, 1);
|
||||
|
||||
static int normal_effect_inverse;
|
||||
normal_effect_inverse = (ll->flags & LANPR_LINE_LAYER_NORMAL_INVERSE) ? 1 : 0;
|
||||
DRW_shgroup_uniform_int(rb->ChainShgrp,
|
||||
"normal_mode",
|
||||
(ll->flags & LANPR_LINE_LAYER_NORMAL_ENABLED) ? &ll->normal_mode :
|
||||
&zero_value,
|
||||
1);
|
||||
DRW_shgroup_uniform_int(
|
||||
rb->ChainShgrp, "normal_effect_inverse", &normal_effect_inverse, 1);
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp, "normal_ramp_begin", &ll->normal_ramp_begin, 1);
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp, "normal_ramp_end", &ll->normal_ramp_end, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
rb->ChainShgrp, "normal_thickness_start", &ll->normal_thickness_start, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
rb->ChainShgrp, "normal_thickness_end", &ll->normal_thickness_end, 1);
|
||||
DRW_shgroup_uniform_vec3(rb->ChainShgrp, "normal_direction", normal_object_direction, 1);
|
||||
|
||||
DRW_shgroup_uniform_int(rb->ChainShgrp, "occlusion_level_start", &ll->level_start, 1);
|
||||
DRW_shgroup_uniform_int(
|
||||
rb->ChainShgrp,
|
||||
"occlusion_level_end",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_MULTIPLE_LEVELS) ? &ll->level_end : &ll->level_start,
|
||||
1);
|
||||
|
||||
DRW_shgroup_uniform_vec4(
|
||||
rb->ChainShgrp, "preview_viewport", stl->g_data->dpix_viewport, 1);
|
||||
DRW_shgroup_uniform_vec4(
|
||||
rb->ChainShgrp, "output_viewport", stl->g_data->output_viewport, 1);
|
||||
|
||||
float *tld = &lanpr->taper_left_distance, *tls = &lanpr->taper_left_strength,
|
||||
*trd = &lanpr->taper_right_distance, *trs = &lanpr->taper_right_strength;
|
||||
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp, "taper_l_dist", tld, 1);
|
||||
DRW_shgroup_uniform_float(rb->ChainShgrp, "taper_l_strength", tls, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
rb->ChainShgrp, "taper_r_dist", (lanpr->flags & LANPR_SAME_TAPER) ? tld : trd, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
rb->ChainShgrp, "taper_r_strength", (lanpr->flags & LANPR_SAME_TAPER) ? tls : trs, 1);
|
||||
|
||||
/* need to add component enable/disable option. */
|
||||
DRW_shgroup_call(rb->ChainShgrp, lanpr_share.render_buffer_shared->chain_draw_batch, NULL);
|
||||
/* debug purpose */
|
||||
/* DRW_draw_pass(psl->color_pass); */
|
||||
/* DRW_draw_pass(psl->color_pass); */
|
||||
DRW_draw_pass(psl->software_pass);
|
||||
}
|
||||
}
|
||||
else if (!(lanpr->flags & LANPR_USE_CHAINING)) {
|
||||
for (ll = lanpr->line_layers.last; ll; ll = ll->prev) {
|
||||
if (ll->batch) {
|
||||
psl->software_pass = DRW_pass_create("Software Render Preview",
|
||||
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
|
||||
DRW_STATE_DEPTH_LESS_EQUAL);
|
||||
ll->shgrp = DRW_shgroup_create(lanpr_share.software_shader, psl->software_pass);
|
||||
|
||||
ED_lanpr_calculate_normal_object_vector(ll, normal_object_direction);
|
||||
|
||||
DRW_shgroup_uniform_float(ll->shgrp, "camdx", &camdx, 1);
|
||||
DRW_shgroup_uniform_float(ll->shgrp, "camdy", &camdy, 1);
|
||||
DRW_shgroup_uniform_float(ll->shgrp, "camzoom", &camzoom, 1);
|
||||
|
||||
DRW_shgroup_uniform_vec4(
|
||||
ll->shgrp,
|
||||
"contour_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color : ll->contour.color,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(
|
||||
ll->shgrp,
|
||||
"crease_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color : ll->crease.color,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(ll->shgrp,
|
||||
"material_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
ll->color :
|
||||
ll->material_separate.color,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(
|
||||
ll->shgrp,
|
||||
"edge_mark_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color : ll->edge_mark.color,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(
|
||||
ll->shgrp,
|
||||
"intersection_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color : ll->intersection.color,
|
||||
1);
|
||||
static float uniform_thickness = 1.0f;
|
||||
DRW_shgroup_uniform_float(ll->shgrp, "thickness", &ll->thickness, 1);
|
||||
DRW_shgroup_uniform_float(ll->shgrp,
|
||||
"thickness_contour",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
&uniform_thickness :
|
||||
&ll->contour.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(ll->shgrp,
|
||||
"thickness_crease",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
&uniform_thickness :
|
||||
&ll->crease.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(ll->shgrp,
|
||||
"thickness_material",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
&uniform_thickness :
|
||||
&ll->material_separate.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(ll->shgrp,
|
||||
"thickness_edge_mark",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
&uniform_thickness :
|
||||
&ll->edge_mark.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(ll->shgrp,
|
||||
"thickness_intersection",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
&uniform_thickness :
|
||||
&ll->intersection.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(ll->shgrp, "preview_viewport", stl->g_data->dpix_viewport, 1);
|
||||
DRW_shgroup_uniform_vec4(ll->shgrp, "output_viewport", stl->g_data->output_viewport, 1);
|
||||
|
||||
static int normal_effect_inverse;
|
||||
normal_effect_inverse = (ll->flags & LANPR_LINE_LAYER_NORMAL_INVERSE) ? 1 : 0;
|
||||
DRW_shgroup_uniform_int(
|
||||
ll->shgrp,
|
||||
"normal_mode",
|
||||
(ll->flags & LANPR_LINE_LAYER_NORMAL_ENABLED) ? &ll->normal_mode : &zero_value,
|
||||
1);
|
||||
DRW_shgroup_uniform_int(ll->shgrp, "normal_effect_inverse", &normal_effect_inverse, 1);
|
||||
DRW_shgroup_uniform_float(ll->shgrp, "normal_ramp_begin", &ll->normal_ramp_begin, 1);
|
||||
DRW_shgroup_uniform_float(ll->shgrp, "normal_ramp_end", &ll->normal_ramp_end, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
ll->shgrp, "normal_thickness_start", &ll->normal_thickness_start, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
ll->shgrp, "normal_thickness_end", &ll->normal_thickness_end, 1);
|
||||
DRW_shgroup_uniform_vec3(ll->shgrp, "normal_direction", normal_object_direction, 1);
|
||||
|
||||
DRW_shgroup_call(ll->shgrp, ll->batch, NULL);
|
||||
DRW_draw_pass(psl->software_pass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GPU_framebuffer_blit(fbl->software_ms, 0, dfb, 0, GPU_COLOR_BIT);
|
||||
|
||||
if (!is_render) {
|
||||
DRW_view_set_active(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void ED_lanpr_update_render_progress(const char *text)
|
||||
{
|
||||
if (lanpr_share.re_render) {
|
||||
RE_engine_update_stats(lanpr_share.re_render, NULL, text);
|
||||
}
|
||||
}
|
553
source/blender/draw/engines/lanpr/lanpr_dpix.c
Normal file
553
source/blender/draw/engines/lanpr/lanpr_dpix.c
Normal file
@@ -0,0 +1,553 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_lanpr_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
#include "DRW_engine.h"
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_immediate_util.h"
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_uniformbuffer.h"
|
||||
#include "GPU_viewport.h"
|
||||
|
||||
#include "lanpr_all.h"
|
||||
#include "bmesh.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
extern LANPR_SharedResource lanpr_share;
|
||||
extern char datatoc_lanpr_dpix_project_passthrough_vert_glsl[];
|
||||
extern char datatoc_lanpr_dpix_project_clip_frag_glsl[];
|
||||
extern char datatoc_lanpr_dpix_preview_geom_glsl[];
|
||||
extern char datatoc_lanpr_dpix_preview_frag_glsl[];
|
||||
|
||||
int lanpr_dpix_texture_size(SceneLANPR *lanpr)
|
||||
{
|
||||
switch (lanpr->gpu_cache_size) {
|
||||
case LANPR_GPU_CACHE_SIZE_512:
|
||||
return 512;
|
||||
case LANPR_GPU_CACHE_SIZE_1K:
|
||||
return 1024;
|
||||
case LANPR_GPU_CACHE_SIZE_2K:
|
||||
return 2048;
|
||||
case LANPR_GPU_CACHE_SIZE_4K:
|
||||
return 4096;
|
||||
}
|
||||
return 512;
|
||||
}
|
||||
|
||||
void lanpr_init_atlas_inputs(void *ved)
|
||||
{
|
||||
lanpr_share.ved_viewport = ved;
|
||||
LANPR_Data *vedata = (LANPR_Data *)ved;
|
||||
LANPR_TextureList *txl = vedata->txl;
|
||||
LANPR_FramebufferList *fbl = vedata->fbl;
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
SceneLANPR *lanpr = &draw_ctx->scene->lanpr;
|
||||
|
||||
int texture_size = lanpr_dpix_texture_size(lanpr);
|
||||
lanpr_share.texture_size = texture_size;
|
||||
|
||||
if (txl->dpix_in_pl && GPU_texture_width(txl->dpix_in_pl) != texture_size) {
|
||||
DRW_texture_free(txl->dpix_in_pl);
|
||||
txl->dpix_in_pl = NULL;
|
||||
DRW_texture_free(txl->dpix_in_pr);
|
||||
txl->dpix_in_pr = NULL;
|
||||
DRW_texture_free(txl->dpix_in_nl);
|
||||
txl->dpix_in_nl = NULL;
|
||||
DRW_texture_free(txl->dpix_in_nr);
|
||||
txl->dpix_in_nr = NULL;
|
||||
DRW_texture_free(txl->dpix_out_pl);
|
||||
txl->dpix_out_pl = NULL;
|
||||
DRW_texture_free(txl->dpix_out_pr);
|
||||
txl->dpix_out_pr = NULL;
|
||||
DRW_texture_free(txl->dpix_out_length);
|
||||
txl->dpix_out_length = NULL;
|
||||
}
|
||||
|
||||
if (lanpr_share.dpix_reloaded || !txl->dpix_in_pl) {
|
||||
DRW_texture_ensure_2d(&txl->dpix_in_pl, texture_size, texture_size, GPU_RGBA32F, 0);
|
||||
DRW_texture_ensure_2d(&txl->dpix_in_pr, texture_size, texture_size, GPU_RGBA32F, 0);
|
||||
DRW_texture_ensure_2d(&txl->dpix_in_nl, texture_size, texture_size, GPU_RGBA32F, 0);
|
||||
DRW_texture_ensure_2d(&txl->dpix_in_nr, texture_size, texture_size, GPU_RGBA32F, 0);
|
||||
DRW_texture_ensure_2d(&txl->dpix_in_edge_mask, texture_size, texture_size, GPU_RGBA8, 0);
|
||||
DRW_texture_ensure_2d(&txl->dpix_out_pl, texture_size, texture_size, GPU_RGBA32F, 0);
|
||||
DRW_texture_ensure_2d(&txl->dpix_out_pr, texture_size, texture_size, GPU_RGBA32F, 0);
|
||||
DRW_texture_ensure_2d(&txl->dpix_out_length, texture_size, texture_size, GPU_RGBA32F, 0);
|
||||
}
|
||||
|
||||
GPU_framebuffer_ensure_config(&fbl->dpix_transform,
|
||||
{GPU_ATTACHMENT_LEAVE,
|
||||
GPU_ATTACHMENT_TEXTURE(txl->dpix_out_pl),
|
||||
GPU_ATTACHMENT_TEXTURE(txl->dpix_out_pr),
|
||||
GPU_ATTACHMENT_TEXTURE(txl->dpix_out_length),
|
||||
GPU_ATTACHMENT_LEAVE,
|
||||
GPU_ATTACHMENT_LEAVE,
|
||||
GPU_ATTACHMENT_LEAVE});
|
||||
|
||||
GPU_framebuffer_ensure_config(&fbl->dpix_preview,
|
||||
{GPU_ATTACHMENT_TEXTURE(txl->depth),
|
||||
GPU_ATTACHMENT_TEXTURE(txl->color),
|
||||
GPU_ATTACHMENT_LEAVE,
|
||||
GPU_ATTACHMENT_LEAVE,
|
||||
GPU_ATTACHMENT_LEAVE,
|
||||
GPU_ATTACHMENT_LEAVE,
|
||||
GPU_ATTACHMENT_LEAVE});
|
||||
|
||||
if (!lanpr_share.dpix_transform_shader) {
|
||||
lanpr_share.dpix_transform_shader = DRW_shader_create(
|
||||
datatoc_lanpr_dpix_project_passthrough_vert_glsl,
|
||||
NULL,
|
||||
datatoc_lanpr_dpix_project_clip_frag_glsl,
|
||||
NULL);
|
||||
if (!lanpr_share.dpix_transform_shader) {
|
||||
lanpr_share.dpix_shader_error = 1;
|
||||
printf("LANPR: DPIX transform shader compile error.");
|
||||
}
|
||||
}
|
||||
if (!lanpr_share.dpix_preview_shader) {
|
||||
lanpr_share.dpix_preview_shader = DRW_shader_create(
|
||||
datatoc_lanpr_dpix_project_passthrough_vert_glsl,
|
||||
datatoc_lanpr_dpix_preview_geom_glsl,
|
||||
datatoc_lanpr_dpix_preview_frag_glsl,
|
||||
NULL);
|
||||
if (!lanpr_share.dpix_transform_shader) {
|
||||
lanpr_share.dpix_shader_error = 1;
|
||||
printf("LANPR: DPIX transform shader compile error.");
|
||||
}
|
||||
}
|
||||
}
|
||||
void lanpr_destroy_atlas(void *UNUSED(ved))
|
||||
{
|
||||
/* no need to free things, no custom data. */
|
||||
}
|
||||
|
||||
int lanpr_feed_atlas_data_obj(void *UNUSED(vedata),
|
||||
float *AtlasPointsL,
|
||||
float *AtlasPointsR,
|
||||
float *AtlasFaceNormalL,
|
||||
float *AtlasFaceNormalR,
|
||||
float *AtlasEdgeMask,
|
||||
Object *ob,
|
||||
int begin_index)
|
||||
{
|
||||
if (!DRW_object_is_renderable(ob)) {
|
||||
return begin_index;
|
||||
}
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
if (ob == draw_ctx->object_edit) {
|
||||
return begin_index;
|
||||
}
|
||||
if (ob->type != OB_MESH) {
|
||||
return begin_index;
|
||||
}
|
||||
|
||||
Mesh *me = ob->data;
|
||||
BMesh *bm;
|
||||
struct BMFace *f1, *f2;
|
||||
struct BMVert *v1, *v2;
|
||||
struct BMEdge *e;
|
||||
struct BMLoop *l1, *l2;
|
||||
FreestyleEdge *fe;
|
||||
int CanFindFreestyle = 0;
|
||||
int edge_count = me->totedge;
|
||||
int i, idx;
|
||||
|
||||
int cache_total = lanpr_share.texture_size * lanpr_share.texture_size;
|
||||
|
||||
/* Don't overflow the cache. */
|
||||
if ((edge_count + begin_index) > (cache_total - 1)) {
|
||||
return begin_index;
|
||||
}
|
||||
|
||||
const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me);
|
||||
bm = BM_mesh_create(&allocsize,
|
||||
&((struct BMeshCreateParams){
|
||||
.use_toolflags = true,
|
||||
}));
|
||||
BM_mesh_bm_from_me(bm,
|
||||
me,
|
||||
&((struct BMeshFromMeshParams){
|
||||
.calc_face_normal = true,
|
||||
}));
|
||||
BM_mesh_elem_table_ensure(bm, BM_VERT | BM_EDGE | BM_FACE);
|
||||
|
||||
if (CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) {
|
||||
CanFindFreestyle = 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < edge_count; i++) {
|
||||
f1 = 0;
|
||||
f2 = 0;
|
||||
e = BM_edge_at_index(bm, i);
|
||||
v1 = e->v1;
|
||||
v2 = e->v2;
|
||||
l1 = e->l;
|
||||
l2 = e->l ? e->l->radial_next : 0;
|
||||
if (l1) {
|
||||
f1 = l1->f;
|
||||
}
|
||||
if (l2) {
|
||||
f2 = l2->f;
|
||||
}
|
||||
|
||||
idx = (begin_index + i) * 4;
|
||||
|
||||
AtlasPointsL[idx + 0] = v1->co[0];
|
||||
AtlasPointsL[idx + 1] = v1->co[1];
|
||||
AtlasPointsL[idx + 2] = v1->co[2];
|
||||
AtlasPointsL[idx + 3] = 1;
|
||||
|
||||
AtlasPointsR[idx + 0] = v2->co[0];
|
||||
AtlasPointsR[idx + 1] = v2->co[1];
|
||||
AtlasPointsR[idx + 2] = v2->co[2];
|
||||
AtlasPointsR[idx + 3] = 1;
|
||||
|
||||
if (CanFindFreestyle) {
|
||||
fe = CustomData_bmesh_get(&bm->edata, e->head.data, FREESTYLE_EDGE_MARK);
|
||||
if (fe->flag & FREESTYLE_EDGE_MARK) {
|
||||
AtlasEdgeMask[idx + 1] = 1; /* channel G */
|
||||
}
|
||||
}
|
||||
|
||||
if (f1) {
|
||||
AtlasFaceNormalL[idx + 0] = f1->no[0];
|
||||
AtlasFaceNormalL[idx + 1] = f1->no[1];
|
||||
AtlasFaceNormalL[idx + 2] = f1->no[2];
|
||||
AtlasFaceNormalL[idx + 3] = 1;
|
||||
}
|
||||
else {
|
||||
AtlasFaceNormalL[idx + 0] = 0;
|
||||
AtlasFaceNormalL[idx + 1] = 0;
|
||||
AtlasFaceNormalL[idx + 2] = 0;
|
||||
AtlasFaceNormalL[idx + 3] = 0;
|
||||
}
|
||||
|
||||
if (f2 && f2 != f1) { /* this is for edge condition */
|
||||
AtlasFaceNormalR[idx + 0] = f2->no[0];
|
||||
AtlasFaceNormalR[idx + 1] = f2->no[1];
|
||||
AtlasFaceNormalR[idx + 2] = f2->no[2];
|
||||
AtlasFaceNormalR[idx + 3] = 1;
|
||||
|
||||
if (f2->mat_nr != f1->mat_nr) {
|
||||
AtlasEdgeMask[idx] = 1; /* channel r */
|
||||
}
|
||||
}
|
||||
else {
|
||||
AtlasFaceNormalR[idx + 0] = 0;
|
||||
AtlasFaceNormalR[idx + 1] = 0;
|
||||
AtlasFaceNormalR[idx + 2] = 0;
|
||||
AtlasFaceNormalR[idx + 3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
BM_mesh_free(bm);
|
||||
|
||||
return begin_index + edge_count;
|
||||
}
|
||||
|
||||
int lanpr_feed_atlas_data_intersection_cache(void *UNUSED(vedata),
|
||||
float *AtlasPointsL,
|
||||
float *AtlasPointsR,
|
||||
float *AtlasFaceNormalL,
|
||||
float *AtlasFaceNormalR,
|
||||
float *AtlasEdgeMask,
|
||||
int begin_index)
|
||||
{
|
||||
LANPR_RenderBuffer *rb = lanpr_share.render_buffer_shared;
|
||||
LinkData *lip;
|
||||
LANPR_RenderLine *rl;
|
||||
int i, idx;
|
||||
|
||||
i = 0;
|
||||
|
||||
if (!rb) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cache_total = lanpr_share.texture_size * lanpr_share.texture_size;
|
||||
|
||||
/* Don't overflow the cache. */
|
||||
if ((rb->intersection_count + begin_index) > (cache_total - 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (lip = rb->intersection_lines.first; lip; lip = lip->next) {
|
||||
rl = lip->data;
|
||||
|
||||
idx = (begin_index + i) * 4;
|
||||
AtlasEdgeMask[idx + 2] = 1; /* channel B */
|
||||
|
||||
AtlasPointsL[idx + 0] = rl->l->gloc[0];
|
||||
AtlasPointsL[idx + 1] = rl->l->gloc[1];
|
||||
AtlasPointsL[idx + 2] = rl->l->gloc[2];
|
||||
AtlasPointsL[idx + 3] = 1;
|
||||
|
||||
AtlasPointsR[idx + 0] = rl->r->gloc[0];
|
||||
AtlasPointsR[idx + 1] = rl->r->gloc[1];
|
||||
AtlasPointsR[idx + 2] = rl->r->gloc[2];
|
||||
AtlasPointsR[idx + 3] = 1;
|
||||
|
||||
AtlasFaceNormalL[idx + 0] = 0;
|
||||
AtlasFaceNormalL[idx + 1] = 0;
|
||||
AtlasFaceNormalL[idx + 2] = 1;
|
||||
AtlasFaceNormalL[idx + 3] = 0;
|
||||
|
||||
AtlasFaceNormalR[idx + 0] = 0;
|
||||
AtlasFaceNormalR[idx + 1] = 0;
|
||||
AtlasFaceNormalR[idx + 2] = 1;
|
||||
AtlasFaceNormalR[idx + 3] = 0;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return begin_index + i;
|
||||
}
|
||||
|
||||
static void lanpr_dpix_index_to_coord(int index, float *x, float *y)
|
||||
{
|
||||
int texture_size = lanpr_share.texture_size;
|
||||
(*x) = interpf(1, -1, (float)(index % texture_size + 0.5) / (float)texture_size);
|
||||
(*y) = interpf(1, -1, (float)(index / texture_size + 0.5) / (float)texture_size);
|
||||
}
|
||||
|
||||
static void lanpr_dpix_index_to_coord_absolute(int index, float *x, float *y)
|
||||
{
|
||||
int texture_size = lanpr_share.texture_size;
|
||||
(*x) = (float)(index % texture_size) + 0.5;
|
||||
(*y) = (float)(index / texture_size) + 0.5;
|
||||
}
|
||||
|
||||
int lanpr_feed_atlas_trigger_preview_obj(void *UNUSED(vedata), Object *ob, int begin_index)
|
||||
{
|
||||
Mesh *me = ob->data;
|
||||
if (ob->type != OB_MESH) {
|
||||
return begin_index;
|
||||
}
|
||||
int edge_count = me->totedge;
|
||||
int i;
|
||||
float co[2];
|
||||
|
||||
int cache_total = lanpr_share.texture_size * lanpr_share.texture_size;
|
||||
|
||||
/* Don't overflow the cache. */
|
||||
if ((edge_count + begin_index) > (cache_total - 1)) {
|
||||
return begin_index;
|
||||
}
|
||||
|
||||
static GPUVertFormat format = {0};
|
||||
static struct {
|
||||
uint pos, uvs;
|
||||
} attr_id;
|
||||
if (format.attr_len == 0) {
|
||||
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
}
|
||||
|
||||
static GPUVertFormat format2 = {0};
|
||||
static struct {
|
||||
uint pos, uvs;
|
||||
} attr_id2;
|
||||
if (format2.attr_len == 0) {
|
||||
attr_id2.pos = GPU_vertformat_attr_add(&format2, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
}
|
||||
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPUVertBuf *vbo2 = GPU_vertbuf_create_with_format(&format2);
|
||||
GPU_vertbuf_data_alloc(vbo, edge_count);
|
||||
GPU_vertbuf_data_alloc(vbo2, edge_count);
|
||||
|
||||
for (i = 0; i < edge_count; i++) {
|
||||
lanpr_dpix_index_to_coord(i + begin_index, &co[0], &co[1]);
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.pos, i, co);
|
||||
lanpr_dpix_index_to_coord_absolute(i + begin_index, &co[0], &co[1]);
|
||||
GPU_vertbuf_attr_set(vbo2, attr_id2.pos, i, co);
|
||||
}
|
||||
|
||||
GPUBatch *gb = GPU_batch_create_ex(
|
||||
GPU_PRIM_POINTS, vbo, 0, GPU_USAGE_DYNAMIC | GPU_BATCH_OWNS_VBO);
|
||||
GPUBatch *gb2 = GPU_batch_create_ex(
|
||||
GPU_PRIM_POINTS, vbo2, 0, GPU_USAGE_DYNAMIC | GPU_BATCH_OWNS_VBO);
|
||||
|
||||
LANPR_BatchItem *bi = BLI_mempool_alloc(lanpr_share.mp_batch_list);
|
||||
BLI_addtail(&lanpr_share.dpix_batch_list, bi);
|
||||
bi->dpix_transform_batch = gb;
|
||||
bi->dpix_preview_batch = gb2;
|
||||
bi->ob = ob;
|
||||
|
||||
return begin_index + edge_count;
|
||||
}
|
||||
|
||||
void lanpr_create_atlas_intersection_preview(void *UNUSED(vedata), int begin_index)
|
||||
{
|
||||
LANPR_RenderBuffer *rb = lanpr_share.render_buffer_shared;
|
||||
float co[2];
|
||||
int i;
|
||||
|
||||
if (!rb) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rb->DPIXIntersectionBatch) {
|
||||
GPU_BATCH_DISCARD_SAFE(rb->DPIXIntersectionBatch);
|
||||
}
|
||||
rb->DPIXIntersectionBatch = 0;
|
||||
|
||||
if (!rb->intersection_count) {
|
||||
return;
|
||||
}
|
||||
|
||||
int cache_total = lanpr_share.texture_size * lanpr_share.texture_size;
|
||||
|
||||
/* Don't overflow the cache. */
|
||||
if ((rb->intersection_count + begin_index) > (cache_total - 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
static GPUVertFormat format = {0};
|
||||
static struct {
|
||||
uint pos, uvs;
|
||||
} attr_id;
|
||||
if (format.attr_len == 0) {
|
||||
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
}
|
||||
static GPUVertFormat format2 = {0};
|
||||
static struct {
|
||||
uint pos, uvs;
|
||||
} attr_id2;
|
||||
if (format2.attr_len == 0) {
|
||||
attr_id2.pos = GPU_vertformat_attr_add(&format2, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
}
|
||||
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(vbo, rb->intersection_count);
|
||||
|
||||
GPUVertBuf *vbo2 = GPU_vertbuf_create_with_format(&format2);
|
||||
GPU_vertbuf_data_alloc(vbo2, rb->intersection_count);
|
||||
|
||||
for (i = 0; i < rb->intersection_count; i++) {
|
||||
lanpr_dpix_index_to_coord(i + begin_index, &co[0], &co[1]);
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.pos, i, co);
|
||||
lanpr_dpix_index_to_coord_absolute(i + begin_index, &co[0], &co[1]);
|
||||
GPU_vertbuf_attr_set(vbo2, attr_id2.pos, i, co);
|
||||
}
|
||||
rb->DPIXIntersectionTransformBatch = GPU_batch_create_ex(
|
||||
GPU_PRIM_POINTS, vbo, 0, GPU_USAGE_DYNAMIC | GPU_BATCH_OWNS_VBO);
|
||||
rb->DPIXIntersectionBatch = GPU_batch_create_ex(
|
||||
GPU_PRIM_POINTS, vbo2, 0, GPU_USAGE_DYNAMIC | GPU_BATCH_OWNS_VBO);
|
||||
}
|
||||
|
||||
void lanpr_dpix_draw_scene(LANPR_TextureList *txl,
|
||||
LANPR_FramebufferList *fbl,
|
||||
LANPR_PassList *psl,
|
||||
LANPR_PrivateData *pd,
|
||||
SceneLANPR *lanpr,
|
||||
GPUFrameBuffer *DefaultFB,
|
||||
int is_render)
|
||||
{
|
||||
float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
float clear_depth = 1.0f;
|
||||
uint clear_stencil = 0xFF;
|
||||
int is_persp = 1;
|
||||
float use_background_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
;
|
||||
|
||||
if (!lanpr->active_layer) {
|
||||
return; /* return early in case we don't have line layers. DPIX only use the first layer. */
|
||||
}
|
||||
int texw = GPU_texture_width(txl->edge_intermediate),
|
||||
texh = GPU_texture_height(txl->edge_intermediate);
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Scene *scene = DEG_get_evaluated_scene(draw_ctx->depsgraph);
|
||||
View3D *v3d = draw_ctx->v3d;
|
||||
Object *camera = 0;
|
||||
if (v3d) {
|
||||
RegionView3D *rv3d = draw_ctx->rv3d;
|
||||
camera = (rv3d && rv3d->persp == RV3D_CAMOB) ? v3d->camera : NULL;
|
||||
is_persp = rv3d->is_persp;
|
||||
}
|
||||
if (!camera) {
|
||||
camera = scene->camera;
|
||||
if (!v3d) {
|
||||
is_persp = ((Camera *)camera->data)->type == CAM_PERSP ? 1 : 0;
|
||||
}
|
||||
}
|
||||
if (is_render && !camera) {
|
||||
return;
|
||||
}
|
||||
/* XXX: should implement view angle functions for ortho camera. */
|
||||
|
||||
int texture_size = lanpr_share.texture_size;
|
||||
|
||||
pd->dpix_viewport[2] = texw;
|
||||
pd->dpix_viewport[3] = texh;
|
||||
pd->dpix_is_perspective = is_persp;
|
||||
pd->dpix_sample_step = 1;
|
||||
pd->dpix_buffer_width = texture_size;
|
||||
pd->dpix_depth_offset = 0.0001;
|
||||
pd->dpix_znear = camera ? ((Camera *)camera->data)->clip_start : v3d->clip_start;
|
||||
pd->dpix_zfar = camera ? ((Camera *)camera->data)->clip_end : v3d->clip_end;
|
||||
|
||||
copy_v3_v3(use_background_color, &scene->world->horr);
|
||||
use_background_color[3] = scene->r.alphamode ? 0.0f : 1.0f;
|
||||
|
||||
GPU_point_size(1);
|
||||
/* GPU_line_width(2); */
|
||||
GPU_framebuffer_bind(fbl->dpix_transform);
|
||||
DRW_draw_pass(psl->dpix_transform_pass);
|
||||
|
||||
GPU_framebuffer_bind(fbl->dpix_preview);
|
||||
eGPUFrameBufferBits clear_bits = GPU_COLOR_BIT;
|
||||
GPU_framebuffer_clear(fbl->dpix_preview, clear_bits, clear_col, clear_depth, clear_stencil);
|
||||
DRW_draw_pass(psl->dpix_preview_pass);
|
||||
|
||||
if (is_render) {
|
||||
mul_v3_v3fl(clear_col, use_background_color, use_background_color[3]);
|
||||
clear_col[3] = use_background_color[3];
|
||||
}
|
||||
else {
|
||||
copy_v4_v4(clear_col, use_background_color);
|
||||
}
|
||||
|
||||
GPU_framebuffer_bind(DefaultFB);
|
||||
GPU_framebuffer_clear(DefaultFB, clear_bits, clear_col, clear_depth, clear_stencil);
|
||||
DRW_multisamples_resolve(txl->depth, txl->color, 0);
|
||||
}
|
815
source/blender/draw/engines/lanpr/lanpr_engine.c
Normal file
815
source/blender/draw/engines/lanpr/lanpr_engine.c
Normal file
@@ -0,0 +1,815 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_rect.h"
|
||||
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_lanpr_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
|
||||
#include "DRW_engine.h"
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_immediate_util.h"
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_uniformbuffer.h"
|
||||
#include "GPU_viewport.h"
|
||||
|
||||
#include "RE_pipeline.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "lanpr_all.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
extern char datatoc_common_fullscreen_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_3D_smooth_color_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
|
||||
extern char datatoc_lanpr_snake_multichannel_frag_glsl[];
|
||||
extern char datatoc_lanpr_snake_edge_frag_glsl[];
|
||||
extern char datatoc_lanpr_snake_image_peel_frag_glsl[];
|
||||
extern char datatoc_lanpr_snake_line_connection_vert_glsl[];
|
||||
extern char datatoc_lanpr_snake_line_connection_frag_glsl[];
|
||||
extern char datatoc_lanpr_snake_line_connection_geom_glsl[];
|
||||
extern char datatoc_lanpr_software_line_chain_geom_glsl[];
|
||||
extern char datatoc_lanpr_software_chain_geom_glsl[];
|
||||
extern char datatoc_lanpr_dpix_project_passthrough_vert_glsl[];
|
||||
extern char datatoc_lanpr_dpix_project_clip_frag_glsl[];
|
||||
extern char datatoc_lanpr_dpix_preview_frag_glsl[];
|
||||
extern char datatoc_lanpr_software_passthrough_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_2D_smooth_color_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_2D_smooth_color_frag_glsl[];
|
||||
|
||||
LANPR_SharedResource lanpr_share;
|
||||
|
||||
static void lanpr_engine_init(void *ved)
|
||||
{
|
||||
lanpr_share.ved_viewport = ved;
|
||||
LANPR_Data *vedata = (LANPR_Data *)ved;
|
||||
LANPR_TextureList *txl = vedata->txl;
|
||||
LANPR_FramebufferList *fbl = vedata->fbl;
|
||||
|
||||
if (!lanpr_share.init_complete) {
|
||||
BLI_spin_init(&lanpr_share.lock_render_status);
|
||||
}
|
||||
|
||||
#if 0 /* Deprecated: snake mode */
|
||||
GPU_framebuffer_ensure_config(&fbl->edge_thinning,
|
||||
{GPU_ATTACHMENT_LEAVE,
|
||||
GPU_ATTACHMENT_TEXTURE(txl->color)});
|
||||
|
||||
if (!lanpr_share.edge_detect_shader) {
|
||||
lanpr_share.edge_detect_shader = DRW_shader_create(
|
||||
datatoc_common_fullscreen_vert_glsl, NULL, datatoc_lanpr_snake_edge_frag_glsl, NULL);
|
||||
}
|
||||
if (!lanpr_share.edge_thinning_shader) {
|
||||
lanpr_share.edge_thinning_shader = DRW_shader_create(
|
||||
datatoc_common_fullscreen_vert_glsl, NULL, datatoc_lanpr_snake_image_peel_frag_glsl, NULL);
|
||||
}
|
||||
if (!lanpr_share.snake_connection_shader) {
|
||||
lanpr_share.snake_connection_shader = DRW_shader_create(
|
||||
datatoc_lanpr_snake_line_connection_vert_glsl,
|
||||
datatoc_lanpr_snake_line_connection_geom_glsl,
|
||||
datatoc_lanpr_snake_line_connection_frag_glsl,
|
||||
NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
DRW_texture_ensure_fullscreen_2D_multisample(&txl->depth, GPU_DEPTH_COMPONENT32F, 8, 0);
|
||||
DRW_texture_ensure_fullscreen_2D_multisample(&txl->color, GPU_RGBA32F, 8, 0);
|
||||
DRW_texture_ensure_fullscreen_2D_multisample(&txl->normal, GPU_RGBA32F, 8, 0);
|
||||
DRW_texture_ensure_fullscreen_2D_multisample(&txl->edge_intermediate, GPU_RGBA32F, 8, 0);
|
||||
|
||||
DRW_texture_ensure_fullscreen_2D_multisample(
|
||||
&txl->ms_resolve_depth, GPU_DEPTH_COMPONENT32F, 8, 0);
|
||||
DRW_texture_ensure_fullscreen_2D_multisample(&txl->ms_resolve_color, GPU_RGBA32F, 8, 0);
|
||||
|
||||
GPU_framebuffer_ensure_config(&fbl->passes,
|
||||
{GPU_ATTACHMENT_TEXTURE(txl->depth),
|
||||
GPU_ATTACHMENT_TEXTURE(txl->color),
|
||||
GPU_ATTACHMENT_TEXTURE(txl->normal)});
|
||||
|
||||
GPU_framebuffer_ensure_config(
|
||||
&fbl->edge_intermediate,
|
||||
{GPU_ATTACHMENT_TEXTURE(txl->depth), GPU_ATTACHMENT_TEXTURE(txl->edge_intermediate)});
|
||||
|
||||
if (!lanpr_share.multichannel_shader) {
|
||||
lanpr_share.multichannel_shader = DRW_shader_create(
|
||||
datatoc_gpu_shader_3D_smooth_color_vert_glsl,
|
||||
NULL,
|
||||
datatoc_gpu_shader_3D_smooth_color_frag_glsl,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* DPIX */
|
||||
lanpr_init_atlas_inputs(ved);
|
||||
|
||||
/* SOFTWARE */
|
||||
if (!lanpr_share.software_shader) {
|
||||
lanpr_share.software_shader = DRW_shader_create(datatoc_lanpr_software_passthrough_vert_glsl,
|
||||
datatoc_lanpr_software_line_chain_geom_glsl,
|
||||
datatoc_lanpr_dpix_preview_frag_glsl,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (!lanpr_share.software_chaining_shader) {
|
||||
lanpr_share.software_chaining_shader = DRW_shader_create(
|
||||
datatoc_lanpr_software_passthrough_vert_glsl,
|
||||
datatoc_lanpr_software_chain_geom_glsl,
|
||||
datatoc_lanpr_dpix_preview_frag_glsl,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GPU_framebuffer_ensure_config(&fbl->software_ms,
|
||||
{GPU_ATTACHMENT_TEXTURE(txl->ms_resolve_depth),
|
||||
GPU_ATTACHMENT_TEXTURE(txl->ms_resolve_color)});
|
||||
|
||||
lanpr_share.init_complete = 1;
|
||||
}
|
||||
|
||||
static void lanpr_dpix_batch_free(void)
|
||||
{
|
||||
LANPR_BatchItem *dpbi;
|
||||
while ((dpbi = BLI_pophead(&lanpr_share.dpix_batch_list)) != NULL) {
|
||||
GPU_BATCH_DISCARD_SAFE(dpbi->dpix_preview_batch);
|
||||
GPU_BATCH_DISCARD_SAFE(dpbi->dpix_transform_batch);
|
||||
}
|
||||
LANPR_RenderBuffer *rb = lanpr_share.render_buffer_shared;
|
||||
if (rb) {
|
||||
if (rb->DPIXIntersectionBatch) {
|
||||
GPU_BATCH_DISCARD_SAFE(rb->DPIXIntersectionBatch);
|
||||
}
|
||||
if (rb->DPIXIntersectionTransformBatch) {
|
||||
GPU_BATCH_DISCARD_SAFE(rb->DPIXIntersectionTransformBatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void lanpr_engine_free(void)
|
||||
{
|
||||
DRW_SHADER_FREE_SAFE(lanpr_share.multichannel_shader);
|
||||
DRW_SHADER_FREE_SAFE(lanpr_share.snake_connection_shader);
|
||||
DRW_SHADER_FREE_SAFE(lanpr_share.software_chaining_shader);
|
||||
DRW_SHADER_FREE_SAFE(lanpr_share.dpix_preview_shader);
|
||||
DRW_SHADER_FREE_SAFE(lanpr_share.dpix_transform_shader);
|
||||
DRW_SHADER_FREE_SAFE(lanpr_share.edge_detect_shader);
|
||||
DRW_SHADER_FREE_SAFE(lanpr_share.edge_thinning_shader);
|
||||
DRW_SHADER_FREE_SAFE(lanpr_share.software_shader);
|
||||
|
||||
lanpr_dpix_batch_free();
|
||||
|
||||
if (lanpr_share.render_buffer_shared) {
|
||||
LANPR_RenderBuffer *rb = lanpr_share.render_buffer_shared;
|
||||
ED_lanpr_destroy_render_data(rb);
|
||||
|
||||
GPU_BATCH_DISCARD_SAFE(rb->chain_draw_batch);
|
||||
|
||||
MEM_freeN(rb);
|
||||
lanpr_share.render_buffer_shared = NULL;
|
||||
}
|
||||
|
||||
BLI_mempool *mp = lanpr_share.mp_batch_list;
|
||||
|
||||
if (mp) {
|
||||
BLI_mempool_destroy(mp);
|
||||
}
|
||||
}
|
||||
|
||||
static void lanpr_cache_init(void *vedata)
|
||||
{
|
||||
|
||||
LANPR_PassList *psl = ((LANPR_Data *)vedata)->psl;
|
||||
LANPR_StorageList *stl = ((LANPR_Data *)vedata)->stl;
|
||||
LANPR_TextureList *txl = ((LANPR_Data *)vedata)->txl;
|
||||
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
static float normal_object_direction[3] = {0, 0, 1};
|
||||
|
||||
/* Transfer reload state */
|
||||
lanpr_share.dpix_reloaded = lanpr_share.dpix_reloaded_deg;
|
||||
|
||||
if (!stl->g_data) {
|
||||
/* Alloc transient pointers */
|
||||
stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
|
||||
}
|
||||
|
||||
if (!lanpr_share.mp_batch_list) {
|
||||
lanpr_share.mp_batch_list = BLI_mempool_create(
|
||||
sizeof(LANPR_BatchItem), 0, 128, BLI_MEMPOOL_NOP);
|
||||
}
|
||||
|
||||
LANPR_PrivateData *pd = stl->g_data;
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Scene *scene = DEG_get_evaluated_scene(draw_ctx->depsgraph);
|
||||
SceneLANPR *lanpr = &scene->lanpr;
|
||||
|
||||
int texture_size = lanpr_dpix_texture_size(lanpr);
|
||||
lanpr_share.texture_size = texture_size;
|
||||
|
||||
psl->color_pass = DRW_pass_create(
|
||||
"color Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WRITE_DEPTH);
|
||||
stl->g_data->multipass_shgrp = DRW_shgroup_create(lanpr_share.multichannel_shader,
|
||||
psl->color_pass);
|
||||
|
||||
if (lanpr->master_mode == LANPR_MASTER_MODE_SNAKE) {
|
||||
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
|
||||
|
||||
psl->edge_intermediate = DRW_pass_create("Edge Detection", DRW_STATE_WRITE_COLOR);
|
||||
stl->g_data->edge_detect_shgrp = DRW_shgroup_create(lanpr_share.edge_detect_shader,
|
||||
psl->edge_intermediate);
|
||||
DRW_shgroup_uniform_texture_ref(stl->g_data->edge_detect_shgrp, "tex_sample_0", &txl->depth);
|
||||
DRW_shgroup_uniform_texture_ref(stl->g_data->edge_detect_shgrp, "tex_sample_1", &txl->color);
|
||||
DRW_shgroup_uniform_texture_ref(stl->g_data->edge_detect_shgrp, "tex_sample_2", &txl->normal);
|
||||
|
||||
DRW_shgroup_uniform_float(stl->g_data->edge_detect_shgrp, "z_near", &stl->g_data->znear, 1);
|
||||
DRW_shgroup_uniform_float(stl->g_data->edge_detect_shgrp, "z_far", &stl->g_data->zfar, 1);
|
||||
|
||||
DRW_shgroup_uniform_float(stl->g_data->edge_detect_shgrp,
|
||||
"normal_clamp",
|
||||
&stl->g_data->normal_clamp,
|
||||
1); /* normal clamp */
|
||||
DRW_shgroup_uniform_float(stl->g_data->edge_detect_shgrp,
|
||||
"normal_strength",
|
||||
&stl->g_data->normal_strength,
|
||||
1); /* normal strength */
|
||||
DRW_shgroup_uniform_float(stl->g_data->edge_detect_shgrp,
|
||||
"depth_clamp",
|
||||
&stl->g_data->depth_clamp,
|
||||
1); /* depth clamp */
|
||||
DRW_shgroup_uniform_float(stl->g_data->edge_detect_shgrp,
|
||||
"depth_strength",
|
||||
&stl->g_data->depth_strength,
|
||||
1); /* depth strength */
|
||||
DRW_shgroup_call(stl->g_data->edge_detect_shgrp, quad, NULL);
|
||||
|
||||
psl->edge_thinning = DRW_pass_create("Edge Thinning Stage 1", DRW_STATE_WRITE_COLOR);
|
||||
stl->g_data->edge_thinning_shgrp = DRW_shgroup_create(lanpr_share.edge_thinning_shader,
|
||||
psl->edge_thinning);
|
||||
DRW_shgroup_uniform_texture_ref(
|
||||
stl->g_data->edge_thinning_shgrp, "tex_sample_0", &dtxl->color);
|
||||
DRW_shgroup_uniform_int(stl->g_data->edge_thinning_shgrp, "stage", &stl->g_data->stage, 1);
|
||||
DRW_shgroup_call(stl->g_data->edge_thinning_shgrp, quad, NULL);
|
||||
}
|
||||
else if (lanpr->master_mode == LANPR_MASTER_MODE_DPIX && lanpr->active_layer &&
|
||||
!lanpr_share.dpix_shader_error) {
|
||||
LANPR_LineLayer *ll = lanpr->line_layers.first;
|
||||
psl->dpix_transform_pass = DRW_pass_create("DPIX Transform Stage", DRW_STATE_WRITE_COLOR);
|
||||
stl->g_data->dpix_transform_shgrp = DRW_shgroup_create(lanpr_share.dpix_transform_shader,
|
||||
psl->dpix_transform_pass);
|
||||
DRW_shgroup_uniform_texture_ref(
|
||||
stl->g_data->dpix_transform_shgrp, "vert0_tex", &txl->dpix_in_pl);
|
||||
DRW_shgroup_uniform_texture_ref(
|
||||
stl->g_data->dpix_transform_shgrp, "vert1_tex", &txl->dpix_in_pr);
|
||||
DRW_shgroup_uniform_texture_ref(
|
||||
stl->g_data->dpix_transform_shgrp, "face_normal0_tex", &txl->dpix_in_nl);
|
||||
DRW_shgroup_uniform_texture_ref(
|
||||
stl->g_data->dpix_transform_shgrp, "face_normal1_tex", &txl->dpix_in_nr);
|
||||
DRW_shgroup_uniform_texture_ref(
|
||||
stl->g_data->dpix_transform_shgrp, "edge_mask_tex", &txl->dpix_in_edge_mask);
|
||||
DRW_shgroup_uniform_int(
|
||||
stl->g_data->dpix_transform_shgrp, "sample_step", &stl->g_data->dpix_sample_step, 1);
|
||||
DRW_shgroup_uniform_int(
|
||||
stl->g_data->dpix_transform_shgrp, "is_perspective", &stl->g_data->dpix_is_perspective, 1);
|
||||
DRW_shgroup_uniform_vec4(
|
||||
stl->g_data->dpix_transform_shgrp, "viewport", stl->g_data->dpix_viewport, 1);
|
||||
DRW_shgroup_uniform_int(
|
||||
stl->g_data->dpix_transform_shgrp, "buffer_width", &stl->g_data->dpix_buffer_width, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_transform_shgrp, "crease_threshold", &lanpr->crease_threshold, 1);
|
||||
DRW_shgroup_uniform_float(stl->g_data->dpix_transform_shgrp,
|
||||
"crease_fade_threshold",
|
||||
&lanpr->crease_fade_threshold,
|
||||
1);
|
||||
DRW_shgroup_uniform_int(stl->g_data->dpix_transform_shgrp, "use_contour", &ll->contour.use, 1);
|
||||
DRW_shgroup_uniform_int(stl->g_data->dpix_transform_shgrp, "use_crease", &ll->crease.use, 1);
|
||||
DRW_shgroup_uniform_int(
|
||||
stl->g_data->dpix_transform_shgrp, "use_material", &ll->material_separate.use, 1);
|
||||
DRW_shgroup_uniform_int(
|
||||
stl->g_data->dpix_transform_shgrp, "use_edge_mark", &ll->edge_mark.use, 1);
|
||||
DRW_shgroup_uniform_int(
|
||||
stl->g_data->dpix_transform_shgrp, "use_intersection", &ll->intersection.use, 1);
|
||||
|
||||
psl->dpix_preview_pass = DRW_pass_create("DPIX Preview",
|
||||
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
|
||||
DRW_STATE_DEPTH_LESS_EQUAL);
|
||||
stl->g_data->dpix_preview_shgrp = DRW_shgroup_create(lanpr_share.dpix_preview_shader,
|
||||
psl->dpix_preview_pass);
|
||||
DRW_shgroup_uniform_texture_ref(
|
||||
stl->g_data->dpix_preview_shgrp, "vert0_tex", &txl->dpix_out_pl);
|
||||
DRW_shgroup_uniform_texture_ref(
|
||||
stl->g_data->dpix_preview_shgrp, "vert1_tex", &txl->dpix_out_pr);
|
||||
DRW_shgroup_uniform_texture_ref(
|
||||
stl->g_data->dpix_preview_shgrp, "face_normal0_tex", &txl->dpix_in_nl);
|
||||
DRW_shgroup_uniform_texture_ref(stl->g_data->dpix_preview_shgrp,
|
||||
"face_normal1_tex",
|
||||
&txl->dpix_in_nr); /* these are for normal shading */
|
||||
DRW_shgroup_uniform_texture_ref(
|
||||
stl->g_data->dpix_preview_shgrp, "edge_mask_tex", &txl->dpix_in_edge_mask);
|
||||
DRW_shgroup_uniform_vec4(
|
||||
stl->g_data->dpix_preview_shgrp, "viewport", stl->g_data->dpix_viewport, 1);
|
||||
DRW_shgroup_uniform_vec4(stl->g_data->dpix_preview_shgrp,
|
||||
"contour_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color :
|
||||
ll->contour.color,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(stl->g_data->dpix_preview_shgrp,
|
||||
"crease_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color :
|
||||
ll->crease.color,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(
|
||||
stl->g_data->dpix_preview_shgrp,
|
||||
"material_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color : ll->material_separate.color,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(stl->g_data->dpix_preview_shgrp,
|
||||
"edge_mark_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color :
|
||||
ll->edge_mark.color,
|
||||
1);
|
||||
DRW_shgroup_uniform_vec4(
|
||||
stl->g_data->dpix_preview_shgrp,
|
||||
"intersection_color",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? ll->color : ll->intersection.color,
|
||||
1);
|
||||
static float use_background_color[4];
|
||||
copy_v3_v3(use_background_color, &scene->world->horr);
|
||||
use_background_color[3] = scene->r.alphamode ? 0.0f : 1.0f;
|
||||
|
||||
DRW_shgroup_uniform_vec4(
|
||||
stl->g_data->dpix_preview_shgrp, "background_color", use_background_color, 1);
|
||||
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp, "depth_offset", &stl->g_data->dpix_depth_offset, 1);
|
||||
DRW_shgroup_uniform_float(stl->g_data->dpix_preview_shgrp,
|
||||
"depth_width_influence",
|
||||
&lanpr->depth_width_influence,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp, "depth_width_curve", &lanpr->depth_width_curve, 1);
|
||||
DRW_shgroup_uniform_float(stl->g_data->dpix_preview_shgrp,
|
||||
"depth_alpha_influence",
|
||||
&lanpr->depth_alpha_influence,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp, "depth_alpha_curve", &lanpr->depth_alpha_curve, 1);
|
||||
static float unit_thickness = 1.0f;
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp, "line_thickness", &ll->thickness, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp,
|
||||
"line_thickness_contour",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? &unit_thickness : &ll->contour.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp,
|
||||
"line_thickness_crease",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? &unit_thickness : &ll->crease.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(stl->g_data->dpix_preview_shgrp,
|
||||
"line_thickness_material",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
&unit_thickness :
|
||||
&ll->material_separate.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp,
|
||||
"line_thickness_edge_mark",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ? &unit_thickness : &ll->edge_mark.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(stl->g_data->dpix_preview_shgrp,
|
||||
"line_thickness_intersection",
|
||||
(ll->flags & LANPR_LINE_LAYER_USE_SAME_STYLE) ?
|
||||
&unit_thickness :
|
||||
&ll->intersection.thickness,
|
||||
1);
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp, "z_near", &stl->g_data->dpix_znear, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp, "z_far", &stl->g_data->dpix_zfar, 1);
|
||||
|
||||
ED_lanpr_calculate_normal_object_vector(ll, normal_object_direction);
|
||||
|
||||
static int normal_effect_inverse;
|
||||
static int zero_value = 0;
|
||||
normal_effect_inverse = (ll->flags & LANPR_LINE_LAYER_NORMAL_INVERSE);
|
||||
|
||||
DRW_shgroup_uniform_int(stl->g_data->dpix_preview_shgrp,
|
||||
"normal_mode",
|
||||
(ll->flags & LANPR_LINE_LAYER_NORMAL_ENABLED) ? &ll->normal_mode :
|
||||
&zero_value,
|
||||
1);
|
||||
DRW_shgroup_uniform_int(
|
||||
stl->g_data->dpix_preview_shgrp, "normal_effect_inverse", &normal_effect_inverse, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp, "normal_ramp_begin", &ll->normal_ramp_begin, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp, "normal_ramp_end", &ll->normal_ramp_end, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp, "normal_thickness_start", &ll->normal_thickness_start, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
stl->g_data->dpix_preview_shgrp, "normal_thickness_end", &ll->normal_thickness_end, 1);
|
||||
DRW_shgroup_uniform_vec3(
|
||||
stl->g_data->dpix_preview_shgrp, "normal_direction", normal_object_direction, 1);
|
||||
|
||||
pd->begin_index = 0;
|
||||
int fsize = sizeof(float) * 4 * texture_size * texture_size;
|
||||
|
||||
if (lanpr_share.dpix_reloaded) {
|
||||
pd->atlas_pl = MEM_callocN(fsize, "atlas_point_l");
|
||||
pd->atlas_pr = MEM_callocN(fsize, "atlas_point_r");
|
||||
pd->atlas_nl = MEM_callocN(fsize, "atlas_normal_l");
|
||||
pd->atlas_nr = MEM_callocN(fsize, "atlas_normal_l");
|
||||
pd->atlas_edge_mask = MEM_callocN(fsize, "atlas_edge_mask"); /* should always be float */
|
||||
|
||||
lanpr_dpix_batch_free();
|
||||
|
||||
BLI_mempool_clear(lanpr_share.mp_batch_list);
|
||||
}
|
||||
}
|
||||
else if (lanpr->master_mode == LANPR_MASTER_MODE_SOFTWARE) {
|
||||
;
|
||||
}
|
||||
|
||||
/* Intersection cache must be calculated before drawing. */
|
||||
int updated = 0;
|
||||
if ((draw_ctx->scene->lanpr.flags & LANPR_AUTO_UPDATE) &&
|
||||
(!lanpr_share.render_buffer_shared ||
|
||||
lanpr_share.render_buffer_shared->cached_for_frame != draw_ctx->scene->r.cfra)) {
|
||||
if (draw_ctx->scene->lanpr.master_mode == LANPR_MASTER_MODE_SOFTWARE) {
|
||||
|
||||
ED_lanpr_compute_feature_lines_background(draw_ctx->depsgraph, 0);
|
||||
}
|
||||
else if (draw_ctx->scene->lanpr.master_mode == LANPR_MASTER_MODE_DPIX) {
|
||||
ED_lanpr_compute_feature_lines_background(draw_ctx->depsgraph, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (ED_lanpr_calculation_flag_check(LANPR_RENDER_FINISHED)) {
|
||||
ED_lanpr_rebuild_all_command(&draw_ctx->scene->lanpr);
|
||||
ED_lanpr_calculation_set_flag(LANPR_RENDER_IDLE);
|
||||
}
|
||||
else {
|
||||
DRW_viewport_request_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
static void lanpr_cache_populate(void *vedata, Object *ob)
|
||||
{
|
||||
|
||||
LANPR_StorageList *stl = ((LANPR_Data *)vedata)->stl;
|
||||
LANPR_PrivateData *pd = stl->g_data;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
SceneLANPR *lanpr = &draw_ctx->scene->lanpr;
|
||||
int usage = OBJECT_FEATURE_LINE_INHERENT, dpix_ok = 0;
|
||||
|
||||
if (!DRW_object_is_renderable(ob)) {
|
||||
return;
|
||||
}
|
||||
if (ob == draw_ctx->object_edit) {
|
||||
return;
|
||||
}
|
||||
if (ob->type != OB_MESH) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
|
||||
if (geom) {
|
||||
if ((dpix_ok = (lanpr->master_mode == LANPR_MASTER_MODE_DPIX && lanpr->active_layer &&
|
||||
!lanpr_share.dpix_shader_error)) != 0) {
|
||||
usage = ED_lanpr_object_collection_usage_check(draw_ctx->scene->master_collection, ob);
|
||||
if (usage == OBJECT_FEATURE_LINE_EXCLUDE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
DRW_shgroup_call_no_cull(stl->g_data->multipass_shgrp, geom, ob);
|
||||
}
|
||||
|
||||
if (dpix_ok) {
|
||||
|
||||
/* usage already set */
|
||||
if (usage == OBJECT_FEATURE_LINE_OCCLUSION_ONLY) {
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = pd->begin_index;
|
||||
if (lanpr_share.dpix_reloaded) {
|
||||
pd->begin_index = lanpr_feed_atlas_data_obj(vedata,
|
||||
pd->atlas_pl,
|
||||
pd->atlas_pr,
|
||||
pd->atlas_nl,
|
||||
pd->atlas_nr,
|
||||
pd->atlas_edge_mask,
|
||||
ob,
|
||||
idx);
|
||||
lanpr_feed_atlas_trigger_preview_obj(vedata, ob, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void lanpr_cache_finish(void *vedata)
|
||||
{
|
||||
LANPR_StorageList *stl = ((LANPR_Data *)vedata)->stl;
|
||||
LANPR_PrivateData *pd = stl->g_data;
|
||||
LANPR_TextureList *txl = ((LANPR_Data *)vedata)->txl;
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
SceneLANPR *lanpr = &draw_ctx->scene->lanpr;
|
||||
float mat[4][4];
|
||||
unit_m4(mat);
|
||||
|
||||
if (lanpr->master_mode == LANPR_MASTER_MODE_DPIX && lanpr->active_layer &&
|
||||
!lanpr_share.dpix_shader_error) {
|
||||
if (lanpr_share.dpix_reloaded) {
|
||||
if (lanpr_share.render_buffer_shared) {
|
||||
lanpr_feed_atlas_data_intersection_cache(vedata,
|
||||
pd->atlas_pl,
|
||||
pd->atlas_pr,
|
||||
pd->atlas_nl,
|
||||
pd->atlas_nr,
|
||||
pd->atlas_edge_mask,
|
||||
pd->begin_index);
|
||||
lanpr_create_atlas_intersection_preview(vedata, pd->begin_index);
|
||||
}
|
||||
GPU_texture_update(txl->dpix_in_pl, GPU_DATA_FLOAT, pd->atlas_pl);
|
||||
GPU_texture_update(txl->dpix_in_pr, GPU_DATA_FLOAT, pd->atlas_pr);
|
||||
GPU_texture_update(txl->dpix_in_nl, GPU_DATA_FLOAT, pd->atlas_nl);
|
||||
GPU_texture_update(txl->dpix_in_nr, GPU_DATA_FLOAT, pd->atlas_nr);
|
||||
GPU_texture_update(txl->dpix_in_edge_mask, GPU_DATA_FLOAT, pd->atlas_edge_mask);
|
||||
|
||||
MEM_freeN(pd->atlas_pl);
|
||||
MEM_freeN(pd->atlas_pr);
|
||||
MEM_freeN(pd->atlas_nl);
|
||||
MEM_freeN(pd->atlas_nr);
|
||||
MEM_freeN(pd->atlas_edge_mask);
|
||||
pd->atlas_pl = 0;
|
||||
lanpr_share.dpix_reloaded = 0;
|
||||
}
|
||||
|
||||
LANPR_BatchItem *bi;
|
||||
for (bi = lanpr_share.dpix_batch_list.first; bi; bi = (void *)bi->item.next) {
|
||||
DRW_shgroup_call_ex(
|
||||
pd->dpix_transform_shgrp, 0, bi->ob->obmat, bi->dpix_transform_batch, 0, 0, true, NULL);
|
||||
DRW_shgroup_call(pd->dpix_preview_shgrp, bi->dpix_preview_batch, 0);
|
||||
}
|
||||
|
||||
if (lanpr_share.render_buffer_shared &&
|
||||
lanpr_share.render_buffer_shared->DPIXIntersectionBatch) {
|
||||
DRW_shgroup_call(pd->dpix_transform_shgrp,
|
||||
lanpr_share.render_buffer_shared->DPIXIntersectionTransformBatch,
|
||||
0);
|
||||
DRW_shgroup_call(
|
||||
pd->dpix_preview_shgrp, lanpr_share.render_buffer_shared->DPIXIntersectionBatch, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void lanpr_draw_scene_exec(void *vedata, GPUFrameBuffer *dfb, int is_render)
|
||||
{
|
||||
LANPR_PassList *psl = ((LANPR_Data *)vedata)->psl;
|
||||
LANPR_TextureList *txl = ((LANPR_Data *)vedata)->txl;
|
||||
LANPR_StorageList *stl = ((LANPR_Data *)vedata)->stl;
|
||||
LANPR_FramebufferList *fbl = ((LANPR_Data *)vedata)->fbl;
|
||||
|
||||
float clear_col[4] = {1.0f, 0.0f, 0.0f, 1.0f};
|
||||
float clear_depth = 1.0f;
|
||||
uint clear_stencil = 0xFF;
|
||||
|
||||
GPU_framebuffer_bind(fbl->passes);
|
||||
eGPUFrameBufferBits clear_bits = GPU_DEPTH_BIT | GPU_COLOR_BIT;
|
||||
GPU_framebuffer_clear(fbl->passes, clear_bits, clear_col, clear_depth, clear_stencil);
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Scene *scene = DEG_get_evaluated_scene(draw_ctx->depsgraph);
|
||||
SceneLANPR *lanpr = &scene->lanpr;
|
||||
|
||||
if (lanpr->master_mode == LANPR_MASTER_MODE_DPIX && !lanpr_share.dpix_shader_error) {
|
||||
DRW_draw_pass(psl->color_pass);
|
||||
lanpr_dpix_draw_scene(txl, fbl, psl, stl->g_data, lanpr, dfb, is_render);
|
||||
}
|
||||
/* Deprecated
|
||||
else if (lanpr->master_mode == LANPR_MASTER_MODE_SNAKE) {
|
||||
DRW_draw_pass(psl->color_pass);
|
||||
lanpr_snake_draw_scene(txl, fbl, psl, stl->g_data, lanpr, dfb, is_render);
|
||||
}
|
||||
*/
|
||||
else if (lanpr->master_mode == LANPR_MASTER_MODE_SOFTWARE) {
|
||||
/* should isolate these into a seperate function. */
|
||||
lanpr_software_draw_scene(vedata, dfb, is_render);
|
||||
}
|
||||
}
|
||||
|
||||
static void lanpr_draw_scene(void *vedata)
|
||||
{
|
||||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
|
||||
lanpr_draw_scene_exec(vedata, dfbl->default_fb, 0);
|
||||
}
|
||||
|
||||
static void lanpr_render_cache(void *vedata,
|
||||
struct Object *ob,
|
||||
struct RenderEngine *UNUSED(engine),
|
||||
struct Depsgraph *UNUSED(depsgraph))
|
||||
{
|
||||
|
||||
lanpr_cache_populate(vedata, ob);
|
||||
}
|
||||
|
||||
static void lanpr_render_matrices_init(RenderEngine *engine, Depsgraph *depsgraph)
|
||||
{
|
||||
/* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */
|
||||
Scene *scene = DEG_get_evaluated_scene(depsgraph);
|
||||
struct Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re));
|
||||
float frame = BKE_scene_frame_get(scene);
|
||||
|
||||
/* Set the persective, view and window matrix. */
|
||||
float winmat[4][4], wininv[4][4];
|
||||
float viewmat[4][4], viewinv[4][4];
|
||||
float persmat[4][4], persinv[4][4];
|
||||
float unitmat[4][4];
|
||||
|
||||
RE_GetCameraWindow(engine->re, ob_camera_eval, frame, winmat);
|
||||
RE_GetCameraModelMatrix(engine->re, ob_camera_eval, viewinv);
|
||||
|
||||
invert_m4_m4(viewmat, viewinv);
|
||||
mul_m4_m4m4(persmat, winmat, viewmat);
|
||||
invert_m4_m4(persinv, persmat);
|
||||
invert_m4_m4(wininv, winmat);
|
||||
|
||||
unit_m4(unitmat);
|
||||
|
||||
DRWView *view = DRW_view_create(viewmat, winmat, NULL, NULL, NULL);
|
||||
DRW_view_default_set(view);
|
||||
DRW_view_set_active(view);
|
||||
}
|
||||
|
||||
static int LANPR_GLOBAL_update_tag;
|
||||
|
||||
static void lanpr_id_update(void *UNUSED(vedata), ID *id)
|
||||
{
|
||||
/* if (vedata->engine_type != &draw_engine_lanpr_type) return; */
|
||||
|
||||
/* Handle updates based on ID type. */
|
||||
switch (GS(id->name)) {
|
||||
case ID_WO:
|
||||
case ID_OB:
|
||||
case ID_ME:
|
||||
LANPR_GLOBAL_update_tag = 1;
|
||||
default:
|
||||
/* pass */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void lanpr_render_to_image(void *vedata,
|
||||
RenderEngine *engine,
|
||||
struct RenderLayer *render_layer,
|
||||
const rcti *rect)
|
||||
{
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
/* int update_mark = DEG_id_type_any_updated(draw_ctx->depsgraph); */
|
||||
Scene *scene = DEG_get_evaluated_scene(draw_ctx->depsgraph);
|
||||
SceneLANPR *lanpr = &scene->lanpr;
|
||||
|
||||
lanpr_share.re_render = engine;
|
||||
|
||||
RE_engine_update_stats(engine, NULL, "LANPR: Initializing");
|
||||
|
||||
if (lanpr->master_mode == LANPR_MASTER_MODE_SOFTWARE ||
|
||||
(lanpr->master_mode == LANPR_MASTER_MODE_DPIX && (lanpr->flags & LANPR_USE_INTERSECTIONS))) {
|
||||
if (!lanpr_share.render_buffer_shared) {
|
||||
ED_lanpr_create_render_buffer();
|
||||
}
|
||||
if (lanpr_share.render_buffer_shared->cached_for_frame != scene->r.cfra ||
|
||||
LANPR_GLOBAL_update_tag) {
|
||||
int intersections_only = (lanpr->master_mode != LANPR_MASTER_MODE_SOFTWARE);
|
||||
ED_lanpr_compute_feature_lines_internal(draw_ctx->depsgraph, intersections_only);
|
||||
}
|
||||
}
|
||||
|
||||
lanpr_render_matrices_init(engine, draw_ctx->depsgraph);
|
||||
|
||||
/* refered to eevee's code */
|
||||
|
||||
/* Init default FB and render targets:
|
||||
* In render mode the default framebuffer is not generated
|
||||
* because there is no viewport. So we need to manually create it or
|
||||
* not use it. For code clarity we just allocate it make use of it. */
|
||||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
DRW_texture_ensure_fullscreen_2d(&dtxl->depth, GPU_DEPTH_COMPONENT32F, 0);
|
||||
DRW_texture_ensure_fullscreen_2d(&dtxl->color, GPU_RGBA32F, 0);
|
||||
|
||||
GPU_framebuffer_ensure_config(
|
||||
&dfbl->default_fb,
|
||||
{GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)});
|
||||
|
||||
lanpr_engine_init(vedata);
|
||||
lanpr_share.dpix_reloaded_deg = 1; /* force dpix batch to re-create */
|
||||
lanpr_cache_init(vedata);
|
||||
DRW_render_object_iter(vedata, engine, draw_ctx->depsgraph, lanpr_render_cache);
|
||||
lanpr_cache_finish(vedata);
|
||||
|
||||
/* get ref for destroy data */
|
||||
/* lanpr_share.rb_ref = lanpr->render_buffer; */
|
||||
|
||||
DRW_render_instance_buffer_finish();
|
||||
|
||||
float clear_col[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
float clear_depth = 1.0f;
|
||||
uint clear_stencil = 0xFF;
|
||||
eGPUFrameBufferBits clear_bits = GPU_DEPTH_BIT | GPU_COLOR_BIT;
|
||||
|
||||
GPU_framebuffer_bind(dfbl->default_fb);
|
||||
GPU_framebuffer_clear(dfbl->default_fb, clear_bits, clear_col, clear_depth, clear_stencil);
|
||||
|
||||
lanpr_draw_scene_exec(vedata, dfbl->default_fb, 1);
|
||||
|
||||
/* read it back so we can again display and save it. */
|
||||
const char *viewname = RE_GetActiveRenderView(engine->re);
|
||||
RenderPass *rp = RE_pass_find_by_name(render_layer, RE_PASSNAME_COMBINED, viewname);
|
||||
GPU_framebuffer_bind(dfbl->default_fb);
|
||||
GPU_framebuffer_read_color(dfbl->default_fb,
|
||||
rect->xmin,
|
||||
rect->ymin,
|
||||
BLI_rcti_size_x(rect),
|
||||
BLI_rcti_size_y(rect),
|
||||
4,
|
||||
0,
|
||||
rp->rect);
|
||||
|
||||
/* Must clear to avoid other problems. */
|
||||
lanpr_share.re_render = NULL;
|
||||
}
|
||||
|
||||
static void lanpr_view_update(void *UNUSED(vedata))
|
||||
{
|
||||
lanpr_share.dpix_reloaded_deg = 1; /* very bad solution, this will slow down animation. */
|
||||
}
|
||||
|
||||
static const DrawEngineDataSize lanpr_data_size = DRW_VIEWPORT_DATA_SIZE(LANPR_Data);
|
||||
|
||||
DrawEngineType draw_engine_lanpr_type = {
|
||||
NULL,
|
||||
NULL,
|
||||
N_("LANPR"),
|
||||
&lanpr_data_size,
|
||||
&lanpr_engine_init,
|
||||
&lanpr_engine_free,
|
||||
&lanpr_cache_init,
|
||||
&lanpr_cache_populate,
|
||||
&lanpr_cache_finish,
|
||||
NULL, /* draw background */
|
||||
&lanpr_draw_scene, /* draw scene */
|
||||
&lanpr_view_update,
|
||||
&lanpr_id_update,
|
||||
&lanpr_render_to_image,
|
||||
};
|
||||
|
||||
RenderEngineType DRW_engine_viewport_lanpr_type = {NULL,
|
||||
NULL,
|
||||
LANPR_ENGINE,
|
||||
N_("LANPR"),
|
||||
RE_INTERNAL,
|
||||
NULL, /* update */
|
||||
&DRW_render_to_image, /* render to img */
|
||||
NULL, /* bake */
|
||||
NULL, /* view update */
|
||||
NULL, /* render to view */
|
||||
NULL, /* update in script */
|
||||
NULL, /* update in render pass */
|
||||
&draw_engine_lanpr_type,
|
||||
{NULL, NULL, NULL}};
|
623
source/blender/draw/engines/lanpr/lanpr_snake.c
Normal file
623
source/blender/draw/engines/lanpr/lanpr_snake.c
Normal file
@@ -0,0 +1,623 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Copyright 2019, Blender Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup draw
|
||||
*/
|
||||
|
||||
#include "DRW_engine.h"
|
||||
#include "DRW_render.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "lanpr_all.h"
|
||||
#include "DRW_render.h"
|
||||
#include "BKE_object.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_immediate_util.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "DNA_lanpr_types.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
#include "GPU_draw.h"
|
||||
#include "GPU_batch.h"
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_uniformbuffer.h"
|
||||
#include "GPU_viewport.h"
|
||||
#include "bmesh.h"
|
||||
|
||||
extern struct LANPR_SharedResource lanpr_share;
|
||||
|
||||
int _TNS_colOffsets[] = {-1, 0, 1, 1, 1, 0, -1, -1};
|
||||
int _TNS_rowOffsets[] = {-1, -1, -1, 0, 1, 1, 1, 0};
|
||||
|
||||
int _TNS_Deviates[8][8] = {{0, 1, 2, 3, 4, 3, 2, 1},
|
||||
{1, 0, 1, 2, 3, 4, 3, 2},
|
||||
{2, 1, 0, 1, 2, 3, 4, 3},
|
||||
{3, 2, 1, 0, 1, 2, 3, 4},
|
||||
{4, 3, 2, 1, 0, 1, 2, 3},
|
||||
{3, 4, 3, 2, 1, 0, 1, 2},
|
||||
{2, 3, 4, 3, 2, 1, 0, 1},
|
||||
{1, 2, 3, 4, 3, 2, 1, 0}};
|
||||
|
||||
#define TNS_CLAMP_TEXTURE_W(t, col) \
|
||||
{ \
|
||||
if (col >= t->width) \
|
||||
col = t->width - 1; \
|
||||
if (col < 0) \
|
||||
col = 0; \
|
||||
}
|
||||
|
||||
#define TNS_CLAMP_TEXTURE_H(t, row) \
|
||||
{ \
|
||||
if (row >= t->height) \
|
||||
row = t->height - 1; \
|
||||
if (row < 0) \
|
||||
row = 0; \
|
||||
}
|
||||
|
||||
#define TNS_CLAMP_TEXTURE_CONTINUE(t, col, row) \
|
||||
{ \
|
||||
if (col >= t->width) \
|
||||
continue; \
|
||||
if (col < 0) \
|
||||
continue; \
|
||||
if (row >= t->height) \
|
||||
continue; \
|
||||
if (row < 0) \
|
||||
continue; \
|
||||
}
|
||||
|
||||
static LANPR_TextureSample *lanpr_any_uncovered_samples(LANPR_PrivateData *pd)
|
||||
{
|
||||
return BLI_pophead(&pd->pending_samples);
|
||||
}
|
||||
|
||||
int lanpr_direction_deviate(int From, int To)
|
||||
{
|
||||
return _TNS_Deviates[From - 1][To - 1];
|
||||
}
|
||||
|
||||
int lanpr_detect_direction(LANPR_PrivateData *pd, int col, int row, int LastDirection)
|
||||
{
|
||||
int Deviate[9] = {100};
|
||||
int MinDeviate = 0;
|
||||
int i;
|
||||
LANPR_TextureSample *ts;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
TNS_CLAMP_TEXTURE_CONTINUE(pd, (_TNS_colOffsets[i] + col), (_TNS_rowOffsets[i] + row));
|
||||
if (ts = pd->sample_table[(_TNS_colOffsets[i] + col) +
|
||||
(_TNS_rowOffsets[i] + row) * pd->width]) {
|
||||
if (!LastDirection) {
|
||||
return i + 1;
|
||||
}
|
||||
Deviate[i + 1] = lanpr_direction_deviate(i, LastDirection);
|
||||
if (!MinDeviate || Deviate[MinDeviate] > Deviate[i + 1]) {
|
||||
MinDeviate = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MinDeviate;
|
||||
}
|
||||
|
||||
LANPR_LineStrip *lanpr_create_line_strip(LANPR_PrivateData *pd)
|
||||
{
|
||||
LANPR_LineStrip *ls = BLI_mempool_calloc(lanpr_share.mp_line_strip);
|
||||
return ls;
|
||||
}
|
||||
LANPR_LineStripPoint *lanpr_append_point(
|
||||
LANPR_PrivateData *pd, LANPR_LineStrip *ls, real X, real Y, real Z)
|
||||
{
|
||||
LANPR_LineStripPoint *lsp = BLI_mempool_calloc(lanpr_share.mp_line_strip_point);
|
||||
|
||||
lsp->P[0] = X;
|
||||
lsp->P[1] = Y;
|
||||
lsp->P[2] = Z;
|
||||
|
||||
BLI_addtail(&ls->points, lsp);
|
||||
|
||||
ls->point_count++;
|
||||
|
||||
return lsp;
|
||||
}
|
||||
LANPR_LineStripPoint *lanpr_push_point(
|
||||
LANPR_PrivateData *pd, LANPR_LineStrip *ls, real X, real Y, real Z)
|
||||
{
|
||||
LANPR_LineStripPoint *lsp = BLI_mempool_calloc(lanpr_share.mp_line_strip_point);
|
||||
|
||||
lsp->P[0] = X;
|
||||
lsp->P[1] = Y;
|
||||
lsp->P[2] = Z;
|
||||
|
||||
BLI_addhead(&ls->points, lsp);
|
||||
|
||||
ls->point_count++;
|
||||
|
||||
return lsp;
|
||||
}
|
||||
|
||||
void lanpr_destroy_line_strip(LANPR_PrivateData *pd, LANPR_LineStrip *ls)
|
||||
{
|
||||
LANPR_LineStripPoint *lsp;
|
||||
while (lsp = BLI_pophead(&ls->points)) {
|
||||
BLI_mempool_free(lanpr_share.mp_line_strip_point, lsp);
|
||||
}
|
||||
BLI_mempool_free(lanpr_share.mp_line_strip, ls);
|
||||
}
|
||||
|
||||
void lanpr_remove_sample(LANPR_PrivateData *pd, int row, int col)
|
||||
{
|
||||
LANPR_TextureSample *ts;
|
||||
ts = pd->sample_table[row * pd->width + col];
|
||||
pd->sample_table[row * pd->width + col] = NULL;
|
||||
|
||||
BLI_remlink(&pd->pending_samples, ts);
|
||||
ts->prev = NULL;
|
||||
ts->next = NULL;
|
||||
BLI_addtail(&pd->erased_samples, ts);
|
||||
}
|
||||
|
||||
void lanpr_grow_snake_r(LANPR_PrivateData *pd,
|
||||
LANPR_LineStrip *ls,
|
||||
LANPR_LineStripPoint *ThisP,
|
||||
int Direction)
|
||||
{
|
||||
LANPR_LineStripPoint *NewP = ThisP, *p2;
|
||||
int Length = 5;
|
||||
int l = 0;
|
||||
int Deviate, Dir = Direction, NewDir;
|
||||
int AddPoint;
|
||||
int TX = NewP->P[0], TY = NewP->P[1];
|
||||
|
||||
while (NewDir = lanpr_detect_direction(pd, TX, TY, Dir)) {
|
||||
AddPoint = 0;
|
||||
Deviate = lanpr_direction_deviate(NewDir, Dir);
|
||||
Dir = NewDir;
|
||||
|
||||
l++;
|
||||
TX += _TNS_colOffsets[NewDir - 1];
|
||||
TY += _TNS_rowOffsets[NewDir - 1];
|
||||
|
||||
if (Deviate < 2) {
|
||||
lanpr_remove_sample(pd, TY, TX);
|
||||
}
|
||||
else if (Deviate < 3) {
|
||||
lanpr_remove_sample(pd, TY, TX);
|
||||
AddPoint = 1;
|
||||
}
|
||||
else {
|
||||
lanpr_remove_sample(pd, TY, TX);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AddPoint || l == Length) {
|
||||
p2 = lanpr_append_point(pd, ls, TX, TY, 0);
|
||||
NewP = p2;
|
||||
l = 0;
|
||||
}
|
||||
}
|
||||
if (TX != ThisP->P[0] || TY != ThisP->P[1]) {
|
||||
lanpr_append_point(pd, ls, TX, TY, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void lanpr_grow_snake_l(LANPR_PrivateData *pd,
|
||||
LANPR_LineStrip *ls,
|
||||
LANPR_LineStripPoint *ThisP,
|
||||
int Direction)
|
||||
{
|
||||
LANPR_LineStripPoint *NewP = ThisP, *p2;
|
||||
int Length = 5;
|
||||
int l = 0;
|
||||
int Deviate, Dir = Direction, NewDir;
|
||||
int AddPoint;
|
||||
int TX = NewP->P[0], TY = NewP->P[1];
|
||||
|
||||
while (NewDir = lanpr_detect_direction(pd, TX, TY, Dir)) {
|
||||
AddPoint = 0;
|
||||
Deviate = lanpr_direction_deviate(NewDir, Dir);
|
||||
Dir = NewDir;
|
||||
|
||||
l++;
|
||||
TX += _TNS_colOffsets[NewDir - 1];
|
||||
TY += _TNS_rowOffsets[NewDir - 1];
|
||||
|
||||
if (Deviate < 2) {
|
||||
lanpr_remove_sample(pd, TY, TX);
|
||||
}
|
||||
else if (Deviate < 4) {
|
||||
lanpr_remove_sample(pd, TY, TX);
|
||||
AddPoint = 1;
|
||||
}
|
||||
else {
|
||||
lanpr_remove_sample(pd, TY, TX);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AddPoint || l == Length) {
|
||||
p2 = lanpr_push_point(pd, ls, TX, TY, 0);
|
||||
NewP = p2;
|
||||
l = 0;
|
||||
}
|
||||
}
|
||||
if (TX != ThisP->P[0] || TY != ThisP->P[1]) {
|
||||
lanpr_push_point(pd, ls, TX, TY, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int lanpr_reverse_direction(int From)
|
||||
{
|
||||
From -= 4;
|
||||
if (From <= 0) {
|
||||
From += 8;
|
||||
}
|
||||
return From;
|
||||
}
|
||||
|
||||
void lanpr_texture_to_ndc(int x, int y, int w, int h, float *x_ndc, float *y_ndc)
|
||||
{
|
||||
*x_ndc = interpf(1, -1, (float)x / (float)w);
|
||||
*y_ndc = interpf(1, -1, (float)y / (float)h);
|
||||
}
|
||||
|
||||
void lanpr_count_drawing_elements(LANPR_PrivateData *pd,
|
||||
int *vert_count,
|
||||
int *index_adjacent_count)
|
||||
{
|
||||
int v_count = 0;
|
||||
int e_count = 0;
|
||||
LANPR_LineStrip *ls;
|
||||
for (ls = (LANPR_LineStrip *)(pd->line_strips.first); ls; ls = (ls->next)) {
|
||||
v_count += (ls->point_count);
|
||||
e_count += ((ls->point_count - 1) * 4);
|
||||
}
|
||||
*vert_count = v_count;
|
||||
*index_adjacent_count = e_count;
|
||||
}
|
||||
|
||||
GPUBatch *lanpr_get_snake_batch(LANPR_PrivateData *pd)
|
||||
{
|
||||
LANPR_LineStrip *ls;
|
||||
LANPR_LineStripPoint *lsp, *plsp;
|
||||
int i;
|
||||
float *Verts;
|
||||
float *Lengths;
|
||||
float TotalLength = 0;
|
||||
int v_count, e_count;
|
||||
|
||||
lanpr_count_drawing_elements(pd, &v_count, &e_count);
|
||||
|
||||
Verts = MEM_callocN(sizeof(float) * v_count * 2, "Verts buffer pre alloc");
|
||||
Lengths = MEM_callocN(sizeof(float) * v_count * 2, "Length buffer pre alloc");
|
||||
|
||||
GPUIndexBufBuilder elb;
|
||||
GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINES_ADJ, e_count, v_count);
|
||||
|
||||
int vert_offset = 0;
|
||||
|
||||
for (ls = (LANPR_LineStrip *)(pd->line_strips.first); ls; ls = (ls->next)) {
|
||||
for (i = 0; i < ls->point_count - 1; i++) {
|
||||
int v1 = i + vert_offset - 1;
|
||||
int v2 = i + vert_offset;
|
||||
int v3 = i + vert_offset + 1;
|
||||
int v4 = i + vert_offset + 2;
|
||||
if (v1 < 0) {
|
||||
v1 = 0;
|
||||
}
|
||||
if (v4 >= v_count) {
|
||||
v4 = v_count - 1;
|
||||
}
|
||||
GPU_indexbuf_add_line_adj_verts(&elb, v1, v2, v3, v4);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
float xf, yf;
|
||||
TotalLength = 0;
|
||||
for (lsp = (LANPR_LineStripPoint *)(ls->points.first); lsp; lsp = (lsp->next)) {
|
||||
lanpr_texture_to_ndc(lsp->P[0], lsp->P[1], pd->width, pd->height, &xf, &yf);
|
||||
Verts[vert_offset * 2 + i * 2 + 0] = xf;
|
||||
Verts[vert_offset * 2 + i * 2 + 1] = yf;
|
||||
if (plsp = (LANPR_LineStripPoint *)(lsp->prev)) {
|
||||
TotalLength += tMatDist2v(plsp->P, lsp->P);
|
||||
Lengths[(vert_offset + i) * 2] = TotalLength;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
ls->total_length = TotalLength;
|
||||
i = 0;
|
||||
for (lsp = (LANPR_LineStripPoint *)(ls->points.first); lsp; lsp = (lsp->next)) {
|
||||
if (plsp = (LANPR_LineStripPoint *)(lsp->prev)) {
|
||||
Lengths[(vert_offset + i) * 2 + 1] = ls->total_length - Lengths[(vert_offset + i) * 2];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
vert_offset += (ls->point_count);
|
||||
}
|
||||
|
||||
static GPUVertFormat format = {0};
|
||||
static struct {
|
||||
uint pos, uvs;
|
||||
} attr_id;
|
||||
if (format.attr_len == 0) {
|
||||
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
attr_id.uvs = GPU_vertformat_attr_add(&format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
}
|
||||
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
GPU_vertbuf_data_alloc(vbo, v_count);
|
||||
|
||||
for (int i = 0; i < v_count; ++i) {
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.pos, i, &Verts[i * 2]);
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.uvs, i, &Lengths[i * 2]);
|
||||
}
|
||||
|
||||
MEM_freeN(Verts);
|
||||
MEM_freeN(Lengths);
|
||||
|
||||
return GPU_batch_create_ex(
|
||||
GPU_PRIM_LINES_ADJ, vbo, GPU_indexbuf_build(&elb), GPU_USAGE_STATIC | GPU_BATCH_OWNS_VBO);
|
||||
}
|
||||
|
||||
void lanpr_snake_prepare_cache(LANPR_PrivateData *pd)
|
||||
{
|
||||
if (pd->line_result_8bit) {
|
||||
MEM_freeN(pd->line_result_8bit);
|
||||
}
|
||||
pd->line_result_8bit = 0;
|
||||
if (pd->line_result) {
|
||||
MEM_freeN(pd->line_result);
|
||||
}
|
||||
pd->line_result = 0;
|
||||
lanpr_share.mp_sample = BLI_mempool_create(sizeof(LANPR_TextureSample), 0, 512, BLI_MEMPOOL_NOP);
|
||||
lanpr_share.mp_line_strip = BLI_mempool_create(sizeof(LANPR_LineStrip), 0, 512, BLI_MEMPOOL_NOP);
|
||||
lanpr_share.mp_line_strip_point = BLI_mempool_create(
|
||||
sizeof(LANPR_LineStripPoint), 0, 1024, BLI_MEMPOOL_NOP);
|
||||
}
|
||||
void lanpe_sanke_free_cache(LANPR_PrivateData *pd)
|
||||
{
|
||||
if (pd->line_result_8bit) {
|
||||
MEM_freeN(pd->line_result_8bit);
|
||||
}
|
||||
pd->line_result_8bit = 0;
|
||||
if (pd->line_result) {
|
||||
MEM_freeN(pd->line_result);
|
||||
}
|
||||
pd->line_result = 0;
|
||||
|
||||
BLI_mempool_destroy(lanpr_share.mp_line_strip);
|
||||
BLI_mempool_destroy(lanpr_share.mp_line_strip_point);
|
||||
BLI_mempool_destroy(lanpr_share.mp_sample);
|
||||
}
|
||||
void lanpr_snake_free_readback_data(LANPR_PrivateData *pd)
|
||||
{
|
||||
if (pd->line_result_8bit) {
|
||||
MEM_freeN(pd->line_result_8bit);
|
||||
}
|
||||
pd->line_result_8bit = 0;
|
||||
if (pd->line_result) {
|
||||
MEM_freeN(pd->line_result);
|
||||
}
|
||||
pd->line_result = 0;
|
||||
}
|
||||
|
||||
void lanpr_snake_draw_scene(LANPR_TextureList *txl,
|
||||
LANPR_FramebufferList *fbl,
|
||||
LANPR_PassList *psl,
|
||||
LANPR_PrivateData *pd,
|
||||
SceneLANPR *lanpr,
|
||||
GPUFrameBuffer *DefaultFB,
|
||||
int is_render)
|
||||
{
|
||||
eGPUFrameBufferBits clear_bits = GPU_COLOR_BIT | GPU_DEPTH_BIT;
|
||||
float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
float clear_depth = 1.0f;
|
||||
uint clear_stencil = 0xFF;
|
||||
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Scene *scene = DEG_get_evaluated_scene(draw_ctx->depsgraph);
|
||||
View3D *v3d = draw_ctx->v3d;
|
||||
Object *camera;
|
||||
if (v3d) {
|
||||
RegionView3D *rv3d = draw_ctx->rv3d;
|
||||
camera = (rv3d->persp == RV3D_CAMOB) ? v3d->camera : NULL;
|
||||
}
|
||||
else {
|
||||
camera = scene->camera;
|
||||
}
|
||||
|
||||
pd->znear = camera ? ((Camera *)camera->data)->clip_start : 0.1;
|
||||
pd->zfar = camera ? ((Camera *)camera->data)->clip_end : 100;
|
||||
pd->normal_clamp = lanpr->normal_clamp;
|
||||
pd->normal_strength = lanpr->normal_strength;
|
||||
pd->depth_clamp = lanpr->depth_clamp;
|
||||
pd->depth_strength = lanpr->depth_strength;
|
||||
|
||||
GPU_framebuffer_bind(fbl->edge_intermediate);
|
||||
DRW_draw_pass(psl->edge_intermediate);
|
||||
|
||||
if ((!lanpr->enable_vector_trace) && (!lanpr->display_thinning_result)) {
|
||||
GPU_framebuffer_bind(DefaultFB);
|
||||
DRW_multisamples_resolve(txl->depth, txl->edge_intermediate, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lanpr->display_thinning_result || lanpr->enable_vector_trace) {
|
||||
pd->stage = 0;
|
||||
|
||||
GPU_framebuffer_bind(DefaultFB);
|
||||
DRW_multisamples_resolve(txl->depth, txl->edge_intermediate, 1);
|
||||
|
||||
GPU_framebuffer_bind(fbl->edge_thinning);
|
||||
DRW_draw_pass(psl->edge_thinning);
|
||||
GPU_framebuffer_bind(DefaultFB);
|
||||
DRW_multisamples_resolve(txl->depth, txl->color, 1);
|
||||
|
||||
pd->stage = 1;
|
||||
GPU_framebuffer_bind(fbl->edge_thinning);
|
||||
DRW_draw_pass(psl->edge_thinning);
|
||||
GPU_framebuffer_bind(DefaultFB);
|
||||
DRW_multisamples_resolve(txl->depth, txl->color, 1);
|
||||
|
||||
pd->stage = 0;
|
||||
GPU_framebuffer_bind(fbl->edge_thinning);
|
||||
DRW_draw_pass(psl->edge_thinning);
|
||||
GPU_framebuffer_bind(DefaultFB);
|
||||
DRW_multisamples_resolve(txl->depth, txl->color, 1);
|
||||
|
||||
pd->stage = 1;
|
||||
GPU_framebuffer_bind(fbl->edge_thinning);
|
||||
DRW_draw_pass(psl->edge_thinning);
|
||||
GPU_framebuffer_bind(DefaultFB);
|
||||
DRW_multisamples_resolve(txl->depth, txl->color, 1);
|
||||
|
||||
if (!lanpr->enable_vector_trace) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int texw = GPU_texture_width(txl->edge_intermediate),
|
||||
texh = GPU_texture_height(txl->edge_intermediate);
|
||||
;
|
||||
int tsize = texw * texh;
|
||||
int recreate = 0;
|
||||
if (tsize != pd->width * pd->height) {
|
||||
recreate = 1;
|
||||
}
|
||||
|
||||
if (recreate || !pd->line_result) {
|
||||
if (pd->line_result) {
|
||||
MEM_freeN(pd->line_result);
|
||||
}
|
||||
pd->line_result = MEM_callocN(sizeof(float) * tsize, "Texture readback buffer");
|
||||
|
||||
if (pd->line_result_8bit) {
|
||||
MEM_freeN(pd->line_result_8bit);
|
||||
}
|
||||
pd->line_result_8bit = MEM_callocN(sizeof(unsigned char) * tsize,
|
||||
"Texture readback buffer 8bit");
|
||||
|
||||
if (pd->sample_table) {
|
||||
MEM_freeN(pd->sample_table);
|
||||
}
|
||||
pd->sample_table = MEM_callocN(sizeof(void *) * tsize, "Texture readback buffer 8bit");
|
||||
|
||||
pd->width = texw;
|
||||
pd->height = texh;
|
||||
}
|
||||
|
||||
GPU_framebuffer_bind(DefaultFB);
|
||||
GPU_framebuffer_read_color(DefaultFB, 0, 0, texw, texh, 1, 0, pd->line_result);
|
||||
|
||||
float sample;
|
||||
int h, w;
|
||||
for (h = 0; h < texh; h++) {
|
||||
for (w = 0; w < texw; w++) {
|
||||
int index = h * texw + w;
|
||||
if ((sample = pd->line_result[index]) > 0.9) {
|
||||
pd->line_result_8bit[index] = 255;
|
||||
LANPR_TextureSample *ts = BLI_mempool_calloc(lanpr_share.mp_sample);
|
||||
BLI_addtail(&pd->pending_samples, ts);
|
||||
pd->sample_table[index] = ts;
|
||||
ts->X = w;
|
||||
ts->Y = h;
|
||||
}
|
||||
else {
|
||||
pd->sample_table[index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LANPR_TextureSample *ts;
|
||||
LANPR_LineStrip *ls;
|
||||
LANPR_LineStripPoint *lsp;
|
||||
while (ts = lanpr_any_uncovered_samples(pd)) {
|
||||
int Direction = 0;
|
||||
LANPR_LineStripPoint tlsp = {0};
|
||||
|
||||
tlsp.P[0] = ts->X;
|
||||
tlsp.P[1] = ts->Y;
|
||||
|
||||
if (Direction = lanpr_detect_direction(pd, ts->X, ts->Y, Direction)) {
|
||||
BLI_addtail(&pd->line_strips, (ls = lanpr_create_line_strip(pd)));
|
||||
lsp = lanpr_append_point(pd, ls, ts->X, ts->Y, 0);
|
||||
lanpr_remove_sample(pd, ts->Y, ts->X);
|
||||
|
||||
lanpr_grow_snake_r(pd, ls, lsp, Direction);
|
||||
|
||||
lanpr_grow_snake_l(pd, ls, lsp, lanpr_reverse_direction(Direction));
|
||||
}
|
||||
}
|
||||
|
||||
float use_background_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
copy_v3_v3(use_background_color, &scene->world->horr);
|
||||
use_background_color[3] = scene->r.alphamode ? 0.0f : 1.0f;
|
||||
|
||||
GPU_framebuffer_bind(DefaultFB);
|
||||
GPU_framebuffer_clear(DefaultFB, clear_bits, use_background_color, clear_depth, clear_stencil);
|
||||
|
||||
GPU_framebuffer_bind(fbl->edge_intermediate);
|
||||
clear_bits = GPU_COLOR_BIT;
|
||||
GPU_framebuffer_clear(
|
||||
fbl->edge_intermediate, clear_bits, use_background_color, clear_depth, clear_stencil);
|
||||
|
||||
float *tld = &lanpr->taper_left_distance, *tls = &lanpr->taper_left_strength,
|
||||
*trd = &lanpr->taper_right_distance, *trs = &lanpr->taper_right_strength;
|
||||
|
||||
GPUBatch *snake_batch = lanpr_get_snake_batch(pd);
|
||||
|
||||
lanpr_snake_prepare_cache(pd);
|
||||
|
||||
psl->snake_pass = DRW_pass_create("Snake Visualization Pass",
|
||||
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
|
||||
DRW_STATE_DEPTH_ALWAYS);
|
||||
pd->snake_shgrp = DRW_shgroup_create(lanpr_share.snake_connection_shader, psl->snake_pass);
|
||||
DRW_shgroup_uniform_float(pd->snake_shgrp, "line_width", &lanpr->line_thickness, 1);
|
||||
DRW_shgroup_uniform_float(pd->snake_shgrp, "taper_l_dist", tld, 1);
|
||||
DRW_shgroup_uniform_float(pd->snake_shgrp, "taper_r_dist", tls, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
pd->snake_shgrp, "taper_l_strength", (lanpr->flags & LANPR_SAME_TAPER) ? tld : trd, 1);
|
||||
DRW_shgroup_uniform_float(
|
||||
pd->snake_shgrp, "taper_r_strength", (lanpr->flags & LANPR_SAME_TAPER) ? tls : trs, 1);
|
||||
DRW_shgroup_uniform_vec4(pd->snake_shgrp, "line_color", lanpr->line_color, 1);
|
||||
|
||||
DRW_shgroup_call(pd->snake_shgrp, snake_batch, NULL);
|
||||
GPU_framebuffer_bind(fbl->edge_intermediate);
|
||||
|
||||
DRW_draw_pass(psl->snake_pass);
|
||||
GPU_BATCH_DISCARD_SAFE(snake_batch);
|
||||
|
||||
BLI_mempool_clear(lanpr_share.mp_sample);
|
||||
BLI_mempool_clear(lanpr_share.mp_line_strip);
|
||||
BLI_mempool_clear(lanpr_share.mp_line_strip_point);
|
||||
|
||||
pd->pending_samples.first = pd->pending_samples.last = 0;
|
||||
pd->erased_samples.first = pd->erased_samples.last = 0;
|
||||
pd->line_strips.first = pd->line_strips.last = 0;
|
||||
|
||||
GPU_framebuffer_bind(DefaultFB);
|
||||
DRW_multisamples_resolve(txl->depth, txl->edge_intermediate, 1);
|
||||
|
||||
lanpe_sanke_free_cache(pd);
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
in vec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragData[0] = vec4(out_color.rgb, 1);
|
||||
}
|
@@ -0,0 +1,193 @@
|
||||
layout(points) in;
|
||||
layout(triangle_strip, max_vertices = 6) out;
|
||||
|
||||
uniform sampler2D vert0_tex; // L
|
||||
uniform sampler2D vert1_tex; // R
|
||||
uniform sampler2D face_normal0_tex;
|
||||
uniform sampler2D face_normal1_tex; // caution: these are face normals!
|
||||
uniform sampler2D edge_mask_tex;
|
||||
|
||||
// uniform float uValue0; // buffer_w
|
||||
uniform vec4 viewport; // viewport
|
||||
uniform float depth_offset;
|
||||
|
||||
// these are for depth related thickness control;
|
||||
uniform float line_thickness;
|
||||
uniform float depth_width_influence;
|
||||
uniform float depth_width_curve;
|
||||
uniform float depth_alpha_influence;
|
||||
uniform float depth_alpha_curve;
|
||||
uniform float z_near;
|
||||
uniform float z_far;
|
||||
|
||||
uniform vec4 background_color;
|
||||
|
||||
uniform vec4 contour_color;
|
||||
uniform vec4 crease_color;
|
||||
uniform vec4 material_color;
|
||||
uniform vec4 edge_mark_color;
|
||||
uniform vec4 intersection_color;
|
||||
|
||||
uniform float line_thickness_contour;
|
||||
uniform float line_thickness_crease;
|
||||
uniform float line_thickness_material;
|
||||
uniform float line_thickness_edge_mark;
|
||||
uniform float line_thickness_intersection;
|
||||
|
||||
// the same as software mode
|
||||
uniform int normal_mode;
|
||||
uniform int normal_effect_inverse;
|
||||
uniform vec3 normal_direction; // also used as point position
|
||||
uniform float normal_ramp_begin;
|
||||
uniform float normal_ramp_end;
|
||||
uniform float normal_thickness_start;
|
||||
uniform float normal_thickness_end;
|
||||
|
||||
float use_thickness;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
vec4 use_color;
|
||||
|
||||
float get_linear_depth(float z)
|
||||
{
|
||||
float ze = 2.0 * z_near * z_far / (z_far + z_near - z * (z_far - z_near));
|
||||
return (ze - z_near) / (z_far - z_near);
|
||||
}
|
||||
|
||||
float curve_01(float z, float factor)
|
||||
{
|
||||
return pow(z, 1 - factor); // factor is -inf~1-eps
|
||||
}
|
||||
|
||||
vec4 apply_scale(vec4 center, vec4 a)
|
||||
{
|
||||
float lz = get_linear_depth(center.z);
|
||||
float depth_factor = mix(0, curve_01(lz, depth_width_curve), depth_width_influence);
|
||||
|
||||
return mix(a, center, depth_factor);
|
||||
}
|
||||
|
||||
void emit_color_and_alpha(vec4 a, int is_crease, float crease_fading)
|
||||
{
|
||||
float lz = get_linear_depth(a.z);
|
||||
float alpha_factor = mix(0, curve_01(lz, depth_alpha_curve), depth_alpha_influence);
|
||||
float alpha_crease_fading = alpha_factor;
|
||||
if (is_crease > 0)
|
||||
alpha_crease_fading = mix(alpha_factor, 1, crease_fading * 2); // fading=0.5 -> fade all
|
||||
out_color = vec4(use_color.rgb, mix(1, 0, alpha_crease_fading));
|
||||
}
|
||||
|
||||
void draw_line(vec4 p1, vec4 p2, int is_crease)
|
||||
{
|
||||
|
||||
vec4 Line = p2 - p1;
|
||||
vec4 Normal = normalize(vec4(-Line.y, Line.x, 0, 0));
|
||||
|
||||
vec4 a, b, c, d;
|
||||
|
||||
vec4 offset = Normal * use_thickness * 0.001;
|
||||
|
||||
// correct thickness
|
||||
offset.x *= viewport.w / viewport.z;
|
||||
|
||||
a = p1 + offset;
|
||||
b = p1 - offset;
|
||||
c = p2 + offset;
|
||||
d = p2 - offset;
|
||||
|
||||
a = apply_scale(p1, a);
|
||||
b = apply_scale(p1, b);
|
||||
c = apply_scale(p2, c);
|
||||
d = apply_scale(p2, d);
|
||||
|
||||
gl_Position = vec4(a.xy, a.z - depth_offset, 1);
|
||||
emit_color_and_alpha(a, is_crease, p2.w);
|
||||
EmitVertex();
|
||||
gl_Position = vec4(b.xy, b.z - depth_offset, 1);
|
||||
emit_color_and_alpha(b, is_crease, p2.w);
|
||||
EmitVertex();
|
||||
gl_Position = vec4(c.xy, c.z - depth_offset, 1);
|
||||
emit_color_and_alpha(c, is_crease, p2.w);
|
||||
EmitVertex();
|
||||
|
||||
gl_Position = vec4(b.xy, b.z - depth_offset, 1);
|
||||
emit_color_and_alpha(b, is_crease, p2.w);
|
||||
EmitVertex();
|
||||
gl_Position = vec4(c.xy, c.z - depth_offset, 1);
|
||||
emit_color_and_alpha(c, is_crease, p2.w);
|
||||
EmitVertex();
|
||||
gl_Position = vec4(d.xy, d.z - depth_offset, 1);
|
||||
emit_color_and_alpha(d, is_crease, p2.w);
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
float factor_to_thickness(float factor)
|
||||
{
|
||||
float r = (factor - normal_ramp_begin) / (normal_ramp_end - normal_ramp_begin);
|
||||
if (r > 1)
|
||||
r = 1;
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
float thickness = normal_effect_inverse == 1 ?
|
||||
mix(normal_thickness_start, normal_thickness_end, r) :
|
||||
mix(normal_thickness_end, normal_thickness_start, r);
|
||||
return thickness;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 p1 = texelFetch(vert0_tex, ivec2(gl_in[0].gl_Position.xy), 0);
|
||||
vec4 p2 = texelFetch(vert1_tex, ivec2(gl_in[0].gl_Position.xy), 0);
|
||||
|
||||
vec4 n1 = texelFetch(face_normal0_tex, ivec2(gl_in[0].gl_Position.xy), 0);
|
||||
vec4 n2 = texelFetch(face_normal1_tex, ivec2(gl_in[0].gl_Position.xy), 0);
|
||||
|
||||
vec3 use_normal = normalize(mix(n1, n2, 0.5).xyz);
|
||||
|
||||
if (p1.w == 0 && p2.w == 0)
|
||||
return;
|
||||
|
||||
vec4 edge_mask = texelFetch(edge_mask_tex, ivec2(gl_in[0].gl_Position.xy), 0);
|
||||
|
||||
int is_crease = 0;
|
||||
|
||||
float th = line_thickness;
|
||||
if (normal_mode == 0) {
|
||||
th = line_thickness;
|
||||
}
|
||||
else if (normal_mode == 1) {
|
||||
float factor = dot(use_normal, normal_direction);
|
||||
th = factor_to_thickness(factor);
|
||||
}
|
||||
else if (normal_mode == 2) {
|
||||
float factor = dot(use_normal, normal_direction);
|
||||
th = factor_to_thickness(factor);
|
||||
}
|
||||
|
||||
if (edge_mask.g > 0) {
|
||||
use_color = edge_mark_color;
|
||||
use_thickness = th * line_thickness_edge_mark;
|
||||
}
|
||||
else if (edge_mask.r > 0) {
|
||||
use_color = material_color;
|
||||
use_thickness = th * line_thickness_material;
|
||||
}
|
||||
else if (edge_mask.b > 0) {
|
||||
use_color = intersection_color;
|
||||
use_thickness = th * line_thickness_intersection;
|
||||
}
|
||||
else if (p2.w != p1.w) {
|
||||
use_color = crease_color;
|
||||
use_thickness = th * line_thickness_crease;
|
||||
is_crease = 1;
|
||||
}
|
||||
else {
|
||||
use_color = contour_color;
|
||||
use_thickness = th * line_thickness_contour;
|
||||
}
|
||||
|
||||
draw_line(p1, p2, is_crease);
|
||||
}
|
@@ -0,0 +1,495 @@
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 ViewMatrixInverse;
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 ProjectionMatrixInverse;
|
||||
|
||||
uniform int use_contour;
|
||||
uniform int use_crease;
|
||||
uniform int use_material;
|
||||
uniform int use_edge_mark;
|
||||
uniform int use_intersection;
|
||||
|
||||
uniform float crease_threshold;
|
||||
uniform float crease_fade_threshold;
|
||||
|
||||
uniform int is_perspective; // persp and orth use different crease line determin method
|
||||
|
||||
// uniform float sample_step; // length calculation unused now.
|
||||
// uniform int buffer_width;
|
||||
|
||||
uniform vec4 viewport;
|
||||
|
||||
uniform sampler2D vert0_tex;
|
||||
uniform sampler2D vert1_tex;
|
||||
uniform sampler2D face_normal0_tex;
|
||||
uniform sampler2D face_normal1_tex;
|
||||
uniform sampler2D edge_mask_tex;
|
||||
|
||||
// uniform sampler2D TexSample4;
|
||||
//#define path_start_end_ptrs TexSample4 // edge adjacent data
|
||||
|
||||
// calculate in shader
|
||||
|
||||
vec3 view_pos;
|
||||
vec3 view_dir;
|
||||
|
||||
int is_crease; // we calculate crease in GPU because it's faster and we have normal data anyway.
|
||||
// and we need to indicate crease test success result using p1.w==1 && p2.w==0
|
||||
|
||||
float crease_strength;
|
||||
|
||||
// these are for adapting argument names...
|
||||
#define modelview (ViewMatrix * ModelMatrix)
|
||||
#define projection ProjectionMatrix
|
||||
#define inverse_projection ProjectionMatrixInverse
|
||||
|
||||
// ivec2 getTexturePix(vec2 fb_coord){
|
||||
// vec2 n = ((fb_coord+vec2(1,1))/2).xy;
|
||||
// return ivec2(n.x*buffer_width,n.y*buffer_width);
|
||||
//}
|
||||
|
||||
// Amount of padding around a segment in the segment atlas.
|
||||
// The amount of padding rolls off to zero for short segments,
|
||||
// and is zero for segments in the middle of paths.
|
||||
|
||||
vec2 segmentPadding(float num_samples, float index, float start_index, float end_index)
|
||||
{
|
||||
const float MAX_PADDING = 10.0;
|
||||
|
||||
float amount = floor(clamp((num_samples - 2.0) * 0.5, 0.0, MAX_PADDING));
|
||||
|
||||
float left = amount * max(1.0 + start_index - index, 0.0);
|
||||
float right = amount * max(1.0 + index - end_index, 0.0);
|
||||
|
||||
return vec2(left, right);
|
||||
}
|
||||
|
||||
// Converting from linear indices to 2D coordinates and back:
|
||||
|
||||
float coordinateToIndex(vec2 coord, float buf_size)
|
||||
{
|
||||
vec2 floor_coord = floor(coord);
|
||||
return floor_coord.x + floor_coord.y * buf_size;
|
||||
}
|
||||
|
||||
vec2 indexToCoordinate(float index, float buf_size)
|
||||
{
|
||||
return vec2(mod(index, buf_size), floor(index / buf_size));
|
||||
}
|
||||
|
||||
// Packing and unpacking values in the segment atlas offset texture:
|
||||
|
||||
float unpackNumSamples(vec4 offset_texel)
|
||||
{
|
||||
return offset_texel.b;
|
||||
}
|
||||
|
||||
float unpackArcLength(vec4 offset_texel)
|
||||
{
|
||||
return offset_texel.a;
|
||||
}
|
||||
|
||||
float unpackSampleOffset(vec4 offset_texel)
|
||||
{
|
||||
return offset_texel.r;
|
||||
}
|
||||
|
||||
float unpackArcLengthOffset(vec4 offset_texel)
|
||||
{
|
||||
return offset_texel.g;
|
||||
}
|
||||
|
||||
vec4 packOffsetTexel(float num_samples, float arc_length)
|
||||
{
|
||||
return vec4(num_samples, arc_length, num_samples, arc_length);
|
||||
}
|
||||
|
||||
vec4 packOffsetTexel(float num_samples,
|
||||
float arc_length,
|
||||
float num_samples_offset,
|
||||
float arc_length_offset)
|
||||
{
|
||||
return vec4(num_samples_offset, arc_length_offset, num_samples, arc_length);
|
||||
}
|
||||
|
||||
// Packing and unpacking values in the 3D vertex positions:
|
||||
|
||||
float unpackPathStart(vec4 texel)
|
||||
{
|
||||
return texel.r;
|
||||
}
|
||||
|
||||
float unpackPathEnd(vec4 texel)
|
||||
{
|
||||
return texel.g;
|
||||
}
|
||||
|
||||
float unpackPathLength(vec4 texel)
|
||||
{
|
||||
return texel.b;
|
||||
}
|
||||
|
||||
// Projecting and unprojecting:
|
||||
|
||||
vec2 clipToWindow(sampler2D clip_positions, vec4 viewport, ivec2 coordinate)
|
||||
{
|
||||
vec4 clip = texelFetch(clip_positions, coordinate, 0);
|
||||
vec3 post_div = clip.xyz / clip.w;
|
||||
return (post_div.xy + vec2(1.0, 1.0)) * 0.5 * viewport.zw;
|
||||
}
|
||||
|
||||
vec2 clipToWindow(vec4 clip, vec4 viewport)
|
||||
{
|
||||
vec3 post_div = clip.xyz / clip.w;
|
||||
return (post_div.xy + vec2(1.0, 1.0)) * 0.5 * viewport.zw;
|
||||
}
|
||||
|
||||
// Path id encoding and decoding.
|
||||
|
||||
bool idEqualGreaterThan(vec3 a, vec3 b)
|
||||
{
|
||||
float ida = a.b * 256.0 * 256.0 + a.g * 256.0 + a.r;
|
||||
float idb = b.b * 256.0 * 256.0 + b.g * 256.0 + b.r;
|
||||
const float small = 0.001;
|
||||
return ida - idb > -small;
|
||||
}
|
||||
|
||||
bool idsEqual(vec3 a, vec3 b)
|
||||
{
|
||||
float ida = a.b * 256.0 * 256.0 + a.g * 256.0 + a.r;
|
||||
float idb = b.b * 256.0 * 256.0 + b.g * 256.0 + b.r;
|
||||
const float small = 0.001;
|
||||
return abs(ida - idb) < small;
|
||||
}
|
||||
|
||||
vec3 idToColor(float id)
|
||||
{
|
||||
id = id + 1.0;
|
||||
float blue = floor(id / (256.0 * 256.0));
|
||||
float green = floor(id / 256.0) - blue * 256.0;
|
||||
float red = id - green * 256.0 - blue * 256.0 * 256.0;
|
||||
return vec3(red, green, blue) / 255.0;
|
||||
}
|
||||
|
||||
struct segment {
|
||||
vec3 p1;
|
||||
vec3 p2;
|
||||
bool on_screen;
|
||||
};
|
||||
|
||||
float epsilon = 0.00001;
|
||||
float xmin = -1.1;
|
||||
float xmax = 1.1;
|
||||
float ymin = -1.1;
|
||||
float ymax = 1.1;
|
||||
|
||||
// this is a conservative offscreen rejection test ... catches most cases
|
||||
bool segmentOffScreen(vec3 p0, vec3 p1)
|
||||
{
|
||||
return ((p0[0] < xmin && p1[0] < xmin) || (p0[0] > xmax && p1[0] > xmax) ||
|
||||
(p0[1] < ymin && p1[1] < ymin) || (p0[1] > ymax && p1[1] > ymax));
|
||||
}
|
||||
|
||||
bool pointOffScreen(vec3 p)
|
||||
{
|
||||
return (p[0] < xmin || p[0] > xmax || p[1] < ymin || p[1] > ymax);
|
||||
}
|
||||
|
||||
vec3 clipMinMaxX(vec3 outv, vec3 inv)
|
||||
{
|
||||
vec3 ret = outv;
|
||||
if (outv.x < xmin) {
|
||||
float t = (xmin - outv.x) / (inv.x - outv.x);
|
||||
ret = t * inv + (1.0 - t) * outv;
|
||||
}
|
||||
else if (outv.x > xmax) {
|
||||
float t = (xmax - inv.x) / (outv.x - inv.x);
|
||||
ret = t * outv + (1.0 - t) * inv;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
vec3 clipMinMaxY(vec3 outv, vec3 inv)
|
||||
{
|
||||
vec3 ret = outv;
|
||||
if (outv.y < ymin) {
|
||||
float t = (ymin - outv.y) / (inv.y - outv.y);
|
||||
ret = t * inv + (1.0 - t) * outv;
|
||||
}
|
||||
else if (outv.y > ymax) {
|
||||
float t = (ymax - inv.y) / (outv.y - inv.y);
|
||||
ret = t * outv + (1.0 - t) * inv;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
vec3 clipSegmentOneOut(vec3 off_screen, vec3 on_screen)
|
||||
{
|
||||
vec3 outv = off_screen;
|
||||
|
||||
// first clip against the x coords
|
||||
outv = clipMinMaxX(outv, on_screen);
|
||||
|
||||
// now clip against the y coords using the newly clipped point
|
||||
outv = clipMinMaxY(outv, on_screen);
|
||||
|
||||
return outv;
|
||||
}
|
||||
|
||||
segment clipToMin(float min, segment inseg, float p1val, float p2val)
|
||||
{
|
||||
float minPos = min + epsilon;
|
||||
float minNeg = min - epsilon;
|
||||
segment outseg = segment(inseg.p1, inseg.p2, inseg.on_screen);
|
||||
|
||||
// trivial reject
|
||||
if ((p1val < minPos && p2val < minPos) || inseg.on_screen == false) {
|
||||
outseg.on_screen = false;
|
||||
}
|
||||
|
||||
// cut at min
|
||||
if (p1val < minPos) {
|
||||
float t = (min - p1val) / (p2val - p1val);
|
||||
outseg.p1 = t * inseg.p2 + (1.0 - t) * inseg.p1;
|
||||
}
|
||||
else if (p2val < minPos) {
|
||||
float t = (min - p2val) / (p1val - p2val);
|
||||
outseg.p2 = t * inseg.p1 + (1.0 - t) * inseg.p2;
|
||||
}
|
||||
return outseg;
|
||||
}
|
||||
|
||||
segment clipToMax(float max, segment inseg, float p1val, float p2val)
|
||||
{
|
||||
float maxPos = max + epsilon;
|
||||
float maxNeg = max - epsilon;
|
||||
segment outseg = segment(inseg.p1, inseg.p2, inseg.on_screen);
|
||||
|
||||
// trivial reject
|
||||
if ((p1val > maxNeg && p2val > maxNeg) || inseg.on_screen == false) {
|
||||
outseg.on_screen = false;
|
||||
}
|
||||
|
||||
// cut at max
|
||||
if (p1val > maxNeg) {
|
||||
float t = (max - p2val) / (p1val - p2val);
|
||||
outseg.p1 = t * inseg.p1 + (1.0 - t) * inseg.p2;
|
||||
}
|
||||
else if (p2val > maxNeg) {
|
||||
float t = (max - p1val) / (p2val - p1val);
|
||||
outseg.p2 = t * inseg.p2 + (1.0 - t) * inseg.p1;
|
||||
}
|
||||
return outseg;
|
||||
}
|
||||
|
||||
segment clipSegmentBothOut(vec3 p1, vec3 p2)
|
||||
{
|
||||
segment seg = segment(p1, p2, true);
|
||||
|
||||
seg = clipToMin(xmin, seg, seg.p1.x, seg.p2.x);
|
||||
seg = clipToMax(xmax, seg, seg.p1.x, seg.p2.x);
|
||||
seg = clipToMin(ymin, seg, seg.p1.y, seg.p2.y);
|
||||
seg = clipToMax(ymax, seg, seg.p1.y, seg.p2.y);
|
||||
|
||||
return seg;
|
||||
}
|
||||
|
||||
vec3 clipSegmentToNear(vec3 off_screen, vec3 on_screen)
|
||||
{
|
||||
// see http://members.tripod.com/~Paul_Kirby/vector/Vplanelineint.html
|
||||
|
||||
vec3 a = off_screen;
|
||||
vec3 b = on_screen;
|
||||
vec3 c = view_pos + view_dir;
|
||||
vec3 n = view_dir;
|
||||
float t = dot((c - a), n) / dot((b - a), n);
|
||||
|
||||
vec3 clipped = a + (b - a) * t;
|
||||
return clipped;
|
||||
}
|
||||
|
||||
bool pointBeyondNear(vec3 p)
|
||||
{
|
||||
vec3 offset = p - view_pos;
|
||||
bool beyond = dot(offset, view_dir) > 0.0;
|
||||
return beyond;
|
||||
}
|
||||
|
||||
// 1 for contour 2 for others
|
||||
int testProfileEdge(ivec2 texcoord, vec3 world_position)
|
||||
{
|
||||
// This should really be the inverse transpose of the modelview matrix, but
|
||||
// that only matters if the camera has a weird anisotropic scale or skew.
|
||||
|
||||
mat3 nm = mat3(transpose(inverse(ModelMatrix)));
|
||||
vec3 face_normal_0 = mat3(nm) * texelFetch(face_normal0_tex, texcoord, 0).xyz;
|
||||
vec3 face_normal_1 = mat3(nm) * texelFetch(face_normal1_tex, texcoord, 0).xyz;
|
||||
vec3 camera_to_line = is_perspective == 1 ? world_position - view_pos :
|
||||
view_dir; // modelview * vec4(world_position, 1.0);
|
||||
|
||||
vec4 edge_mask = texelFetch(edge_mask_tex, texcoord, 0);
|
||||
|
||||
float dot0 = dot(camera_to_line.xyz, vec3(face_normal_0.xyz));
|
||||
float dot1 = dot(camera_to_line.xyz, vec3(face_normal_1.xyz));
|
||||
float dot2 = dot(normalize(vec3(face_normal_0.xyz)), normalize(vec3(face_normal_1.xyz)));
|
||||
|
||||
bool contour = (dot0 >= 0.0 && dot1 <= 0.0) || (dot0 <= 0.0 && dot1 >= 0.0);
|
||||
|
||||
is_crease = (((use_contour > 0 && !contour) || use_contour == 0) &&
|
||||
((dot2 < crease_threshold) || (dot2 < crease_fade_threshold))) ?
|
||||
1 :
|
||||
0;
|
||||
|
||||
crease_strength = (is_crease > 0 && dot2 > crease_threshold) ?
|
||||
((dot2 - crease_threshold) / (crease_fade_threshold - crease_threshold) /
|
||||
2) :
|
||||
0;
|
||||
// use 0 to 0.5 to repesent the range, because 1 will represent another meaning
|
||||
|
||||
if (use_contour > 0 && contour)
|
||||
return 1;
|
||||
if (((use_crease > 0) && (is_crease > 0)) || ((use_material > 0) && (edge_mask.r > 0)) ||
|
||||
((use_edge_mark > 0) && (edge_mask.g > 0)) ||
|
||||
((use_intersection > 0) && (edge_mask.b > 0)) || false)
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
view_dir = -mat3(ViewMatrixInverse) * vec3(0, 0, 1);
|
||||
view_pos = (ViewMatrixInverse)[3].xyz;
|
||||
|
||||
xmin *= viewport.z / viewport.w;
|
||||
xmax *= viewport.z / viewport.w;
|
||||
|
||||
// look up the world positions of the segment vertices
|
||||
ivec2 texcoord = ivec2(gl_FragCoord.xy);
|
||||
|
||||
vec4 v0_world_pos = texelFetch(vert0_tex, texcoord, 0);
|
||||
vec4 v1_world_pos = texelFetch(vert1_tex, texcoord, 0);
|
||||
v0_world_pos = ModelMatrix * vec4(v0_world_pos.xyz, 1);
|
||||
v1_world_pos = ModelMatrix * vec4(v1_world_pos.xyz, 1);
|
||||
|
||||
// early exit if there are no vertices here to process
|
||||
if (v0_world_pos.w < 0.5) {
|
||||
// no vertex data to process
|
||||
gl_FragData[0] = vec4(0.5, 0.0, 0.0, 0.0);
|
||||
gl_FragData[1] = vec4(0.5, 0.5, 0.0, 0.0);
|
||||
// must write something into fragdata[2] to prevent
|
||||
// buffer 2 from getting filled with garbage? (very weird)
|
||||
gl_FragData[2] = vec4(0.0, 1.0, 0.0, 0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 v0_clipped_near = v0_world_pos.xyz;
|
||||
vec3 v1_clipped_near = v1_world_pos.xyz;
|
||||
|
||||
if (is_perspective == 1) {
|
||||
// clip to the near plane
|
||||
bool v0_beyond_near = pointBeyondNear(v0_world_pos.xyz);
|
||||
bool v1_beyond_near = pointBeyondNear(v1_world_pos.xyz);
|
||||
|
||||
if (!v0_beyond_near && !v1_beyond_near) {
|
||||
// segment entirely behind the camera
|
||||
gl_FragData[0] = vec4(0.0, 1.0, 0.0, 0.0);
|
||||
gl_FragData[1] = vec4(0.0, 0.0, 1.0, 0.0);
|
||||
gl_FragData[2] = vec4(0.0, 1.0, 0.0, 0.0);
|
||||
return;
|
||||
}
|
||||
else if (!v0_beyond_near) {
|
||||
v0_clipped_near = clipSegmentToNear(v0_world_pos.xyz, v1_clipped_near);
|
||||
}
|
||||
else if (!v1_beyond_near) {
|
||||
v1_clipped_near = clipSegmentToNear(v1_world_pos.xyz, v0_clipped_near);
|
||||
}
|
||||
}
|
||||
|
||||
// If this segment is a profile edge, test to see if it should be turned on.
|
||||
// if (v1_world_pos.w > 0.5)
|
||||
//{
|
||||
int profile_on = testProfileEdge(texcoord, v0_clipped_near);
|
||||
if (profile_on == 0) {
|
||||
// Profile edge should be off.
|
||||
gl_FragData[0] = vec4(0.0, 1.0, 0.5, 0.0);
|
||||
gl_FragData[1] = vec4(0.0, 0.5, 1.0, 0.0);
|
||||
gl_FragData[2] = vec4(0.0, 1.0, 0.0, 0.0);
|
||||
return;
|
||||
}
|
||||
//}
|
||||
|
||||
// project
|
||||
vec4 v0_pre_div = projection * ViewMatrix * vec4(v0_clipped_near, 1.0);
|
||||
vec4 v1_pre_div = projection * ViewMatrix * vec4(v1_clipped_near, 1.0);
|
||||
|
||||
// perspective divide
|
||||
vec3 v0_clip_pos = v0_pre_div.xyz;
|
||||
vec3 v1_clip_pos = v1_pre_div.xyz;
|
||||
if (is_perspective == 1) {
|
||||
v0_clip_pos /= v0_pre_div.w;
|
||||
v1_clip_pos /= v1_pre_div.w;
|
||||
}
|
||||
// clip to frustum
|
||||
bool v0_on_screen = !pointOffScreen(v0_clip_pos);
|
||||
bool v1_on_screen = !pointOffScreen(v1_clip_pos);
|
||||
|
||||
if (!v0_on_screen && !v1_on_screen) {
|
||||
segment ret = clipSegmentBothOut(v0_clip_pos, v1_clip_pos);
|
||||
if (ret.on_screen == false) {
|
||||
// segment entirely off screen: BLUE / MAGENTA / BLACK
|
||||
gl_FragData[0] = vec4(0.0, 0.0, 1.0, 0.0);
|
||||
gl_FragData[1] = vec4(1.0, 0.0, 1.0, 0.0);
|
||||
gl_FragData[2] = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
return;
|
||||
}
|
||||
v0_clip_pos = ret.p1;
|
||||
v1_clip_pos = ret.p2;
|
||||
}
|
||||
else if (!v0_on_screen) {
|
||||
v0_clip_pos = clipSegmentOneOut(v0_clip_pos, v1_clip_pos);
|
||||
}
|
||||
else if (!v1_on_screen) {
|
||||
v1_clip_pos = clipSegmentOneOut(v1_clip_pos, v0_clip_pos);
|
||||
}
|
||||
|
||||
// convert to window coordinates
|
||||
vec2 v0_screen = (v0_clip_pos.xy + vec2(1.0, 1.0)) * 0.5 * viewport.zw;
|
||||
vec2 v1_screen = (v1_clip_pos.xy + vec2(1.0, 1.0)) * 0.5 * viewport.zw;
|
||||
|
||||
// if(v1_screen == v0_screen){ gl_FragData[0] = vec4(1,0,0,1); return; }
|
||||
|
||||
float segment_screen_length = length(v0_screen - v1_screen);
|
||||
|
||||
// scale the length by sample_step to get the number of samples
|
||||
// float num_samples = segment_screen_length / sample_step;
|
||||
// num_samples = ceil(num_samples);
|
||||
|
||||
// Unproject and reproject the final clipped positions
|
||||
// so that interpolation is perspective correct later on.
|
||||
vec4 v0_world = inverse_projection * vec4(v0_clip_pos, 1.0);
|
||||
vec4 v1_world = inverse_projection * vec4(v1_clip_pos, 1.0);
|
||||
vec4 v0_clipped_pre_div = projection * v0_world;
|
||||
vec4 v1_clipped_pre_div = projection * v1_world;
|
||||
|
||||
// Add some padding to the number of samples so that filters
|
||||
// that work along the segment length (such as overshoot)
|
||||
// have some room to work with at the end of each segment.
|
||||
// vec4 path_texel = texelFetch(path_start_end_ptrs, texcoord,0);
|
||||
// vec2 padding = segmentPadding(num_samples,
|
||||
// coordinateToIndex(texcoord, buffer_width),
|
||||
// unpackPathStart(path_texel),
|
||||
// unpackPathEnd(path_texel));
|
||||
// float total_padding = padding.x + padding.y;
|
||||
|
||||
// if(v0_clipped_pre_div == v1_clipped_pre_div)gl_FragData[0] =vec4(1);
|
||||
// else gl_FragData[0] = vec4(v0_clipped_pre_div.xyz,1);
|
||||
|
||||
gl_FragData[0] = vec4(v0_clipped_pre_div.xyz,
|
||||
1); // contour has priority, modification cause trouble
|
||||
gl_FragData[1] = vec4(v1_clipped_pre_div.xyz, is_crease > 0 ? crease_strength : 1);
|
||||
// gl_FragData[2] = packOffsetTexel(num_samples, segment_screen_length,
|
||||
// num_samples, segment_screen_length);
|
||||
// num_samples + total_padding, segment_screen_length);
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
in vec4 pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = pos;
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
in vec4 uvcoordsvar;
|
||||
uniform sampler2DMS tex_sampe_0; // depth
|
||||
uniform sampler2DMS tex_sample_1; // color
|
||||
uniform sampler2DMS tex_sample_2; // normal
|
||||
uniform float normal_clamp; // normal clamp
|
||||
uniform float normal_strength; // normal strength
|
||||
uniform float depth_clamp; // depth clamp
|
||||
uniform float depth_strength; // depth strength
|
||||
uniform float z_near; // z_near
|
||||
uniform float z_far; // z_far
|
||||
|
||||
mat3 sx = mat3(1.0, 2.0, 1.0, 0.0, 0.0, 0.0, -1.0, -2.0, -1.0);
|
||||
mat3 sy = mat3(1.0, 0.0, -1.0, 2.0, 0.0, -2.0, 1.0, 0.0, -1.0);
|
||||
vec3 rgb2hsv(vec3 c)
|
||||
{
|
||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
float linearDepth(float depthSample)
|
||||
{
|
||||
float d = 2.0 * depthSample - 1.0;
|
||||
float zLinear = 2.0 * z_near * z_far / (z_far + z_near - d * (z_far - z_near));
|
||||
return zLinear;
|
||||
}
|
||||
|
||||
vec4 DetectEdge(sampler2DMS tex, float clamp, float strength)
|
||||
{
|
||||
mat3 I = mat3(0);
|
||||
mat3 J = mat3(0);
|
||||
mat3 K = mat3(0);
|
||||
|
||||
ivec2 texSize = textureSize(tex);
|
||||
ivec2 sp = ivec2(uvcoordsvar.xy * texSize);
|
||||
vec4 cs = vec4(0);
|
||||
|
||||
// sample hardcoded (8) now
|
||||
for (int s = 0; s < 8; s++) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
vec4 col = texelFetch(tex, sp + ivec2(i - 1, j - 1), s);
|
||||
vec3 sample1 = vec3((col.r));
|
||||
vec3 sample2 = vec3((col.g));
|
||||
vec3 sample3 = vec3((col.b));
|
||||
I[i][j] += length(sample1) / 8;
|
||||
J[i][j] += length(sample2) / 8;
|
||||
K[i][j] += length(sample3) / 8;
|
||||
}
|
||||
}
|
||||
cs += texelFetch(tex_sample_1, sp, s) / 8;
|
||||
}
|
||||
|
||||
float gx1 = dot(sx[0], I[0]) + dot(sx[1], I[1]) + dot(sx[2], I[2]);
|
||||
float gy1 = dot(sy[0], I[0]) + dot(sy[1], I[1]) + dot(sy[2], I[2]);
|
||||
float g1 = sqrt(pow(gx1, 2.0) + pow(gy1, 2.0));
|
||||
|
||||
float gx2 = dot(sx[0], J[0]) + dot(sx[1], J[1]) + dot(sx[2], J[2]);
|
||||
float gy2 = dot(sy[0], J[0]) + dot(sy[1], J[1]) + dot(sy[2], J[2]);
|
||||
float g2 = sqrt(pow(gx2, 2.0) + pow(gy2, 2.0));
|
||||
|
||||
float gx3 = dot(sx[0], K[0]) + dot(sx[1], K[1]) + dot(sx[2], K[2]);
|
||||
float gy3 = dot(sy[0], K[0]) + dot(sy[1], K[1]) + dot(sy[2], K[2]);
|
||||
float g3 = sqrt(pow(gx3, 2.0) + pow(gy3, 2.0));
|
||||
|
||||
float value = max(max(g1, g2), g3);
|
||||
|
||||
value = value > clamp ? value : 0;
|
||||
return vec4(vec3(value * strength), 1);
|
||||
|
||||
// if(value<clamp) value=0;
|
||||
|
||||
// return vec4(pow(value,strength));
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
float nc = normal_clamp; //(normal_clamp==0? 0.01:normal_clamp);
|
||||
float ns = normal_strength; //(normal_strength==0? 5: normal_strength);
|
||||
float dc = depth_clamp; //(depth_clamp==0? 0.2: depth_clamp);
|
||||
float ds = depth_strength; //(depth_strength==0? 2.5: depth_strength);
|
||||
|
||||
vec4 diffuse = vec4(1, 1, 1, 1);
|
||||
vec4 color = (DetectEdge(tex_sampe_0, dc, ds) + DetectEdge(tex_sample_2, nc, ns));
|
||||
gl_FragColor = color;
|
||||
};
|
@@ -0,0 +1,329 @@
|
||||
|
||||
in vec4 uvcoordsvar;
|
||||
uniform sampler2D tex_sample_0;
|
||||
uniform int stage;
|
||||
|
||||
int decisions[256] = int[](0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
|
||||
int PickPixel(ivec2 sp)
|
||||
{
|
||||
vec4 accum = vec4(0);
|
||||
// for(int i=0;i<4;i++){
|
||||
accum += texelFetch(tex_sample_0, sp, 0);
|
||||
//}
|
||||
return (accum.r > 0.9) ? 1 : 0;
|
||||
}
|
||||
|
||||
// MZS Thinning method, implemented by YimingWu
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
ivec2 texSize = textureSize(tex_sample_0, 0);
|
||||
ivec2 sp = ivec2(uvcoordsvar.xy * texSize);
|
||||
vec4 OriginalColor = texelFetch(tex_sample_0, sp, 0);
|
||||
|
||||
int p2 = PickPixel(sp + ivec2(0, +1));
|
||||
int p3 = PickPixel(sp + ivec2(+1, +1));
|
||||
int p4 = PickPixel(sp + ivec2(+1, 0));
|
||||
int p5 = PickPixel(sp + ivec2(+1, -1));
|
||||
int p6 = PickPixel(sp + ivec2(0, -1));
|
||||
int p7 = PickPixel(sp + ivec2(-1, -1));
|
||||
int p8 = PickPixel(sp + ivec2(-1, 0));
|
||||
int p9 = PickPixel(sp + ivec2(-1, +1));
|
||||
|
||||
int Bp1 = p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9;
|
||||
|
||||
bool bp2 = bool(p2);
|
||||
bool bp3 = bool(p3);
|
||||
bool bp4 = bool(p4);
|
||||
bool bp5 = bool(p5);
|
||||
bool bp6 = bool(p6);
|
||||
bool bp7 = bool(p7);
|
||||
bool bp8 = bool(p8);
|
||||
bool bp9 = bool(p9);
|
||||
|
||||
int Cp1 = int(!bp2 && (bp3 || bp4)) + int(!bp4 && (bp5 || bp6)) + int(!bp6 && (bp7 || bp8)) +
|
||||
int(!bp8 && (bp9 || bp2));
|
||||
|
||||
if (stage == 0) {
|
||||
if (((sp.x + sp.y) % 2 == 0) && (Cp1 == 1) && (Bp1 >= 2 && Bp1 <= 7) && (p2 * p4 * p6 == 0) &&
|
||||
(p4 * p6 * p8 == 0)) {
|
||||
gl_FragColor = vec4(0, 0, 0, 1);
|
||||
return;
|
||||
}
|
||||
gl_FragColor = OriginalColor;
|
||||
}
|
||||
else {
|
||||
if (((sp.x + sp.y) % 2 != 0) && (Cp1 == 1) && (Bp1 >= 1 && Bp1 <= 7) && (p2 * p4 * p8 == 0) &&
|
||||
(p2 * p6 * p8 == 0)) {
|
||||
gl_FragColor = vec4(0, 0, 0, 1);
|
||||
return;
|
||||
}
|
||||
gl_FragColor = OriginalColor;
|
||||
}
|
||||
|
||||
// int test = PickPixel(sp+ivec2(-1,-1))*1 + PickPixel(sp+ivec2(0 ,-1))*2 +
|
||||
// PickPixel(sp+ivec2(+1,-1))*4
|
||||
// + PickPixel(sp+ivec2(-1, 0))*8 + PickPixel(sp+ivec2(+1, 0))*16
|
||||
// + PickPixel(sp+ivec2(-1,+1))*32 + PickPixel(sp+ivec2( 0,+1))*64 +
|
||||
// PickPixel(sp+ivec2(+1,+1))*128;
|
||||
|
||||
// if(decisions[test]==1) gl_FragColor=vec4(1,0,0,1);
|
||||
// else gl_FragColor=texelFetch(tex_sample_0, sp, 0);//vec4(1,1,1,1);
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
uniform vec4 line_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = line_color;
|
||||
}
|
@@ -0,0 +1,114 @@
|
||||
layout(lines_adjacency) in;
|
||||
layout(triangle_strip, max_vertices = 6) out;
|
||||
|
||||
in vec2 gOffset[];
|
||||
|
||||
uniform float line_width;
|
||||
uniform float taper_l_dist;
|
||||
uniform float taper_r_dist;
|
||||
uniform float taper_l_strength;
|
||||
uniform float taper_r_strength;
|
||||
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
|
||||
vec4 MakeLeftTaperLinear(vec4 L, vec4 a, float offset)
|
||||
{
|
||||
if (offset >= taper_l_dist)
|
||||
return a;
|
||||
a = mix(mix(a, L, taper_l_strength), a, offset / taper_l_dist);
|
||||
return a;
|
||||
}
|
||||
|
||||
vec4 MakeRightTaperLinear(vec4 R, vec4 c, float offset)
|
||||
{
|
||||
if (offset >= taper_r_dist)
|
||||
return c;
|
||||
c = mix(mix(c, R, taper_r_strength), c, offset / taper_r_dist);
|
||||
return c;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
float LAngle, RAngle;
|
||||
|
||||
vec4 LL = gl_in[0].gl_Position, L = gl_in[1].gl_Position, R = gl_in[2].gl_Position,
|
||||
RR = gl_in[3].gl_Position;
|
||||
|
||||
float OffsetL = gOffset[1].x;
|
||||
float OffsetR = gOffset[2].x;
|
||||
float OffsetL2 = gOffset[1].y;
|
||||
float OffsetR2 = gOffset[2].y;
|
||||
|
||||
if (L == R || L == LL || R == RR || LL == RR || L == RR || R == LL)
|
||||
return;
|
||||
|
||||
vec4 a;
|
||||
vec4 b;
|
||||
vec4 c;
|
||||
vec4 d;
|
||||
vec4 Line = R - L;
|
||||
vec4 Normal = normalize(vec4(-Line.y, Line.x, 0, 0));
|
||||
|
||||
a = L - line_width * Normal * 0.001;
|
||||
b = L + line_width * Normal * 0.001;
|
||||
c = R - line_width * Normal * 0.001;
|
||||
d = R + line_width * Normal * 0.001;
|
||||
|
||||
float lim = line_width * 0.002;
|
||||
|
||||
{
|
||||
vec4 Tangent = normalize(normalize(L - LL) + normalize(R - L));
|
||||
vec4 Minter = normalize(vec4(-Tangent.y, Tangent.x, 0, 0));
|
||||
float length = line_width / (dot(Minter, Normal)) * 0.001;
|
||||
a = L - length * Minter;
|
||||
b = L + length * Minter;
|
||||
if (distance(a, b) > 2 * lim) {
|
||||
a = L - lim * Minter;
|
||||
b = L + lim * Minter;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
vec4 Tangent = normalize(normalize(RR - R) + normalize(R - L));
|
||||
vec4 Minter = normalize(vec4(-Tangent.y, Tangent.x, 0, 0));
|
||||
float length = line_width / (dot(Minter, Normal)) * 0.001;
|
||||
c = R - length * Minter;
|
||||
d = R + length * Minter;
|
||||
if (distance(c, d) > 2 * lim) {
|
||||
c = R - lim * Minter;
|
||||
d = R + lim * Minter;
|
||||
}
|
||||
}
|
||||
|
||||
a = MakeLeftTaperLinear(L, a, OffsetL);
|
||||
b = MakeLeftTaperLinear(L, b, OffsetL);
|
||||
c = MakeLeftTaperLinear(R, c, OffsetR);
|
||||
d = MakeLeftTaperLinear(R, d, OffsetR);
|
||||
|
||||
a = MakeRightTaperLinear(L, a, OffsetL2);
|
||||
b = MakeRightTaperLinear(L, b, OffsetL2);
|
||||
c = MakeRightTaperLinear(R, c, OffsetR2);
|
||||
d = MakeRightTaperLinear(R, d, OffsetR2);
|
||||
|
||||
a.w = 1;
|
||||
b.w = 1;
|
||||
c.w = 1;
|
||||
d.w = 1;
|
||||
|
||||
gl_Position = a;
|
||||
EmitVertex();
|
||||
gl_Position = b;
|
||||
EmitVertex();
|
||||
gl_Position = c;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
|
||||
gl_Position = c;
|
||||
EmitVertex();
|
||||
gl_Position = d;
|
||||
EmitVertex();
|
||||
gl_Position = b;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
in vec2 pos;
|
||||
in vec2 uvs;
|
||||
|
||||
out vec2 gOffset;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(pos, 0.0, 1.0);
|
||||
gOffset = uvs;
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
in vec3 normal;
|
||||
in vec4 finalColor;
|
||||
|
||||
float Interpolate(float between1, float between2, float value1, float value2, float key)
|
||||
{
|
||||
float i = (key - between1) / (between2 - between1);
|
||||
return value1 * (1 - i) + value2 * i;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
float value = dot(vec3(0, 0, 1), normal);
|
||||
// if(value<0.65) value=0.15;
|
||||
// else if(value>=0.65 && value<0.85) value=Interpolate(0.65,0.85,0.15,0.75,value);
|
||||
// else if(value>=0.85 && value<0.95) value=0.75;
|
||||
// else if(value>=0.95) value=0.9;
|
||||
gl_FragData[0] = vec4(finalColor.rgb * value, 1);
|
||||
gl_FragData[1] = vec4(normal, 1); // vec4((normal+vec3(1))*0.5,1);
|
||||
}
|
@@ -0,0 +1,291 @@
|
||||
layout(lines_adjacency) in;
|
||||
layout(triangle_strip, max_vertices = 6) out;
|
||||
|
||||
in vec2 gOffset[];
|
||||
in int gType[];
|
||||
in int gLevel[];
|
||||
|
||||
in vec3 gNormal[];
|
||||
uniform int normal_mode;
|
||||
uniform int normal_effect_inverse;
|
||||
uniform vec3 normal_direction; // also used as point position
|
||||
uniform float normal_ramp_begin;
|
||||
uniform float normal_ramp_end;
|
||||
uniform float normal_thickness_start;
|
||||
uniform float normal_thickness_end;
|
||||
|
||||
uniform float thickness;
|
||||
uniform float thickness_contour;
|
||||
uniform float thickness_crease;
|
||||
uniform float thickness_material;
|
||||
uniform float thickness_edge_mark;
|
||||
uniform float thickness_intersection;
|
||||
|
||||
uniform int use_contour;
|
||||
uniform int use_crease;
|
||||
uniform int use_material;
|
||||
uniform int use_edge_mark;
|
||||
uniform int use_intersection;
|
||||
|
||||
uniform int occlusion_level_start;
|
||||
uniform int occlusion_level_end;
|
||||
|
||||
// implement these later.
|
||||
// uniform float depth_width_influence;
|
||||
// uniform float depth_width_curve;
|
||||
// uniform float depth_alpha_influence;
|
||||
// uniform float depth_alpha_curve;
|
||||
// uniform float zNear;
|
||||
// uniform float zFar;
|
||||
|
||||
uniform vec4 contour_color;
|
||||
uniform vec4 crease_color;
|
||||
uniform vec4 material_color;
|
||||
uniform vec4 edge_mark_color;
|
||||
uniform vec4 intersection_color;
|
||||
|
||||
uniform float taper_l_dist;
|
||||
uniform float taper_r_dist;
|
||||
uniform float taper_l_strength;
|
||||
uniform float taper_r_strength;
|
||||
|
||||
// for line width correction
|
||||
uniform vec4 output_viewport;
|
||||
uniform vec4 preview_viewport;
|
||||
|
||||
uniform float camdx;
|
||||
uniform float camdy;
|
||||
uniform float camzoom;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
float use_thickness;
|
||||
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
|
||||
vec4 END_POINT = vec4(vec2(3e30f), 0, 1); // end point flag
|
||||
|
||||
vec4 MakeLeftTaperLinear(vec4 L, vec4 a, float offset)
|
||||
{
|
||||
if (offset >= taper_l_dist)
|
||||
return a;
|
||||
a = mix(mix(a, L, taper_l_strength), a, offset / taper_l_dist);
|
||||
return a;
|
||||
}
|
||||
|
||||
vec4 MakeRightTaperLinear(vec4 R, vec4 c, float offset)
|
||||
{
|
||||
if (offset >= taper_r_dist)
|
||||
return c;
|
||||
c = mix(mix(c, R, taper_r_strength), c, offset / taper_r_dist);
|
||||
return c;
|
||||
}
|
||||
|
||||
void draw_line(vec4 LL, vec4 L, vec4 R, vec4 RR)
|
||||
{
|
||||
|
||||
float LAngle, RAngle;
|
||||
|
||||
float OffsetL = gOffset[1].x;
|
||||
float OffsetR = gOffset[2].x;
|
||||
float OffsetL2 = gOffset[1].y;
|
||||
float OffsetR2 = gOffset[2].y;
|
||||
|
||||
if (L == R)
|
||||
return;
|
||||
|
||||
vec4 a;
|
||||
vec4 b;
|
||||
vec4 c;
|
||||
vec4 d;
|
||||
vec4 Line = R - L;
|
||||
vec4 Normal = normalize(vec4(-Line.y, Line.x, 0, 0));
|
||||
|
||||
a = L - use_thickness * Normal * 0.001;
|
||||
b = L + use_thickness * Normal * 0.001;
|
||||
c = R - use_thickness * Normal * 0.001;
|
||||
d = R + use_thickness * Normal * 0.001;
|
||||
|
||||
float lim = use_thickness * 0.002;
|
||||
|
||||
float x_scale = preview_viewport.w / preview_viewport.z;
|
||||
|
||||
if (LL.x < 3e20) {
|
||||
vec4 avg = normalize(L - LL) + normalize(R - L);
|
||||
if (length(avg) > 0.001) {
|
||||
vec4 Tangent = normalize(avg);
|
||||
vec4 Minter = normalize(vec4(-Tangent.y, Tangent.x, 0, 0));
|
||||
float length = use_thickness / (dot(Minter, Normal)) * 0.001;
|
||||
if (length < 4 * lim) {
|
||||
Minter.x *= x_scale;
|
||||
a = L - length * Minter;
|
||||
b = L + length * Minter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (RR.x < 3e20) {
|
||||
vec4 avg = normalize(RR - R) + normalize(R - L);
|
||||
if (length(avg) > 0.001) {
|
||||
vec4 Tangent = normalize(avg);
|
||||
vec4 Minter = normalize(vec4(-Tangent.y, Tangent.x, 0, 0));
|
||||
float length = use_thickness / (dot(Minter, Normal)) * 0.001;
|
||||
if (length < 4 * lim) {
|
||||
Minter.x *= x_scale;
|
||||
c = R - length * Minter;
|
||||
d = R + length * Minter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a = MakeLeftTaperLinear(L, a, OffsetL);
|
||||
b = MakeLeftTaperLinear(L, b, OffsetL);
|
||||
c = MakeLeftTaperLinear(R, c, OffsetR);
|
||||
d = MakeLeftTaperLinear(R, d, OffsetR);
|
||||
|
||||
a = MakeRightTaperLinear(L, a, OffsetL2);
|
||||
b = MakeRightTaperLinear(L, b, OffsetL2);
|
||||
c = MakeRightTaperLinear(R, c, OffsetR2);
|
||||
d = MakeRightTaperLinear(R, d, OffsetR2);
|
||||
|
||||
a.w = 1;
|
||||
b.w = 1;
|
||||
c.w = 1;
|
||||
d.w = 1;
|
||||
|
||||
gl_Position = a;
|
||||
EmitVertex();
|
||||
gl_Position = b;
|
||||
EmitVertex();
|
||||
gl_Position = c;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
|
||||
gl_Position = c;
|
||||
EmitVertex();
|
||||
gl_Position = d;
|
||||
EmitVertex();
|
||||
gl_Position = b;
|
||||
EmitVertex();
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
float factor_to_thickness(float factor)
|
||||
{
|
||||
float r = (factor - normal_ramp_begin) / (normal_ramp_end - normal_ramp_begin);
|
||||
if (r > 1)
|
||||
r = 1;
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
float thickness = normal_effect_inverse == 1 ?
|
||||
mix(normal_thickness_start, normal_thickness_end, r) :
|
||||
mix(normal_thickness_end, normal_thickness_start, r);
|
||||
return thickness;
|
||||
}
|
||||
|
||||
void decide_line_style(int component_id)
|
||||
{
|
||||
float th = thickness;
|
||||
if (normal_mode == 0) {
|
||||
th = thickness;
|
||||
}
|
||||
else if (normal_mode == 1) {
|
||||
float factor = dot(gNormal[0], normal_direction);
|
||||
th = factor_to_thickness(factor);
|
||||
}
|
||||
else if (normal_mode == 2) {
|
||||
float factor = dot(gNormal[0], normal_direction);
|
||||
th = factor_to_thickness(factor);
|
||||
}
|
||||
|
||||
if (component_id == 0) {
|
||||
out_color = contour_color;
|
||||
use_thickness = th * thickness_contour * use_contour;
|
||||
return;
|
||||
}
|
||||
if (component_id == 1) {
|
||||
out_color = crease_color;
|
||||
use_thickness = th * thickness_crease * use_crease;
|
||||
return;
|
||||
}
|
||||
if (component_id == 2) {
|
||||
out_color = material_color;
|
||||
use_thickness = th * thickness_material * use_material;
|
||||
return;
|
||||
}
|
||||
if (component_id == 3) {
|
||||
out_color = edge_mark_color;
|
||||
use_thickness = th * thickness_edge_mark * use_edge_mark;
|
||||
return;
|
||||
}
|
||||
if (component_id == 4) {
|
||||
out_color = intersection_color;
|
||||
use_thickness = th * thickness_intersection * use_intersection;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
vec4 correct_camera_scale(vec4 p)
|
||||
{
|
||||
|
||||
p.x -= camdx * 4;
|
||||
p.y -= camdy * 4;
|
||||
p.xy *= camzoom;
|
||||
return p;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int level = gLevel[1];
|
||||
|
||||
if (occlusion_level_start > level || occlusion_level_end < level)
|
||||
return;
|
||||
|
||||
float asp1 = output_viewport.z / output_viewport.w;
|
||||
float asp2 = preview_viewport.z / preview_viewport.w;
|
||||
float x_scale;
|
||||
float y_scale;
|
||||
if (asp1 > 1) {
|
||||
if (asp2 < 1) {
|
||||
x_scale = 1 / asp2;
|
||||
y_scale = 1 / asp1;
|
||||
}
|
||||
else {
|
||||
x_scale = 1;
|
||||
y_scale = asp2 / asp1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (asp2 < 1) {
|
||||
x_scale = asp1 / asp2;
|
||||
y_scale = 1;
|
||||
}
|
||||
else {
|
||||
x_scale = asp1;
|
||||
y_scale = asp2;
|
||||
}
|
||||
}
|
||||
|
||||
vec4 LL = vec4(gl_in[0].gl_Position.xy, 0, 1), L = vec4(gl_in[1].gl_Position.xy, 0, 1),
|
||||
R = vec4(gl_in[2].gl_Position.xy, 0, 1), RR = vec4(gl_in[3].gl_Position.xy, 0, 1);
|
||||
|
||||
LL.x *= x_scale;
|
||||
LL.y *= y_scale;
|
||||
L.x *= x_scale;
|
||||
L.y *= y_scale;
|
||||
R.x *= x_scale;
|
||||
R.y *= y_scale;
|
||||
RR.x *= x_scale;
|
||||
RR.y *= y_scale;
|
||||
|
||||
LL = correct_camera_scale(LL);
|
||||
L = correct_camera_scale(L);
|
||||
R = correct_camera_scale(R);
|
||||
RR = correct_camera_scale(RR);
|
||||
|
||||
int type = gType[1];
|
||||
|
||||
decide_line_style(type);
|
||||
|
||||
draw_line(LL, L, R, RR);
|
||||
}
|
@@ -0,0 +1,185 @@
|
||||
layout(lines) in;
|
||||
layout(triangle_strip, max_vertices = 6) out;
|
||||
|
||||
in vec3 gNormal[];
|
||||
uniform int normal_mode;
|
||||
uniform int normal_effect_inverse;
|
||||
uniform vec3 normal_direction; // also used as point position
|
||||
uniform float normal_ramp_begin;
|
||||
uniform float normal_ramp_end;
|
||||
uniform float normal_thickness_start;
|
||||
uniform float normal_thickness_end;
|
||||
|
||||
uniform float thickness;
|
||||
uniform float thickness_contour;
|
||||
uniform float thickness_crease;
|
||||
uniform float thickness_material;
|
||||
uniform float thickness_edge_mark;
|
||||
uniform float thickness_intersection;
|
||||
|
||||
// implement these later.
|
||||
// uniform float depth_width_influence;
|
||||
// uniform float depth_width_curve;
|
||||
// uniform float depth_alpha_influence;
|
||||
// uniform float depth_alpha_curve;
|
||||
// uniform float zNear;
|
||||
// uniform float zFar;
|
||||
|
||||
uniform vec4 contour_color;
|
||||
uniform vec4 crease_color;
|
||||
uniform vec4 material_color;
|
||||
uniform vec4 edge_mark_color;
|
||||
uniform vec4 intersection_color;
|
||||
|
||||
// for line width correction
|
||||
uniform vec4 output_viewport;
|
||||
uniform vec4 preview_viewport;
|
||||
|
||||
uniform float camdx;
|
||||
uniform float camdy;
|
||||
uniform float camzoom;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
float use_thickness;
|
||||
|
||||
void draw_line(vec4 p1, vec4 p2)
|
||||
{
|
||||
|
||||
vec4 Line = p2 - p1;
|
||||
vec4 Normal = normalize(vec4(-Line.y, Line.x, 0, 0));
|
||||
|
||||
vec4 a, b, c, d;
|
||||
|
||||
float x_scale = preview_viewport.w / preview_viewport.z;
|
||||
Normal.x *= x_scale;
|
||||
vec4 offset = Normal * use_thickness * 0.001;
|
||||
|
||||
a = p1 + offset;
|
||||
b = p1 - offset;
|
||||
c = p2 + offset;
|
||||
d = p2 - offset;
|
||||
|
||||
gl_Position = vec4(a.xy, 0, 1);
|
||||
EmitVertex();
|
||||
gl_Position = vec4(b.xy, 0, 1);
|
||||
EmitVertex();
|
||||
gl_Position = vec4(c.xy, 0, 1);
|
||||
EmitVertex();
|
||||
|
||||
gl_Position = vec4(b.xy, 0, 1);
|
||||
EmitVertex();
|
||||
gl_Position = vec4(c.xy, 0, 1);
|
||||
EmitVertex();
|
||||
gl_Position = vec4(d.xy, 0, 1);
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
float factor_to_thickness(float factor)
|
||||
{
|
||||
float r = (factor - normal_ramp_begin) / (normal_ramp_end - normal_ramp_begin);
|
||||
if (r > 1)
|
||||
r = 1;
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
float thickness = normal_effect_inverse == 1 ?
|
||||
mix(normal_thickness_start, normal_thickness_end, r) :
|
||||
mix(normal_thickness_end, normal_thickness_start, r);
|
||||
return thickness;
|
||||
}
|
||||
|
||||
void decide_color_and_thickness(float component_id)
|
||||
{
|
||||
float th = thickness;
|
||||
if (normal_mode == 0) {
|
||||
th = thickness;
|
||||
}
|
||||
else if (normal_mode == 1) {
|
||||
float factor = dot(gNormal[0], normal_direction);
|
||||
th = factor_to_thickness(factor);
|
||||
}
|
||||
else if (normal_mode == 2) {
|
||||
float factor = dot(gNormal[0], normal_direction);
|
||||
th = factor_to_thickness(factor);
|
||||
}
|
||||
|
||||
if (component_id < 1.5) {
|
||||
out_color = contour_color;
|
||||
use_thickness = th * thickness_contour;
|
||||
return;
|
||||
}
|
||||
if (component_id < 2.5) {
|
||||
out_color = crease_color;
|
||||
use_thickness = th * thickness_crease;
|
||||
return;
|
||||
}
|
||||
if (component_id < 3.5) {
|
||||
out_color = material_color;
|
||||
use_thickness = th * thickness_material;
|
||||
return;
|
||||
}
|
||||
if (component_id < 4.5) {
|
||||
out_color = edge_mark_color;
|
||||
use_thickness = th * thickness_edge_mark;
|
||||
return;
|
||||
}
|
||||
if (component_id < 5.5) {
|
||||
out_color = intersection_color;
|
||||
use_thickness = th * thickness_intersection;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
vec4 correct_camera_scale(vec4 p)
|
||||
{
|
||||
p.x -= camdx * 4;
|
||||
p.y -= camdy * 4;
|
||||
p.xy *= camzoom;
|
||||
return p;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
float asp1 = output_viewport.z / output_viewport.w;
|
||||
float asp2 = preview_viewport.z / preview_viewport.w;
|
||||
float x_scale;
|
||||
float y_scale;
|
||||
if (asp1 > 1) {
|
||||
if (asp2 < 1) {
|
||||
x_scale = 1 / asp2;
|
||||
y_scale = 1 / asp1;
|
||||
}
|
||||
else {
|
||||
x_scale = 1;
|
||||
y_scale = asp2 / asp1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (asp2 < 1) {
|
||||
x_scale = asp1 / asp2;
|
||||
y_scale = 1;
|
||||
}
|
||||
else {
|
||||
x_scale = asp1;
|
||||
y_scale = asp2;
|
||||
}
|
||||
}
|
||||
|
||||
vec4 p1 = vec4(gl_in[0].gl_Position.xy, 0, 1);
|
||||
vec4 p2 = vec4(gl_in[1].gl_Position.xy, 0, 1);
|
||||
|
||||
p1.x *= x_scale;
|
||||
p2.x *= x_scale;
|
||||
p1.y *= y_scale;
|
||||
p2.y *= y_scale;
|
||||
|
||||
p1 = correct_camera_scale(p1);
|
||||
p2 = correct_camera_scale(p2);
|
||||
|
||||
decide_color_and_thickness(gl_in[0].gl_Position.z);
|
||||
|
||||
draw_line(p1, p2);
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
in vec4 pos;
|
||||
in vec2 uvs;
|
||||
in vec3 normal;
|
||||
in int type;
|
||||
in int level;
|
||||
|
||||
out vec2 gOffset;
|
||||
out int gType;
|
||||
out int gLevel;
|
||||
out vec3 gNormal;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 p = pos;
|
||||
|
||||
gOffset = uvs;
|
||||
gType = type;
|
||||
gLevel = level;
|
||||
gNormal = normal;
|
||||
gl_Position = vec4(vec3(p), 1);
|
||||
}
|
@@ -225,6 +225,17 @@ void DRW_texture_ensure_fullscreen_2d(struct GPUTexture **tex,
|
||||
void DRW_texture_ensure_2d(
|
||||
struct GPUTexture **tex, int w, int h, eGPUTextureFormat format, DRWTextureFlag flags);
|
||||
|
||||
void DRW_texture_ensure_fullscreen_2D_multisample(struct GPUTexture **tex,
|
||||
eGPUTextureFormat format,
|
||||
int samples,
|
||||
DRWTextureFlag flags);
|
||||
void DRW_texture_ensure_2D_multisample(struct GPUTexture **tex,
|
||||
int w,
|
||||
int h,
|
||||
eGPUTextureFormat format,
|
||||
int samples,
|
||||
DRWTextureFlag flags);
|
||||
|
||||
void DRW_texture_generate_mipmaps(struct GPUTexture *tex);
|
||||
void DRW_texture_free(struct GPUTexture *tex);
|
||||
#define DRW_TEXTURE_FREE_SAFE(tex) \
|
||||
|
@@ -90,6 +90,7 @@
|
||||
#include "engines/basic/basic_engine.h"
|
||||
#include "engines/workbench/workbench_engine.h"
|
||||
#include "engines/external/external_engine.h"
|
||||
#include "engines/lanpr/lanpr_all.h"
|
||||
#include "engines/gpencil/gpencil_engine.h"
|
||||
#include "engines/select/select_engine.h"
|
||||
|
||||
@@ -2848,7 +2849,9 @@ void DRW_engine_register(DrawEngineType *draw_engine_type)
|
||||
void DRW_engines_register(void)
|
||||
{
|
||||
RE_engines_register(&DRW_engine_viewport_eevee_type);
|
||||
RE_engines_register(&DRW_engine_viewport_workbench_type);
|
||||
// RE_engines_register(&DRW_engine_viewport_workbench_type); //registered as two DRW_engines
|
||||
// below.
|
||||
RE_engines_register(&DRW_engine_viewport_lanpr_type);
|
||||
|
||||
DRW_engine_register(&draw_engine_workbench_solid);
|
||||
DRW_engine_register(&draw_engine_workbench_transparent);
|
||||
|
@@ -103,6 +103,19 @@ GPUTexture *DRW_texture_create_2d_array(
|
||||
return tex;
|
||||
}
|
||||
|
||||
GPUTexture *DRW_texture_create_2d_multisample(int w,
|
||||
int h,
|
||||
eGPUTextureFormat format,
|
||||
int samples,
|
||||
DRWTextureFlag flags,
|
||||
const float *fpixels)
|
||||
{
|
||||
GPUTexture *tex = GPU_texture_create_2d_multisample(w, h, format, fpixels, samples, NULL);
|
||||
drw_texture_set_parameters(tex, flags);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
GPUTexture *DRW_texture_create_3d(
|
||||
int w, int h, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
|
||||
{
|
||||
@@ -152,6 +165,26 @@ void DRW_texture_ensure_2d(
|
||||
}
|
||||
}
|
||||
|
||||
void DRW_texture_ensure_fullscreen_2D_multisample(GPUTexture **tex,
|
||||
eGPUTextureFormat format,
|
||||
int samples,
|
||||
DRWTextureFlag flags)
|
||||
{
|
||||
if (*(tex) == NULL) {
|
||||
const float *size = DRW_viewport_size_get();
|
||||
*(tex) = DRW_texture_create_2d_multisample(
|
||||
(int)size[0], (int)size[1], format, samples, flags, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void DRW_texture_ensure_2D_multisample(
|
||||
GPUTexture **tex, int w, int h, eGPUTextureFormat format, int samples, DRWTextureFlag flags)
|
||||
{
|
||||
if (*(tex) == NULL) {
|
||||
*(tex) = DRW_texture_create_2d_multisample(w, h, format, samples, flags, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void DRW_texture_generate_mipmaps(GPUTexture *tex)
|
||||
{
|
||||
GPU_texture_bind(tex, 0);
|
||||
|
@@ -27,6 +27,7 @@ if(WITH_BLENDER)
|
||||
add_subdirectory(interface)
|
||||
add_subdirectory(io)
|
||||
add_subdirectory(lattice)
|
||||
add_subdirectory(lanpr)
|
||||
add_subdirectory(gizmo_library)
|
||||
add_subdirectory(mask)
|
||||
add_subdirectory(mesh)
|
||||
|
622
source/blender/editors/include/ED_lanpr.h
Normal file
622
source/blender/editors/include/ED_lanpr.h
Normal file
@@ -0,0 +1,622 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __ED_LANPR_H__
|
||||
#define __ED_LANPR_H__
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "DNA_lanpr_types.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef double real;
|
||||
|
||||
typedef real tnsVector2d[2];
|
||||
typedef real tnsVector3d[3];
|
||||
typedef real tnsVector4d[4];
|
||||
typedef float tnsVector3f[3];
|
||||
typedef float tnsVector4f[4];
|
||||
typedef int tnsVector2i[2];
|
||||
|
||||
typedef struct LANPR_StaticMemPoolNode {
|
||||
Link item;
|
||||
int used_byte;
|
||||
/* User memory starts here */
|
||||
} LANPR_StaticMemPoolNode;
|
||||
|
||||
typedef struct LANPR_StaticMemPool {
|
||||
int each_size;
|
||||
ListBase pools;
|
||||
SpinLock lock_mem;
|
||||
} LANPR_StaticMemPool;
|
||||
|
||||
typedef struct LANPR_TextureSample {
|
||||
struct LANPR_TextureSample *next, *prev;
|
||||
int X, Y;
|
||||
/** For future usage */
|
||||
float Z;
|
||||
} LANPR_TextureSample;
|
||||
|
||||
typedef struct LANPR_LineStripPoint {
|
||||
struct LANPR_LineStripPoint *next, *prev;
|
||||
float P[3];
|
||||
} LANPR_LineStripPoint;
|
||||
|
||||
typedef struct LANPR_LineStrip {
|
||||
struct LANPR_LineStrip *next, *prev;
|
||||
ListBase points;
|
||||
int point_count;
|
||||
float total_length;
|
||||
} LANPR_LineStrip;
|
||||
|
||||
typedef struct LANPR_RenderTriangle {
|
||||
struct LANPR_RenderTriangle *next, *prev;
|
||||
struct LANPR_RenderVert *v[3];
|
||||
struct LANPR_RenderLine *rl[3];
|
||||
real gn[3];
|
||||
real gc[3];
|
||||
/* struct BMFace *F; */
|
||||
short material_id;
|
||||
ListBase intersecting_verts;
|
||||
char cull_status;
|
||||
/** Should be testing** , Use testing[NumOfThreads] to access. */
|
||||
struct LANPR_RenderTriangle *testing;
|
||||
} LANPR_RenderTriangle;
|
||||
|
||||
typedef struct LANPR_RenderTriangleThread {
|
||||
struct LANPR_RenderTriangle base;
|
||||
struct LANPR_RenderLine *testing[127];
|
||||
} LANPR_RenderTriangleThread;
|
||||
|
||||
typedef struct LANPR_RenderElementLinkNode {
|
||||
struct LANPR_RenderElementLinkNode *next, *prev;
|
||||
void *pointer;
|
||||
int element_count;
|
||||
void *object_ref;
|
||||
char additional;
|
||||
} LANPR_RenderElementLinkNode;
|
||||
|
||||
typedef struct LANPR_RenderLineSegment {
|
||||
struct LANPR_RenderLineSegment *next, *prev;
|
||||
/** at==0: left at==1: right (this is in 2D projected space) */
|
||||
real at;
|
||||
/** This is used to reconstruct 3d stroke (TODO: implement global space?) */
|
||||
real at_global;
|
||||
/** Occlusion level after "at" point */
|
||||
unsigned char occlusion;
|
||||
/** For determining lines beind a glass window material. (TODO: implement this) */
|
||||
short material_mask_mark;
|
||||
} LANPR_RenderLineSegment;
|
||||
|
||||
typedef struct LANPR_RenderVert {
|
||||
struct LANPR_RenderVert *next, *prev;
|
||||
real gloc[4];
|
||||
real fbcoord[4];
|
||||
int fbcoordi[2];
|
||||
/** Used as "r" when intersecting */
|
||||
struct BMVert *v;
|
||||
struct LANPR_RenderLine *intersecting_line;
|
||||
struct LANPR_RenderLine *intersecting_line2;
|
||||
struct LANPR_RenderTriangle *intersecting_with;
|
||||
|
||||
/** positive 1 Negative 0
|
||||
* <| |>
|
||||
* l---->|----->r l---->|----->r
|
||||
* <| |>
|
||||
* this means dot(r-l,face_normal)<0 then 1 otherwise 0
|
||||
*/
|
||||
char positive;
|
||||
char edge_used;
|
||||
} LANPR_RenderVert;
|
||||
|
||||
typedef enum LANPR_EdgeFlag {
|
||||
LANPR_EDGE_FLAG_EDGE_MARK = (1 << 0),
|
||||
LANPR_EDGE_FLAG_CONTOUR = (1 << 1),
|
||||
LANPR_EDGE_FLAG_CREASE = (1 << 2),
|
||||
LANPR_EDGE_FLAG_MATERIAL = (1 << 3),
|
||||
LANPR_EDGE_FLAG_INTERSECTION = (1 << 4),
|
||||
/** floating edge, unimplemented yet */
|
||||
LANPR_EDGE_FLAG_FLOATING = (1 << 5),
|
||||
LANPR_EDGE_FLAG_CHAIN_PICKED = (1 << 6),
|
||||
} LANPR_EdgeFlag;
|
||||
|
||||
#define LANPR_EDGE_FLAG_ALL_TYPE 0x3f
|
||||
|
||||
typedef struct LANPR_RenderLine {
|
||||
struct LANPR_RenderLine *next, *prev;
|
||||
struct LANPR_RenderVert *l, *r;
|
||||
struct LANPR_RenderTriangle *tl, *tr;
|
||||
ListBase segments;
|
||||
char min_occ;
|
||||
|
||||
/** Also for line type determination on chainning */
|
||||
char flags;
|
||||
|
||||
/** Still need this entry because culled lines will not add to object reln node */
|
||||
struct Object *object_ref;
|
||||
|
||||
/** For gpencil stroke modifier */
|
||||
int edge_idx;
|
||||
} LANPR_RenderLine;
|
||||
|
||||
typedef struct LANPR_RenderLineChain {
|
||||
struct LANPR_RenderLineChain *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;
|
||||
struct Object *object_ref;
|
||||
} LANPR_RenderLineChain;
|
||||
|
||||
typedef struct LANPR_RenderLineChainItem {
|
||||
struct LANPR_RenderLineChainItem *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;
|
||||
} LANPR_RenderLineChainItem;
|
||||
|
||||
typedef struct LANPR_ChainRegisterEntry {
|
||||
struct LANPR_ChainRegisterEntry *next, *prev;
|
||||
LANPR_RenderLineChain *rlc;
|
||||
LANPR_RenderLineChainItem *rlci;
|
||||
char picked;
|
||||
|
||||
/** left/right mark.
|
||||
* Because we revert list in chaining so we need the flag. */
|
||||
char is_left;
|
||||
} LANPR_ChainRegisterEntry;
|
||||
|
||||
typedef struct LANPR_RenderBuffer {
|
||||
struct LANPR_RenderBuffer *prev, *next;
|
||||
|
||||
/** For render. */
|
||||
int is_copied;
|
||||
|
||||
int w, h;
|
||||
int tile_size_w, tile_size_h;
|
||||
int tile_count_x, tile_count_y;
|
||||
real width_per_tile, height_per_tile;
|
||||
double view_projection[4][4];
|
||||
|
||||
int output_mode;
|
||||
int output_aa_level;
|
||||
|
||||
struct LANPR_BoundingArea *initial_bounding_areas;
|
||||
unsigned int bounding_area_count;
|
||||
|
||||
ListBase vertex_buffer_pointers;
|
||||
ListBase line_buffer_pointers;
|
||||
ListBase triangle_buffer_pointers;
|
||||
ListBase all_render_lines;
|
||||
|
||||
ListBase intersecting_vertex_buffer;
|
||||
|
||||
struct GPUBatch *DPIXIntersectionTransformBatch;
|
||||
struct GPUBatch *DPIXIntersectionBatch;
|
||||
|
||||
/** Use the one comes with LANPR. */
|
||||
LANPR_StaticMemPool render_data_pool;
|
||||
|
||||
struct Material *material_pointers[2048];
|
||||
|
||||
/* Render status */
|
||||
|
||||
int cached_for_frame;
|
||||
|
||||
real view_vector[3];
|
||||
|
||||
int triangle_size;
|
||||
|
||||
unsigned int contour_count;
|
||||
unsigned int contour_processed;
|
||||
LinkData *contour_managed;
|
||||
ListBase contours;
|
||||
|
||||
unsigned int intersection_count;
|
||||
unsigned int intersection_processed;
|
||||
LinkData *intersection_managed;
|
||||
ListBase intersection_lines;
|
||||
|
||||
unsigned int crease_count;
|
||||
unsigned int crease_processed;
|
||||
LinkData *crease_managed;
|
||||
ListBase crease_lines;
|
||||
|
||||
unsigned int material_line_count;
|
||||
unsigned int material_processed;
|
||||
LinkData *material_managed;
|
||||
ListBase material_lines;
|
||||
|
||||
unsigned int edge_mark_count;
|
||||
unsigned int edge_mark_processed;
|
||||
LinkData *edge_mark_managed;
|
||||
ListBase edge_marks;
|
||||
|
||||
ListBase chains;
|
||||
struct GPUBatch *chain_draw_batch;
|
||||
|
||||
struct DRWShadingGroup *ChainShgrp;
|
||||
|
||||
/** For managing calculation tasks for multiple threads. */
|
||||
SpinLock lock_task;
|
||||
|
||||
/* settings */
|
||||
|
||||
int max_occlusion_level;
|
||||
real crease_angle;
|
||||
real crease_cos;
|
||||
int thread_count;
|
||||
|
||||
int draw_material_preview;
|
||||
real material_transparency;
|
||||
|
||||
int show_line;
|
||||
int show_fast;
|
||||
int show_material;
|
||||
int override_display;
|
||||
|
||||
struct Scene *scene;
|
||||
struct Object *camera;
|
||||
|
||||
int use_intersections;
|
||||
int _pad;
|
||||
|
||||
} LANPR_RenderBuffer;
|
||||
|
||||
typedef enum LANPR_RenderStatus {
|
||||
LANPR_RENDER_IDLE = 0,
|
||||
LANPR_RENDER_RUNNING = 1,
|
||||
LANPR_RENDER_INCOMPELTE = 2,
|
||||
LANPR_RENDER_FINISHED = 3,
|
||||
} LANPR_RenderStatus;
|
||||
|
||||
typedef struct LANPR_SharedResource {
|
||||
|
||||
/* We only allocate once for all */
|
||||
LANPR_RenderBuffer *render_buffer_shared;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Image filtering */
|
||||
struct GPUShader *multichannel_shader;
|
||||
struct GPUShader *edge_detect_shader;
|
||||
struct GPUShader *edge_thinning_shader;
|
||||
struct GPUShader *snake_connection_shader;
|
||||
|
||||
/* GPU */
|
||||
struct GPUShader *dpix_transform_shader;
|
||||
struct GPUShader *dpix_preview_shader;
|
||||
int dpix_shader_error;
|
||||
int texture_size;
|
||||
ListBase dpix_batch_list;
|
||||
int dpix_reloaded;
|
||||
int dpix_reloaded_deg;
|
||||
|
||||
/* CPU */
|
||||
struct GPUShader *software_shader;
|
||||
struct GPUShader *software_chaining_shader;
|
||||
|
||||
void *ved_viewport;
|
||||
void *ved_render;
|
||||
|
||||
int init_complete;
|
||||
|
||||
/** To bypass or cancel rendering. */
|
||||
SpinLock lock_render_status;
|
||||
LANPR_RenderStatus flag_render_status;
|
||||
|
||||
/** Set before rendering and cleared upon finish! */
|
||||
struct RenderEngine *re_render;
|
||||
} LANPR_SharedResource;
|
||||
|
||||
#define DBL_TRIANGLE_LIM 1e-8
|
||||
#define DBL_EDGE_LIM 1e-9
|
||||
|
||||
#define LANPR_MEMORY_POOL_1MB 1048576
|
||||
#define LANPR_MEMORY_POOL_128MB 134217728
|
||||
#define LANPR_MEMORY_POOL_256MB 268435456
|
||||
#define LANPR_MEMORY_POOL_512MB 536870912
|
||||
|
||||
typedef enum LANPR_CullState {
|
||||
LANPR_CULL_DONT_CARE = 0,
|
||||
LANPR_CULL_USED = 1,
|
||||
LANPR_CULL_DISCARD = 2,
|
||||
} LANPR_CullState;
|
||||
|
||||
#define TNS_THREAD_LINE_COUNT 10000
|
||||
|
||||
typedef struct LANPR_RenderTaskInfo {
|
||||
int thread_id;
|
||||
|
||||
LinkData *contour;
|
||||
ListBase contour_pointers;
|
||||
|
||||
LinkData *intersection;
|
||||
ListBase intersection_pointers;
|
||||
|
||||
LinkData *crease;
|
||||
ListBase crease_pointers;
|
||||
|
||||
LinkData *material;
|
||||
ListBase material_pointers;
|
||||
|
||||
LinkData *edge_mark;
|
||||
ListBase edge_mark_pointers;
|
||||
|
||||
} LANPR_RenderTaskInfo;
|
||||
|
||||
typedef struct LANPR_BoundingArea {
|
||||
real l, r, u, b;
|
||||
real cx, cy;
|
||||
|
||||
/** 1,2,3,4 quadrant */
|
||||
struct LANPR_BoundingArea *child;
|
||||
|
||||
ListBase lp;
|
||||
ListBase rp;
|
||||
ListBase up;
|
||||
ListBase bp;
|
||||
|
||||
int triangle_count;
|
||||
ListBase linked_triangles;
|
||||
ListBase linked_lines;
|
||||
|
||||
/** Reserved for image space reduction && multithread chainning */
|
||||
ListBase linked_chains;
|
||||
} LANPR_BoundingArea;
|
||||
|
||||
#define TNS_COMMAND_LINE 0
|
||||
#define TNS_COMMAND_MATERIAL 1
|
||||
#define TNS_COMMAND_EDGE 2
|
||||
|
||||
#define TNS_TRANSPARENCY_DRAW_SIMPLE 0
|
||||
#define TNS_TRANSPARENCY_DRAW_LAYERED 1
|
||||
|
||||
#define TNS_OVERRIDE_ONLY 0
|
||||
#define TNS_OVERRIDE_EXCLUDE 1
|
||||
/* #define TNS_OVERRIDE_ALL_OTHERS_OUTSIDE_GROUP 2 */
|
||||
/* #define TNS_OVERRIDE_ALL_OTHERS_IN_GROUP 3 */
|
||||
/* #define TNS_OVERRIDE_ALL_OTHERS 4 */
|
||||
|
||||
#define TNS_TILE(tile, r, c, CCount) tile[r * CCount + c]
|
||||
|
||||
#define TNS_CLAMP(a, Min, Max) a = a < Min ? Min : (a > Max ? Max : a)
|
||||
|
||||
#define TNS_MAX3_INDEX(a, b, c) (a > b ? (a > c ? 0 : (b > c ? 1 : 2)) : (b > c ? 1 : 2))
|
||||
|
||||
#define TNS_MIN3_INDEX(a, b, c) (a < b ? (a < c ? 0 : (b < c ? 1 : 2)) : (b < c ? 1 : 2))
|
||||
|
||||
#define TNS_MAX3_INDEX_ABC(x, y, z) (x > y ? (x > z ? a : (y > z ? b : c)) : (y > z ? b : c))
|
||||
|
||||
#define TNS_MIN3_INDEX_ABC(x, y, z) (x < y ? (x < z ? a : (y < z ? b : c)) : (y < z ? b : c))
|
||||
|
||||
#define TNS_ABC(index) (index == 0 ? a : (index == 1 ? b : c))
|
||||
|
||||
#define TNS_DOUBLE_CLOSE_ENOUGH(a, b) (((a) + DBL_EDGE_LIM) >= (b) && ((a)-DBL_EDGE_LIM) <= (b))
|
||||
|
||||
/* #define TNS_DOUBLE_CLOSE_ENOUGH(a,b)\ */
|
||||
/* //(((a)+0.00000000001)>=(b) && ((a)-0.0000000001)<=(b)) */
|
||||
|
||||
#define TNS_FLOAT_CLOSE_ENOUGH_WIDER(a, b) (((a) + 0.0000001) >= (b) && ((a)-0.0000001) <= (b))
|
||||
|
||||
#define TNS_IN_TILE_X(RenderTile, Fx) (RenderTile->FX <= Fx && RenderTile->FXLim >= Fx)
|
||||
|
||||
#define TNS_IN_TILE_Y(RenderTile, Fy) (RenderTile->FY <= Fy && RenderTile->FYLim >= Fy)
|
||||
|
||||
#define TNS_IN_TILE(RenderTile, Fx, Fy) \
|
||||
(TNS_IN_TILE_X(RenderTile, Fx) && TNS_IN_TILE_Y(RenderTile, Fy))
|
||||
|
||||
BLI_INLINE int lanpr_TrangleLineBoundBoxTest(LANPR_RenderTriangle *rt, LANPR_RenderLine *rl)
|
||||
{
|
||||
if (MAX3(rt->v[0]->fbcoord[2], rt->v[1]->fbcoord[2], rt->v[2]->fbcoord[2]) >
|
||||
MIN2(rl->l->fbcoord[2], rl->r->fbcoord[2]))
|
||||
return 0;
|
||||
if (MAX3(rt->v[0]->fbcoord[0], rt->v[1]->fbcoord[0], rt->v[2]->fbcoord[0]) <
|
||||
MIN2(rl->l->fbcoord[0], rl->r->fbcoord[0]))
|
||||
return 0;
|
||||
if (MIN3(rt->v[0]->fbcoord[0], rt->v[1]->fbcoord[0], rt->v[2]->fbcoord[0]) >
|
||||
MAX2(rl->l->fbcoord[0], rl->r->fbcoord[0]))
|
||||
return 0;
|
||||
if (MAX3(rt->v[0]->fbcoord[1], rt->v[1]->fbcoord[1], rt->v[2]->fbcoord[1]) <
|
||||
MIN2(rl->l->fbcoord[1], rl->r->fbcoord[1]))
|
||||
return 0;
|
||||
if (MIN3(rt->v[0]->fbcoord[1], rt->v[1]->fbcoord[1], rt->v[2]->fbcoord[1]) >
|
||||
MAX2(rl->l->fbcoord[1], rl->r->fbcoord[1]))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
BLI_INLINE double tMatGetLinearRatio(real l, real r, real FromL);
|
||||
BLI_INLINE int lanpr_LineIntersectTest2d(
|
||||
const double *a1, const double *a2, const double *b1, const double *b2, double *aRatio)
|
||||
{
|
||||
double k1, k2;
|
||||
double x;
|
||||
double y;
|
||||
double Ratio;
|
||||
double xDiff = (a2[0] - a1[0]); /* +DBL_EPSILON; */
|
||||
double xDiff2 = (b2[0] - b1[0]);
|
||||
|
||||
if (xDiff == 0) {
|
||||
if (xDiff2 == 0) {
|
||||
*aRatio = 0;
|
||||
return 0;
|
||||
}
|
||||
double r2 = tMatGetLinearRatio(b1[0], b2[0], a1[0]);
|
||||
x = interpd(b2[0], b1[0], r2);
|
||||
y = interpd(b2[1], b1[1], r2);
|
||||
*aRatio = Ratio = tMatGetLinearRatio(a1[1], a2[1], y);
|
||||
}
|
||||
else {
|
||||
if (xDiff2 == 0) {
|
||||
Ratio = tMatGetLinearRatio(a1[0], a2[0], b1[0]);
|
||||
x = interpd(a2[0], a1[0], Ratio);
|
||||
*aRatio = Ratio;
|
||||
}
|
||||
else {
|
||||
k1 = (a2[1] - a1[1]) / xDiff;
|
||||
k2 = (b2[1] - b1[1]) / xDiff2;
|
||||
|
||||
if ((k1 == k2))
|
||||
return 0;
|
||||
|
||||
x = (a1[1] - b1[1] - k1 * a1[0] + k2 * b1[0]) / (k2 - k1);
|
||||
|
||||
Ratio = (x - a1[0]) / xDiff;
|
||||
|
||||
*aRatio = Ratio;
|
||||
}
|
||||
}
|
||||
|
||||
if (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;
|
||||
}
|
||||
BLI_INLINE double lanpr_GetLineZ(tnsVector3d l, tnsVector3d r, real Ratio)
|
||||
{
|
||||
double z = interpd(r[2], l[2], Ratio);
|
||||
return z;
|
||||
}
|
||||
BLI_INLINE double lanpr_GetLineZPoint(tnsVector3d l, tnsVector3d r, tnsVector3d FromL)
|
||||
{
|
||||
double ra = (FromL[0] - l[0]) / (r[0] - l[0]);
|
||||
return interpd(r[2], l[2], ra);
|
||||
}
|
||||
BLI_INLINE double lanpr_GetLinearRatio(tnsVector3d l, tnsVector3d r, tnsVector3d FromL)
|
||||
{
|
||||
double ra = (FromL[0] - l[0]) / (r[0] - l[0]);
|
||||
return ra;
|
||||
}
|
||||
|
||||
BLI_INLINE double tMatGetLinearRatio(real l, real r, real FromL)
|
||||
{
|
||||
double ra = (FromL - l) / (r - l);
|
||||
return ra;
|
||||
}
|
||||
|
||||
int ED_lanpr_point_inside_triangled(tnsVector2d v, tnsVector2d v0, tnsVector2d v1, tnsVector2d v2);
|
||||
|
||||
struct Depsgraph;
|
||||
struct SceneLANPR;
|
||||
|
||||
int ED_lanpr_object_collection_usage_check(struct Collection *c, struct Object *o);
|
||||
|
||||
void ED_lanpr_NO_THREAD_chain_feature_lines(LANPR_RenderBuffer *rb);
|
||||
void ED_lanpr_split_chains_for_fixed_occlusion(LANPR_RenderBuffer *rb);
|
||||
void ED_lanpr_connect_chains(LANPR_RenderBuffer *rb, int do_geometry_space);
|
||||
void ED_lanpr_discard_short_chains(LANPR_RenderBuffer *rb, float threshold);
|
||||
int ED_lanpr_count_chain(LANPR_RenderLineChain *rlc);
|
||||
void ED_lanpr_chain_clear_picked_flag(struct LANPR_RenderBuffer *rb);
|
||||
|
||||
int ED_lanpr_count_leveled_edge_segment_count(ListBase *LineList, struct LANPR_LineLayer *ll);
|
||||
void *ED_lanpr_make_leveled_edge_vertex_array(struct LANPR_RenderBuffer *rb,
|
||||
ListBase *LineList,
|
||||
float *vertexArray,
|
||||
float *NormalArray,
|
||||
float **NextNormal,
|
||||
LANPR_LineLayer *ll,
|
||||
float componet_id);
|
||||
|
||||
void ED_lanpr_calculation_set_flag(LANPR_RenderStatus flag);
|
||||
bool ED_lanpr_calculation_flag_check(LANPR_RenderStatus flag);
|
||||
|
||||
int ED_lanpr_compute_feature_lines_internal(struct Depsgraph *depsgraph, int instersections_only);
|
||||
|
||||
void ED_lanpr_compute_feature_lines_background(struct Depsgraph *dg, int intersection_only);
|
||||
|
||||
LANPR_RenderBuffer *ED_lanpr_create_render_buffer(void);
|
||||
void ED_lanpr_destroy_render_data(struct LANPR_RenderBuffer *rb);
|
||||
|
||||
void ED_lanpr_calculation_set_flag(LANPR_RenderStatus flag);
|
||||
bool ED_lanpr_calculation_flag_check(LANPR_RenderStatus flag);
|
||||
|
||||
bool ED_lanpr_dpix_shader_error(void);
|
||||
|
||||
int ED_lanpr_max_occlusion_in_line_layers(struct SceneLANPR *lanpr);
|
||||
LANPR_LineLayer *ED_lanpr_new_line_layer(struct SceneLANPR *lanpr);
|
||||
LANPR_LineLayerComponent *ED_lanpr_new_line_component(struct SceneLANPR *lanpr);
|
||||
|
||||
LANPR_BoundingArea *ED_lanpr_get_point_bounding_area(LANPR_RenderBuffer *rb, real x, real y);
|
||||
LANPR_BoundingArea *ED_lanpr_get_point_bounding_area_deep(LANPR_RenderBuffer *rb, real x, real y);
|
||||
|
||||
void ED_lanpr_post_frame_update_external(struct Scene *s, struct Depsgraph *dg);
|
||||
|
||||
struct SceneLANPR;
|
||||
|
||||
void ED_lanpr_rebuild_all_command(struct SceneLANPR *lanpr);
|
||||
|
||||
void ED_lanpr_update_render_progress(const char *text);
|
||||
|
||||
void ED_lanpr_calculate_normal_object_vector(LANPR_LineLayer *ll, float *normal_object_direction);
|
||||
|
||||
float ED_lanpr_compute_chain_length(LANPR_RenderLineChain *rlc);
|
||||
|
||||
struct wmOperatorType;
|
||||
|
||||
/* Operator types */
|
||||
void SCENE_OT_lanpr_calculate_feature_lines(struct wmOperatorType *ot);
|
||||
void SCENE_OT_lanpr_add_line_layer(struct wmOperatorType *ot);
|
||||
void SCENE_OT_lanpr_delete_line_layer(struct wmOperatorType *ot);
|
||||
void SCENE_OT_lanpr_rebuild_all_commands(struct wmOperatorType *ot);
|
||||
void SCENE_OT_lanpr_auto_create_line_layer(struct wmOperatorType *ot);
|
||||
void SCENE_OT_lanpr_move_line_layer(struct wmOperatorType *ot);
|
||||
void SCENE_OT_lanpr_add_line_component(struct wmOperatorType *ot);
|
||||
void SCENE_OT_lanpr_delete_line_component(struct wmOperatorType *ot);
|
||||
void SCENE_OT_lanpr_enable_all_line_types(struct wmOperatorType *ot);
|
||||
void SCENE_OT_lanpr_update_gp_strokes(struct wmOperatorType *ot);
|
||||
void SCENE_OT_lanpr_bake_gp_strokes(struct wmOperatorType *ot);
|
||||
|
||||
void OBJECT_OT_lanpr_update_gp_target(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_lanpr_update_gp_source(struct wmOperatorType *ot);
|
||||
|
||||
void ED_operatortypes_lanpr(void);
|
||||
|
||||
#endif /* __ED_LANPR_H__ */
|
46
source/blender/editors/lanpr/CMakeLists.txt
Normal file
46
source/blender/editors/lanpr/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
|
||||
lanpr_ops.c
|
||||
lanpr_cpu.c
|
||||
lanpr_chain.c
|
||||
lanpr_util.c
|
||||
|
||||
lanpr_intern.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
)
|
||||
|
||||
blender_add_lib(bf_editor_lanpr "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
817
source/blender/editors/lanpr/lanpr_chain.c
Normal file
817
source/blender/editors/lanpr/lanpr_chain.c
Normal file
@@ -0,0 +1,817 @@
|
||||
/*
|
||||
* 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_listbase.h"
|
||||
#include "BLI_linklist.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_lanpr_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "ED_lanpr.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
#include "lanpr_intern.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define LANPR_OTHER_RV(rl, rv) ((rv) == (rl)->l ? (rl)->r : (rl)->l)
|
||||
|
||||
static LANPR_RenderLine *lanpr_get_connected_render_line(LANPR_BoundingArea *ba,
|
||||
LANPR_RenderVert *rv,
|
||||
LANPR_RenderVert **new_rv,
|
||||
int match_flag)
|
||||
{
|
||||
LinkData *lip;
|
||||
LANPR_RenderLine *nrl;
|
||||
|
||||
for (lip = ba->linked_lines.first; lip; lip = lip->next) {
|
||||
nrl = lip->data;
|
||||
|
||||
if ((!(nrl->flags & LANPR_EDGE_FLAG_ALL_TYPE)) ||
|
||||
(nrl->flags & LANPR_EDGE_FLAG_CHAIN_PICKED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (match_flag && ((nrl->flags & LANPR_EDGE_FLAG_ALL_TYPE) & match_flag) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* always chain connected lines for now. */
|
||||
/* simplification will take care of the sharp points. */
|
||||
/* if(cosine whatever) continue; */
|
||||
|
||||
if (rv != nrl->l && rv != nrl->r) {
|
||||
if (nrl->flags & LANPR_EDGE_FLAG_INTERSECTION) {
|
||||
if (rv->fbcoord[0] == nrl->l->fbcoord[0] && rv->fbcoord[1] == nrl->l->fbcoord[1]) {
|
||||
*new_rv = LANPR_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 = LANPR_OTHER_RV(nrl, nrl->r);
|
||||
return nrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
*new_rv = LANPR_OTHER_RV(nrl, rv);
|
||||
return nrl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static LANPR_RenderLineChain *lanpr_create_render_line_chain(LANPR_RenderBuffer *rb)
|
||||
{
|
||||
LANPR_RenderLineChain *rlc;
|
||||
rlc = mem_static_aquire(&rb->render_data_pool, sizeof(LANPR_RenderLineChain));
|
||||
|
||||
BLI_addtail(&rb->chains, rlc);
|
||||
|
||||
return rlc;
|
||||
}
|
||||
|
||||
static LANPR_RenderLineChainItem *lanpr_append_render_line_chain_point(LANPR_RenderBuffer *rb,
|
||||
LANPR_RenderLineChain *rlc,
|
||||
float x,
|
||||
float y,
|
||||
float gx,
|
||||
float gy,
|
||||
float gz,
|
||||
float *normal,
|
||||
char type,
|
||||
int level)
|
||||
{
|
||||
LANPR_RenderLineChainItem *rlci;
|
||||
rlci = mem_static_aquire(&rb->render_data_pool, sizeof(LANPR_RenderLineChainItem));
|
||||
|
||||
rlci->pos[0] = x;
|
||||
rlci->pos[1] = y;
|
||||
rlci->gpos[0] = gx;
|
||||
rlci->gpos[1] = gy;
|
||||
rlci->gpos[2] = gz;
|
||||
copy_v3_v3(rlci->normal, normal);
|
||||
rlci->line_type = type & LANPR_EDGE_FLAG_ALL_TYPE;
|
||||
rlci->occlusion = level;
|
||||
BLI_addtail(&rlc->chain, rlci);
|
||||
|
||||
/* printf("a %f,%f %d\n", x, y, level); */
|
||||
|
||||
return rlci;
|
||||
}
|
||||
|
||||
static LANPR_RenderLineChainItem *lanpr_push_render_line_chain_point(LANPR_RenderBuffer *rb,
|
||||
LANPR_RenderLineChain *rlc,
|
||||
float x,
|
||||
float y,
|
||||
float gx,
|
||||
float gy,
|
||||
float gz,
|
||||
float *normal,
|
||||
char type,
|
||||
int level)
|
||||
{
|
||||
LANPR_RenderLineChainItem *rlci;
|
||||
rlci = mem_static_aquire(&rb->render_data_pool, sizeof(LANPR_RenderLineChainItem));
|
||||
|
||||
rlci->pos[0] = x;
|
||||
rlci->pos[1] = y;
|
||||
rlci->gpos[0] = gx;
|
||||
rlci->gpos[1] = gy;
|
||||
rlci->gpos[2] = gz;
|
||||
copy_v3_v3(rlci->normal, normal);
|
||||
rlci->line_type = type & LANPR_EDGE_FLAG_ALL_TYPE;
|
||||
rlci->occlusion = level;
|
||||
BLI_addhead(&rlc->chain, rlci);
|
||||
|
||||
/* printf("data %f,%f %d\n", x, y, level); */
|
||||
|
||||
return rlci;
|
||||
}
|
||||
|
||||
/* refer to http://karthaus.nl/rdp/ for description */
|
||||
static void lanpr_reduce_render_line_chain_recursive(LANPR_RenderLineChain *rlc,
|
||||
LANPR_RenderLineChainItem *from,
|
||||
LANPR_RenderLineChainItem *to,
|
||||
float dist_threshold)
|
||||
{
|
||||
LANPR_RenderLineChainItem *rlci, *next_rlci;
|
||||
float max_dist = 0;
|
||||
LANPR_RenderLineChainItem *max_rlci = 0;
|
||||
|
||||
/* find the max distance item */
|
||||
for (rlci = from->next; rlci != to; rlci = next_rlci) {
|
||||
next_rlci = rlci->next;
|
||||
|
||||
if (next_rlci &&
|
||||
(next_rlci->occlusion != rlci->occlusion || next_rlci->line_type != rlci->line_type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float dist = dist_to_line_segment_v2(rlci->pos, from->pos, to->pos);
|
||||
if (dist > dist_threshold && dist > max_dist) {
|
||||
max_dist = dist;
|
||||
max_rlci = rlci;
|
||||
}
|
||||
/* if (dist <= dist_threshold) BLI_remlink(&rlc->chain, (void*)rlci); */
|
||||
}
|
||||
|
||||
if (!max_rlci) {
|
||||
if (from->next == to) {
|
||||
return;
|
||||
}
|
||||
for (rlci = from->next; rlci != to; rlci = next_rlci) {
|
||||
next_rlci = rlci->next;
|
||||
if (next_rlci &&
|
||||
(next_rlci->occlusion != rlci->occlusion || next_rlci->line_type != rlci->line_type)) {
|
||||
continue;
|
||||
}
|
||||
BLI_remlink(&rlc->chain, (void *)rlci);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (from->next != max_rlci) {
|
||||
lanpr_reduce_render_line_chain_recursive(rlc, from, max_rlci, dist_threshold);
|
||||
}
|
||||
if (to->prev != max_rlci) {
|
||||
lanpr_reduce_render_line_chain_recursive(rlc, max_rlci, to, dist_threshold);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ED_lanpr_NO_THREAD_chain_feature_lines(LANPR_RenderBuffer *rb)
|
||||
{
|
||||
LANPR_RenderLineChain *rlc;
|
||||
LANPR_RenderLineChainItem *rlci;
|
||||
LANPR_RenderLine *rl;
|
||||
LANPR_BoundingArea *ba;
|
||||
LANPR_RenderLineSegment *rls;
|
||||
int last_occlusion;
|
||||
|
||||
for (rl = rb->all_render_lines.first; rl; rl = rl->next) {
|
||||
|
||||
if ((!(rl->flags & LANPR_EDGE_FLAG_ALL_TYPE)) || (rl->flags & LANPR_EDGE_FLAG_CHAIN_PICKED)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rl->flags |= LANPR_EDGE_FLAG_CHAIN_PICKED;
|
||||
|
||||
rlc = lanpr_create_render_line_chain(rb);
|
||||
|
||||
rlc->object_ref = rl->object_ref; /* can only be the same object in a chain. */
|
||||
rlc->type = (rl->flags & LANPR_EDGE_FLAG_ALL_TYPE);
|
||||
|
||||
LANPR_RenderLine *new_rl = rl;
|
||||
LANPR_RenderVert *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_lanpr_get_point_bounding_area_deep(rb, rl->l->fbcoord[0], rl->l->fbcoord[1]);
|
||||
new_rv = rl->l;
|
||||
rls = rl->segments.first;
|
||||
lanpr_push_render_line_chain_point(rb,
|
||||
rlc,
|
||||
new_rv->fbcoord[0],
|
||||
new_rv->fbcoord[1],
|
||||
new_rv->gloc[0],
|
||||
new_rv->gloc[1],
|
||||
new_rv->gloc[2],
|
||||
N,
|
||||
rl->flags,
|
||||
rls->occlusion);
|
||||
while (ba && (new_rl = lanpr_get_connected_render_line(ba, new_rv, &new_rv, rl->flags))) {
|
||||
new_rl->flags |= LANPR_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];
|
||||
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, rls->at);
|
||||
lanpr_push_render_line_chain_point(rb,
|
||||
rlc,
|
||||
lpos[0],
|
||||
lpos[1],
|
||||
gpos[0],
|
||||
gpos[1],
|
||||
gpos[2],
|
||||
N,
|
||||
new_rl->flags,
|
||||
rls->occlusion);
|
||||
last_occlusion = rls->occlusion;
|
||||
}
|
||||
}
|
||||
else if (new_rv == new_rl->r) {
|
||||
rls = new_rl->segments.first;
|
||||
last_occlusion = rls->occlusion;
|
||||
rls = rls->next;
|
||||
for (; rls; rls = rls->next) {
|
||||
double gpos[3], lpos[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, rls->at);
|
||||
lanpr_push_render_line_chain_point(rb,
|
||||
rlc,
|
||||
lpos[0],
|
||||
lpos[1],
|
||||
gpos[0],
|
||||
gpos[1],
|
||||
gpos[2],
|
||||
N,
|
||||
new_rl->flags,
|
||||
last_occlusion);
|
||||
last_occlusion = rls->occlusion;
|
||||
}
|
||||
lanpr_push_render_line_chain_point(rb,
|
||||
rlc,
|
||||
new_rl->r->fbcoord[0],
|
||||
new_rl->r->fbcoord[1],
|
||||
new_rl->r->gloc[0],
|
||||
new_rl->r->gloc[1],
|
||||
new_rl->r->gloc[2],
|
||||
N,
|
||||
new_rl->flags,
|
||||
last_occlusion);
|
||||
}
|
||||
ba = ED_lanpr_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 = ((LANPR_RenderLineSegment *)rls)->occlusion;
|
||||
for (rls = rls->next; rls; rls = rls->next) {
|
||||
double gpos[3], lpos[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, rls->at);
|
||||
lanpr_append_render_line_chain_point(
|
||||
rb, rlc, lpos[0], lpos[1], gpos[0], gpos[1], gpos[2], N, rl->flags, rls->occlusion);
|
||||
last_occlusion = rls->occlusion;
|
||||
}
|
||||
lanpr_append_render_line_chain_point(rb,
|
||||
rlc,
|
||||
rl->r->fbcoord[0],
|
||||
rl->r->fbcoord[1],
|
||||
rl->r->gloc[0],
|
||||
rl->r->gloc[1],
|
||||
rl->r->gloc[2],
|
||||
N,
|
||||
rl->flags,
|
||||
last_occlusion);
|
||||
|
||||
/* step 3: grow right */
|
||||
ba = ED_lanpr_get_point_bounding_area_deep(rb, rl->r->fbcoord[0], rl->r->fbcoord[1]);
|
||||
new_rv = rl->r;
|
||||
/* below already done in step 2 */
|
||||
/* lanpr_push_render_line_chain_point(rb,rlc,new_rv->fbcoord[0],new_rv->fbcoord[1],rl->flags,0);
|
||||
*/
|
||||
while (ba && (new_rl = lanpr_get_connected_render_line(ba, new_rv, &new_rv, rl->flags))) {
|
||||
new_rl->flags |= LANPR_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 & LANPR_EDGE_FLAG_ALL_TYPE;
|
||||
|
||||
if (new_rv == new_rl->l) {
|
||||
rls = new_rl->segments.last;
|
||||
last_occlusion = rls->occlusion;
|
||||
rlci->occlusion = last_occlusion; /* fix leading vertex occlusion */
|
||||
for (rls = new_rl->segments.last; rls; rls = rls->prev) {
|
||||
double gpos[3], lpos[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, rls->at);
|
||||
last_occlusion = rls->prev ? rls->prev->occlusion : last_occlusion;
|
||||
lanpr_append_render_line_chain_point(rb,
|
||||
rlc,
|
||||
lpos[0],
|
||||
lpos[1],
|
||||
gpos[0],
|
||||
gpos[1],
|
||||
gpos[2],
|
||||
N,
|
||||
new_rl->flags,
|
||||
last_occlusion);
|
||||
}
|
||||
}
|
||||
else if (new_rv == new_rl->r) {
|
||||
rls = new_rl->segments.first;
|
||||
last_occlusion = rls->occlusion;
|
||||
rlci->occlusion = last_occlusion;
|
||||
rls = rls->next;
|
||||
for (; rls; rls = rls->next) {
|
||||
double gpos[3], lpos[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, rls->at);
|
||||
lanpr_append_render_line_chain_point(rb,
|
||||
rlc,
|
||||
lpos[0],
|
||||
lpos[1],
|
||||
gpos[0],
|
||||
gpos[1],
|
||||
gpos[2],
|
||||
N,
|
||||
new_rl->flags,
|
||||
rls->occlusion);
|
||||
last_occlusion = rls->occlusion;
|
||||
}
|
||||
lanpr_append_render_line_chain_point(rb,
|
||||
rlc,
|
||||
new_rl->r->fbcoord[0],
|
||||
new_rl->r->fbcoord[1],
|
||||
new_rl->r->gloc[0],
|
||||
new_rl->r->gloc[1],
|
||||
new_rl->r->gloc[2],
|
||||
N,
|
||||
new_rl->flags,
|
||||
last_occlusion);
|
||||
}
|
||||
ba = ED_lanpr_get_point_bounding_area_deep(rb, new_rv->fbcoord[0], new_rv->fbcoord[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static LANPR_BoundingArea *lanpr_get_rlci_bounding_area_recursive(LANPR_RenderBuffer *rb,
|
||||
LANPR_BoundingArea *root,
|
||||
LANPR_RenderLineChainItem *rlci)
|
||||
{
|
||||
if (!root->child) {
|
||||
return root;
|
||||
}
|
||||
else {
|
||||
LANPR_BoundingArea *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 lanpr_get_rlci_bounding_area_recursive(rb, &ch[0], rlci);
|
||||
}
|
||||
else if (IN_BOUND(ch[1], rlci)) {
|
||||
return lanpr_get_rlci_bounding_area_recursive(rb, &ch[1], rlci);
|
||||
}
|
||||
else if (IN_BOUND(ch[2], rlci)) {
|
||||
return lanpr_get_rlci_bounding_area_recursive(rb, &ch[2], rlci);
|
||||
}
|
||||
else if (IN_BOUND(ch[3], rlci)) {
|
||||
return lanpr_get_rlci_bounding_area_recursive(rb, &ch[3], rlci);
|
||||
}
|
||||
#undef IN_BOUND
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static LANPR_BoundingArea *lanpr_get_end_point_bounding_area(LANPR_RenderBuffer *rb,
|
||||
LANPR_RenderLineChainItem *rlci)
|
||||
{
|
||||
LANPR_BoundingArea *root = ED_lanpr_get_point_bounding_area(rb, rlci->pos[0], rlci->pos[1]);
|
||||
if (!root) {
|
||||
return NULL;
|
||||
}
|
||||
return lanpr_get_rlci_bounding_area_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 lanpr_link_point_with_bounding_area_recursive(LANPR_RenderBuffer *rb,
|
||||
LANPR_BoundingArea *root,
|
||||
LANPR_RenderLineChain *rlc,
|
||||
LANPR_RenderLineChainItem *rlci)
|
||||
{
|
||||
if (!root->child) {
|
||||
LANPR_ChainRegisterEntry *cre = list_append_pointer_static_sized(
|
||||
&root->linked_chains, &rb->render_data_pool, rlc, sizeof(LANPR_ChainRegisterEntry));
|
||||
|
||||
cre->rlci = rlci;
|
||||
|
||||
if (rlci == rlc->chain.first) {
|
||||
cre->is_left = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LANPR_BoundingArea *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)) {
|
||||
lanpr_link_point_with_bounding_area_recursive(rb, &ch[0], rlc, rlci);
|
||||
}
|
||||
else if (IN_BOUND(ch[1], rlci)) {
|
||||
lanpr_link_point_with_bounding_area_recursive(rb, &ch[1], rlc, rlci);
|
||||
}
|
||||
else if (IN_BOUND(ch[2], rlci)) {
|
||||
lanpr_link_point_with_bounding_area_recursive(rb, &ch[2], rlc, rlci);
|
||||
}
|
||||
else if (IN_BOUND(ch[3], rlci)) {
|
||||
lanpr_link_point_with_bounding_area_recursive(rb, &ch[3], rlc, rlci);
|
||||
}
|
||||
|
||||
#undef IN_BOUND
|
||||
}
|
||||
}
|
||||
|
||||
static void lanpr_link_chain_with_bounding_areas(LANPR_RenderBuffer *rb,
|
||||
LANPR_RenderLineChain *rlc)
|
||||
{
|
||||
LANPR_RenderLineChainItem *pl = rlc->chain.first;
|
||||
LANPR_RenderLineChainItem *pr = rlc->chain.last;
|
||||
LANPR_BoundingArea *ba1 = ED_lanpr_get_point_bounding_area(rb, pl->pos[0], pl->pos[1]);
|
||||
LANPR_BoundingArea *ba2 = ED_lanpr_get_point_bounding_area(rb, pr->pos[0], pr->pos[1]);
|
||||
|
||||
if (ba1) {
|
||||
lanpr_link_point_with_bounding_area_recursive(rb, ba1, rlc, pl);
|
||||
}
|
||||
if (ba2) {
|
||||
lanpr_link_point_with_bounding_area_recursive(rb, ba2, rlc, pr);
|
||||
}
|
||||
}
|
||||
|
||||
void ED_lanpr_split_chains_for_fixed_occlusion(LANPR_RenderBuffer *rb)
|
||||
{
|
||||
LANPR_RenderLineChain *rlc, *new_rlc;
|
||||
LANPR_RenderLineChainItem *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);
|
||||
LANPR_RenderLineChainItem *first_rlci = (LANPR_RenderLineChainItem *)rlc->chain.first;
|
||||
int fixed_occ = first_rlci->occlusion;
|
||||
rlc->level = fixed_occ;
|
||||
for (rlci = first_rlci->next; rlci; rlci = next_rlci) {
|
||||
next_rlci = rlci->next;
|
||||
if (rlci->occlusion != fixed_occ) {
|
||||
new_rlc = lanpr_create_render_line_chain(rb);
|
||||
new_rlc->chain.first = rlci;
|
||||
new_rlc->chain.last = rlc->chain.last;
|
||||
rlc->chain.last = rlci->prev;
|
||||
((LANPR_RenderLineChainItem *)rlc->chain.last)->next = 0;
|
||||
rlci->prev = 0;
|
||||
|
||||
/* end the previous one */
|
||||
lanpr_append_render_line_chain_point(rb,
|
||||
rlc,
|
||||
rlci->pos[0],
|
||||
rlci->pos[1],
|
||||
rlci->gpos[0],
|
||||
rlci->gpos[1],
|
||||
rlci->gpos[2],
|
||||
rlci->normal,
|
||||
rlci->line_type,
|
||||
fixed_occ);
|
||||
new_rlc->object_ref = rlc->object_ref;
|
||||
new_rlc->type = rlc->type;
|
||||
rlc = new_rlc;
|
||||
fixed_occ = rlci->occlusion;
|
||||
rlc->level = fixed_occ;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (rlc = rb->chains.first; rlc; rlc = rlc->next) {
|
||||
lanpr_link_chain_with_bounding_areas(rb, rlc);
|
||||
}
|
||||
}
|
||||
|
||||
/* note: segment type (crease/material/contour...) is ambiguous after this. */
|
||||
static void lanpr_connect_two_chains(LANPR_RenderBuffer *UNUSED(rb),
|
||||
LANPR_RenderLineChain *onto,
|
||||
LANPR_RenderLineChain *sub,
|
||||
int reverse_1,
|
||||
int reverse_2)
|
||||
{
|
||||
if (!reverse_1) { /* L--R L-R */
|
||||
if (reverse_2) { /* L--R R-L */
|
||||
BLI_listbase_reverse(&sub->chain);
|
||||
}
|
||||
((LANPR_RenderLineChainItem *)onto->chain.last)->next = sub->chain.first;
|
||||
((LANPR_RenderLineChainItem *)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);
|
||||
}
|
||||
((LANPR_RenderLineChainItem *)sub->chain.last)->next = onto->chain.first;
|
||||
((LANPR_RenderLineChainItem *)onto->chain.first)->prev = sub->chain.last;
|
||||
onto->chain.first = sub->chain.first;
|
||||
}
|
||||
/* ((LANPR_RenderLineChainItem*)sub->chain.first)->occlusion = */
|
||||
/* ((LANPR_RenderLineChainItem*)onto->chain.first)->occlusion; */
|
||||
/* ((LANPR_RenderLineChainItem*)onto->chain.last)->occlusion = */
|
||||
/* ((LANPR_RenderLineChainItem*)onto->chain.first)->occlusion; */
|
||||
/* ((LANPR_RenderLineChainItem*)sub->chain.last)->occlusion = */
|
||||
/* ((LANPR_RenderLineChainItem*)onto->chain.first)->occlusion; */
|
||||
}
|
||||
|
||||
/* this only does head-tail connection. */
|
||||
/* overlapping / tiny isolated segment / loop reduction not implemented here yet. */
|
||||
void ED_lanpr_connect_chains(LANPR_RenderBuffer *rb, int do_geometry_space)
|
||||
{
|
||||
LANPR_RenderLineChain *rlc;
|
||||
LANPR_RenderLineChainItem *rlci;
|
||||
LANPR_BoundingArea *ba;
|
||||
LANPR_ChainRegisterEntry *cre, *next_cre, *closest_cre;
|
||||
float dist;
|
||||
int occlusion;
|
||||
ListBase swap = {0};
|
||||
|
||||
if ((!do_geometry_space && rb->scene->lanpr.chaining_image_threshold < 0.0001) ||
|
||||
(do_geometry_space && rb->scene->lanpr.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;
|
||||
BLI_addtail(&rb->chains, rlc);
|
||||
if (rlc->picked) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rlc->picked = 1;
|
||||
|
||||
occlusion = ((LANPR_RenderLineChainItem *)rlc->chain.first)->occlusion;
|
||||
|
||||
rlci = rlc->chain.last;
|
||||
while ((ba = lanpr_get_end_point_bounding_area(rb, rlci)) != NULL) {
|
||||
dist = do_geometry_space ? rb->scene->lanpr.chaining_geometry_threshold :
|
||||
rb->scene->lanpr.chaining_image_threshold;
|
||||
closest_cre = NULL;
|
||||
if (!ba->linked_chains.first) {
|
||||
break;
|
||||
}
|
||||
for (cre = ba->linked_chains.first; cre; cre = next_cre) {
|
||||
next_cre = cre->next;
|
||||
if (cre->rlc->object_ref != rlc->object_ref) {
|
||||
continue;
|
||||
}
|
||||
if (cre->rlc == rlc ||
|
||||
((LANPR_RenderLineChainItem *)cre->rlc->chain.first)->occlusion != occlusion ||
|
||||
(cre->rlc->type != rlc->type)) {
|
||||
continue;
|
||||
}
|
||||
if (cre->rlc->picked) {
|
||||
BLI_remlink(&ba->linked_chains, cre);
|
||||
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 (closest_cre) {
|
||||
closest_cre->picked = 1;
|
||||
closest_cre->rlc->picked = 1;
|
||||
BLI_remlink(&ba->linked_chains, cre);
|
||||
if (closest_cre->is_left) {
|
||||
lanpr_connect_two_chains(rb, rlc, closest_cre->rlc, 0, 0);
|
||||
}
|
||||
else {
|
||||
lanpr_connect_two_chains(rb, rlc, closest_cre->rlc, 0, 1);
|
||||
}
|
||||
BLI_remlink(&swap, closest_cre->rlc);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
rlci = rlc->chain.last;
|
||||
}
|
||||
|
||||
rlci = rlc->chain.first;
|
||||
while ((ba = lanpr_get_end_point_bounding_area(rb, rlci)) != NULL) {
|
||||
dist = do_geometry_space ? rb->scene->lanpr.chaining_geometry_threshold :
|
||||
rb->scene->lanpr.chaining_image_threshold;
|
||||
closest_cre = NULL;
|
||||
if (!ba->linked_chains.first) {
|
||||
break;
|
||||
}
|
||||
for (cre = ba->linked_chains.first; cre; cre = next_cre) {
|
||||
next_cre = cre->next;
|
||||
if (cre->rlc->object_ref != rlc->object_ref) {
|
||||
continue;
|
||||
}
|
||||
if (cre->rlc == rlc ||
|
||||
((LANPR_RenderLineChainItem *)cre->rlc->chain.first)->occlusion != occlusion ||
|
||||
(cre->rlc->type != rlc->type)) {
|
||||
continue;
|
||||
}
|
||||
if (cre->rlc->picked) {
|
||||
BLI_remlink(&ba->linked_chains, cre);
|
||||
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 (closest_cre) {
|
||||
closest_cre->picked = 1;
|
||||
closest_cre->rlc->picked = 1;
|
||||
BLI_remlink(&ba->linked_chains, cre);
|
||||
if (closest_cre->is_left) {
|
||||
lanpr_connect_two_chains(rb, rlc, closest_cre->rlc, 1, 0);
|
||||
}
|
||||
else {
|
||||
lanpr_connect_two_chains(rb, rlc, closest_cre->rlc, 1, 1);
|
||||
}
|
||||
BLI_remlink(&swap, closest_cre->rlc);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
rlci = rlc->chain.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* length is in image space */
|
||||
float ED_lanpr_compute_chain_length(LANPR_RenderLineChain *rlc)
|
||||
{
|
||||
LANPR_RenderLineChainItem *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_lanpr_discard_short_chains(LANPR_RenderBuffer *rb, float threshold)
|
||||
{
|
||||
LANPR_RenderLineChain *rlc, *next_rlc;
|
||||
for (rlc = rb->chains.first; rlc; rlc = next_rlc) {
|
||||
next_rlc = rlc->next;
|
||||
if (ED_lanpr_compute_chain_length(rlc) < threshold) {
|
||||
BLI_remlink(&rb->chains, rlc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ED_lanpr_count_chain(LANPR_RenderLineChain *rlc)
|
||||
{
|
||||
LANPR_RenderLineChainItem *rlci;
|
||||
int Count = 0;
|
||||
for (rlci = rlc->chain.first; rlci; rlci = rlci->next) {
|
||||
Count++;
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
|
||||
void ED_lanpr_chain_clear_picked_flag(LANPR_RenderBuffer *rb)
|
||||
{
|
||||
LANPR_RenderLineChain *rlc;
|
||||
if (!rb) {
|
||||
return;
|
||||
}
|
||||
for (rlc = rb->chains.first; rlc; rlc = rlc->next) {
|
||||
rlc->picked = 0;
|
||||
}
|
||||
}
|
4512
source/blender/editors/lanpr/lanpr_cpu.c
Normal file
4512
source/blender/editors/lanpr/lanpr_cpu.c
Normal file
File diff suppressed because it is too large
Load Diff
74
source/blender/editors/lanpr/lanpr_intern.h
Normal file
74
source/blender/editors/lanpr/lanpr_intern.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 __LANPR_INTERN_H__
|
||||
#define __LANPR_INTERN_H__
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_threads.h"
|
||||
|
||||
#include "DNA_lanpr_types.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
struct LANPR_StaticMemPoolNode;
|
||||
struct LANPR_RenderLine;
|
||||
struct LANPR_RenderBuffer;
|
||||
|
||||
void *list_append_pointer_static(ListBase *h, struct LANPR_StaticMemPool *smp, void *p);
|
||||
void *list_append_pointer_static_sized(ListBase *h,
|
||||
struct LANPR_StaticMemPool *smp,
|
||||
void *p,
|
||||
int size);
|
||||
void *list_push_pointer_static(ListBase *h, struct LANPR_StaticMemPool *smp, void *p);
|
||||
void *list_push_pointer_static_sized(ListBase *h,
|
||||
struct LANPR_StaticMemPool *smp,
|
||||
void *p,
|
||||
int size);
|
||||
|
||||
void *list_append_pointer_static_pool(struct LANPR_StaticMemPool *mph, ListBase *h, void *p);
|
||||
void *list_pop_pointer_no_free(ListBase *h);
|
||||
void list_remove_pointer_item_no_free(ListBase *h, LinkData *lip);
|
||||
|
||||
LANPR_StaticMemPoolNode *mem_new_static_pool(struct LANPR_StaticMemPool *smp);
|
||||
void *mem_static_aquire(struct LANPR_StaticMemPool *smp, int size);
|
||||
void *mem_static_aquire_thread(struct LANPR_StaticMemPool *smp, int size);
|
||||
void *mem_static_destroy(LANPR_StaticMemPool *smp);
|
||||
|
||||
void tmat_make_ortho_matrix_44d(double (*mProjection)[4],
|
||||
double xMin,
|
||||
double xMax,
|
||||
double yMin,
|
||||
double yMax,
|
||||
double zMin,
|
||||
double zMax);
|
||||
void tmat_make_perspective_matrix_44d(
|
||||
double (*mProjection)[4], double fFov_rad, double fAspect, double zMin, double zMax);
|
||||
|
||||
int lanpr_count_this_line(struct LANPR_RenderLine *rl, struct LANPR_LineLayer *ll);
|
||||
int lanpr_count_intersection_segment_count(struct LANPR_RenderBuffer *rb);
|
||||
|
||||
#endif
|
50
source/blender/editors/lanpr/lanpr_ops.c
Normal file
50
source/blender/editors/lanpr/lanpr_ops.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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 "BLI_utildefines.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "ED_lanpr.h"
|
||||
|
||||
void ED_operatortypes_lanpr(void)
|
||||
{
|
||||
/* lanpr: */
|
||||
WM_operatortype_append(SCENE_OT_lanpr_calculate_feature_lines);
|
||||
WM_operatortype_append(SCENE_OT_lanpr_add_line_layer);
|
||||
WM_operatortype_append(SCENE_OT_lanpr_delete_line_layer);
|
||||
WM_operatortype_append(SCENE_OT_lanpr_rebuild_all_commands);
|
||||
WM_operatortype_append(SCENE_OT_lanpr_auto_create_line_layer);
|
||||
WM_operatortype_append(SCENE_OT_lanpr_move_line_layer);
|
||||
WM_operatortype_append(SCENE_OT_lanpr_add_line_component);
|
||||
WM_operatortype_append(SCENE_OT_lanpr_delete_line_component);
|
||||
WM_operatortype_append(SCENE_OT_lanpr_enable_all_line_types);
|
||||
WM_operatortype_append(SCENE_OT_lanpr_update_gp_strokes);
|
||||
WM_operatortype_append(SCENE_OT_lanpr_bake_gp_strokes);
|
||||
|
||||
WM_operatortype_append(OBJECT_OT_lanpr_update_gp_target);
|
||||
/* Not working */
|
||||
/* WM_operatortype_append(OBJECT_OT_lanpr_update_gp_source); */
|
||||
}
|
197
source/blender/editors/lanpr/lanpr_util.c
Normal file
197
source/blender/editors/lanpr/lanpr_util.c
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
/* #include <time.h> */
|
||||
#include "ED_lanpr.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include <math.h>
|
||||
|
||||
#include "lanpr_intern.h"
|
||||
|
||||
/* ===================================================================[slt] */
|
||||
|
||||
void *list_append_pointer_static(ListBase *h, LANPR_StaticMemPool *smp, void *data)
|
||||
{
|
||||
LinkData *lip;
|
||||
if (!h) {
|
||||
return 0;
|
||||
}
|
||||
lip = mem_static_aquire(smp, sizeof(LinkData));
|
||||
lip->data = data;
|
||||
BLI_addtail(h, lip);
|
||||
return lip;
|
||||
}
|
||||
void *list_append_pointer_static_sized(ListBase *h, LANPR_StaticMemPool *smp, void *data, int size)
|
||||
{
|
||||
LinkData *lip;
|
||||
if (!h) {
|
||||
return 0;
|
||||
}
|
||||
lip = mem_static_aquire(smp, size);
|
||||
lip->data = data;
|
||||
BLI_addtail(h, lip);
|
||||
return lip;
|
||||
}
|
||||
|
||||
void *list_append_pointer_static_pool(LANPR_StaticMemPool *mph, ListBase *h, void *data)
|
||||
{
|
||||
LinkData *lip;
|
||||
if (!h) {
|
||||
return 0;
|
||||
}
|
||||
lip = mem_static_aquire(mph, sizeof(LinkData));
|
||||
lip->data = data;
|
||||
BLI_addtail(h, lip);
|
||||
return lip;
|
||||
}
|
||||
void *list_pop_pointer_no_free(ListBase *h)
|
||||
{
|
||||
LinkData *lip;
|
||||
void *rev = 0;
|
||||
if (!h) {
|
||||
return 0;
|
||||
}
|
||||
lip = BLI_pophead(h);
|
||||
rev = lip ? lip->data : 0;
|
||||
return rev;
|
||||
}
|
||||
void list_remove_pointer_item_no_free(ListBase *h, LinkData *lip)
|
||||
{
|
||||
BLI_remlink(h, (void *)lip);
|
||||
}
|
||||
|
||||
LANPR_StaticMemPoolNode *mem_new_static_pool(LANPR_StaticMemPool *smp)
|
||||
{
|
||||
LANPR_StaticMemPoolNode *smpn = MEM_callocN(LANPR_MEMORY_POOL_128MB, "mempool");
|
||||
smpn->used_byte = sizeof(LANPR_StaticMemPoolNode);
|
||||
BLI_addhead(&smp->pools, smpn);
|
||||
return smpn;
|
||||
}
|
||||
void *mem_static_aquire(LANPR_StaticMemPool *smp, int size)
|
||||
{
|
||||
LANPR_StaticMemPoolNode *smpn = smp->pools.first;
|
||||
void *ret;
|
||||
|
||||
if (!smpn || (smpn->used_byte + size) > LANPR_MEMORY_POOL_128MB) {
|
||||
smpn = mem_new_static_pool(smp);
|
||||
}
|
||||
|
||||
ret = ((unsigned char *)smpn) + smpn->used_byte;
|
||||
|
||||
smpn->used_byte += size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
void *mem_static_aquire_thread(LANPR_StaticMemPool *smp, int size)
|
||||
{
|
||||
LANPR_StaticMemPoolNode *smpn = smp->pools.first;
|
||||
void *ret;
|
||||
|
||||
BLI_spin_lock(&smp->lock_mem);
|
||||
|
||||
if (!smpn || (smpn->used_byte + size) > LANPR_MEMORY_POOL_128MB) {
|
||||
smpn = mem_new_static_pool(smp);
|
||||
}
|
||||
|
||||
ret = ((unsigned char *)smpn) + smpn->used_byte;
|
||||
|
||||
smpn->used_byte += size;
|
||||
|
||||
BLI_spin_unlock(&smp->lock_mem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
void *mem_static_destroy(LANPR_StaticMemPool *smp)
|
||||
{
|
||||
LANPR_StaticMemPoolNode *smpn;
|
||||
void *ret = 0;
|
||||
|
||||
while ((smpn = BLI_pophead(&smp->pools)) != NULL) {
|
||||
MEM_freeN(smpn);
|
||||
}
|
||||
|
||||
smp->each_size = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* =======================================================================[str] */
|
||||
|
||||
real tmat_length_3d(tnsVector3d l)
|
||||
{
|
||||
return (sqrt(l[0] * l[0] + l[1] * l[1] + l[2] * l[2]));
|
||||
}
|
||||
real tmat_vector_cross_3d(tnsVector3d result, tnsVector3d l, tnsVector3d r)
|
||||
{
|
||||
result[0] = l[1] * r[2] - l[2] * r[1];
|
||||
result[1] = l[2] * r[0] - l[0] * r[2];
|
||||
result[2] = l[0] * r[1] - l[1] * r[0];
|
||||
return tmat_length_3d(result);
|
||||
}
|
||||
void tmat_make_perspective_matrix_44d(
|
||||
double (*mProjection)[4], real fFov_rad, real fAspect, real zMin, real zMax)
|
||||
{
|
||||
real yMax;
|
||||
real yMin;
|
||||
real xMin;
|
||||
real 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 tmat_make_ortho_matrix_44d(
|
||||
double (*mProjection)[4], real xMin, real xMax, real yMin, real yMax, real zMin, real 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;
|
||||
}
|
@@ -59,6 +59,8 @@
|
||||
#include "ED_render.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
#include "ED_lanpr.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
@@ -95,6 +97,9 @@ void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int update
|
||||
return;
|
||||
}
|
||||
|
||||
/* Temporary solution for updating LANPR GPencil targets. */
|
||||
ED_lanpr_post_frame_update_external(scene, update_ctx->depsgraph);
|
||||
|
||||
recursive_check = true;
|
||||
|
||||
C = CTX_create();
|
||||
|
@@ -64,6 +64,8 @@
|
||||
#include "ED_gizmo_library.h"
|
||||
#include "ED_transform.h"
|
||||
|
||||
#include "ED_lanpr.h"
|
||||
|
||||
#include "io_ops.h"
|
||||
|
||||
/* only call once on startup, storage is global in BKE kernel listbase */
|
||||
@@ -123,6 +125,8 @@ void ED_spacetypes_init(void)
|
||||
ED_operatortypes_view2d();
|
||||
ED_operatortypes_ui();
|
||||
|
||||
ED_operatortypes_lanpr();
|
||||
|
||||
ED_screen_user_menu_register();
|
||||
|
||||
/* gizmo types */
|
||||
|
@@ -164,6 +164,31 @@ static int buttons_context_path_world(ButsContextPath *path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buttons_context_path_collection(ButsContextPath *path, wmWindow *window)
|
||||
{
|
||||
Scene *scene;
|
||||
World *world;
|
||||
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 1;
|
||||
}
|
||||
/* 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 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* no path to a collection possible */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buttons_context_path_linestyle(ButsContextPath *path, wmWindow *window)
|
||||
{
|
||||
FreestyleLineStyle *linestyle;
|
||||
@@ -575,6 +600,18 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
|
||||
case BCONTEXT_WORLD:
|
||||
found = buttons_context_path_world(path);
|
||||
break;
|
||||
case BCONTEXT_COLLECTION:
|
||||
found = buttons_context_path_collection(path, window);
|
||||
break;
|
||||
case BCONTEXT_LANPR:
|
||||
if (scene &&
|
||||
((scene->lanpr.flags & LANPR_ENABLED) || !strcmp(scene->r.engine, "BLENDER_LANPR"))) {
|
||||
found = buttons_context_path_object(path);
|
||||
}
|
||||
else {
|
||||
found = 0;
|
||||
}
|
||||
break;
|
||||
case BCONTEXT_TOOL:
|
||||
found = true;
|
||||
break;
|
||||
|
@@ -160,6 +160,12 @@ static void buttons_main_region_layout_properties(const bContext *C,
|
||||
case BCONTEXT_WORLD:
|
||||
contexts[0] = "world";
|
||||
break;
|
||||
case BCONTEXT_COLLECTION:
|
||||
contexts[0] = "collection";
|
||||
break;
|
||||
case BCONTEXT_LANPR:
|
||||
contexts[0] = "lanpr";
|
||||
break;
|
||||
case BCONTEXT_OBJECT:
|
||||
contexts[0] = "object";
|
||||
break;
|
||||
|
@@ -1005,6 +1005,7 @@ static void view3d_main_region_message_subscribe(const struct bContext *C,
|
||||
}
|
||||
|
||||
WM_msg_subscribe_rna_anon_type(mbus, SceneEEVEE, &msg_sub_value_region_tag_redraw);
|
||||
WM_msg_subscribe_rna_anon_type(mbus, SceneLANPR, &msg_sub_value_region_tag_redraw);
|
||||
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);
|
||||
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#define __DNA_COLLECTION_TYPES_H__
|
||||
|
||||
#include "DNA_defs.h"
|
||||
#include "DNA_lanpr_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_ID.h"
|
||||
|
||||
@@ -43,6 +44,39 @@ typedef struct CollectionChild {
|
||||
struct Collection *collection;
|
||||
} CollectionChild;
|
||||
|
||||
enum CollectionFeatureLine_Usage {
|
||||
COLLECTION_FEATURE_LINE_INCLUDE = 0,
|
||||
COLLECTION_FEATURE_LINE_OCCLUSION_ONLY = (1 << 0),
|
||||
COLLECTION_FEATURE_LINE_EXCLUDE = (1 << 1),
|
||||
};
|
||||
|
||||
typedef struct CollectionLANPRLineType {
|
||||
int use;
|
||||
char _pad[4];
|
||||
char target_layer[128];
|
||||
char target_material[128];
|
||||
} CollectionLANPRLineType;
|
||||
|
||||
typedef struct CollectionLANPR {
|
||||
int usage;
|
||||
|
||||
/* Separate flags for LANPR shared flag values. */
|
||||
int flags;
|
||||
|
||||
struct Object *target;
|
||||
char target_layer[128];
|
||||
char target_material[128];
|
||||
|
||||
struct CollectionLANPRLineType contour;
|
||||
struct CollectionLANPRLineType crease;
|
||||
struct CollectionLANPRLineType material;
|
||||
struct CollectionLANPRLineType edge_mark;
|
||||
struct CollectionLANPRLineType intersection;
|
||||
|
||||
int level_start;
|
||||
int level_end;
|
||||
} CollectionLANPR;
|
||||
|
||||
typedef struct Collection {
|
||||
ID id;
|
||||
|
||||
@@ -61,6 +95,9 @@ typedef struct Collection {
|
||||
short tag;
|
||||
char _pad[4];
|
||||
|
||||
/** LANPR engine specific */
|
||||
CollectionLANPR lanpr;
|
||||
|
||||
/* Runtime. Cache of objects in this collection and all its
|
||||
* children. This is created on demand when e.g. some physics
|
||||
* simulation needs it, we don't want to have it for every
|
||||
|
@@ -294,6 +294,8 @@ typedef enum eGPDframe_Flag {
|
||||
GP_FRAME_PAINT = (1 << 0),
|
||||
/* for editing in Action Editor */
|
||||
GP_FRAME_SELECT = (1 << 1),
|
||||
/* LANPR generation */
|
||||
GP_FRAME_LANPR_CLEARED = (1 << 2),
|
||||
} eGPDframe_Flag;
|
||||
|
||||
/* ***************************************** */
|
||||
|
140
source/blender/makesdna/DNA_lanpr_types.h
Normal file
140
source/blender/makesdna/DNA_lanpr_types.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* ***** 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_LANPR_TYPES_H__
|
||||
#define __DNA_LANPR_TYPES_H__
|
||||
|
||||
/** \file DNA_lanpr_types.h
|
||||
* \ingroup DNA
|
||||
*/
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_collection_types.h"
|
||||
|
||||
struct Object;
|
||||
struct Material;
|
||||
struct Collection;
|
||||
|
||||
typedef enum LANPR_TaperSettings {
|
||||
LANPR_USE_DIFFERENT_TAPER = 0,
|
||||
LANPR_USE_SAME_TAPER = 1,
|
||||
} LANPR_TaperSettings;
|
||||
|
||||
typedef enum LANPR_NomalEffect {
|
||||
/* Shouldn't have access to zero value. */
|
||||
/* Enable/disable is another flag. */
|
||||
LANPR_NORMAL_DIRECTIONAL = 1,
|
||||
LANPR_NORMAL_POINT = 2,
|
||||
} LANPR_NomalEffect;
|
||||
|
||||
typedef enum LANPR_ComponentMode {
|
||||
LANPR_COMPONENT_MODE_ALL = 0,
|
||||
LANPR_COMPONENT_MODE_OBJECT = 1,
|
||||
LANPR_COMPONENT_MODE_MATERIAL = 2,
|
||||
LANPR_COMPONENT_MODE_COLLECTION = 3,
|
||||
} LANPR_ComponentMode;
|
||||
|
||||
typedef enum LANPR_ComponentUsage {
|
||||
LANPR_COMPONENT_INCLUSIVE = 0,
|
||||
LANPR_COMPONENT_EXCLUSIVE = 1,
|
||||
} LANPR_ComponentUsage;
|
||||
|
||||
typedef enum LANPR_ComponentLogic {
|
||||
LANPR_COMPONENT_LOGIG_OR = 0,
|
||||
LANPR_COMPONENT_LOGIC_AND = 1,
|
||||
} LANPR_ComponentLogic;
|
||||
|
||||
struct DRWShadingGroup;
|
||||
|
||||
typedef struct LANPR_LineLayerComponent {
|
||||
struct LANPR_LineLayerComponent *next, *prev;
|
||||
|
||||
struct Object *object_select;
|
||||
struct Material *material_select;
|
||||
struct Collection *collection_select;
|
||||
|
||||
int component_mode;
|
||||
int what;
|
||||
|
||||
} LANPR_LineLayerComponent;
|
||||
|
||||
typedef struct LANPR_LineType {
|
||||
int use;
|
||||
float thickness;
|
||||
float color[4];
|
||||
} LANPR_LineType;
|
||||
|
||||
typedef enum LANPR_LineLayerFlags {
|
||||
LANPR_LINE_LAYER_USE_SAME_STYLE = (1 << 0), /* Share with object lanpr flags */
|
||||
LANPR_LINE_LAYER_USE_MULTIPLE_LEVELS = (1 << 1), /* Share with object lanpr flags */
|
||||
LANPR_LINE_LAYER_NORMAL_ENABLED = (1 << 2),
|
||||
LANPR_LINE_LAYER_NORMAL_INVERSE = (1 << 3),
|
||||
LANPR_LINE_LAYER_REPLACE_STROKES = (1 << 4),
|
||||
LANPR_LINE_LAYER_COLLECTION_FORCE = (1 << 5),
|
||||
} LANPR_LineLayerFlags;
|
||||
|
||||
typedef struct LANPR_LineLayer {
|
||||
struct LANPR_LineLayer *next, *prev;
|
||||
|
||||
int flags;
|
||||
int _pad1;
|
||||
int level_start;
|
||||
int level_end;
|
||||
|
||||
/** To be displayed on the list */
|
||||
char name[64];
|
||||
|
||||
LANPR_LineType contour;
|
||||
LANPR_LineType crease;
|
||||
LANPR_LineType edge_mark;
|
||||
LANPR_LineType material_separate;
|
||||
LANPR_LineType intersection;
|
||||
|
||||
float thickness;
|
||||
|
||||
float color[4];
|
||||
|
||||
int normal_mode;
|
||||
float normal_ramp_begin;
|
||||
float normal_ramp_end;
|
||||
float normal_thickness_start;
|
||||
float normal_thickness_end;
|
||||
struct Object *normal_control_object;
|
||||
|
||||
/** For component evaluation */
|
||||
int logic_mode;
|
||||
int _pad3;
|
||||
|
||||
ListBase components;
|
||||
|
||||
struct DRWShadingGroup *shgrp;
|
||||
struct GPUBatch *batch;
|
||||
|
||||
} LANPR_LineLayer;
|
||||
|
||||
#endif
|
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "DNA_defs.h"
|
||||
#include "DNA_customdata_types.h"
|
||||
#include "DNA_lanpr_types.h"
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_ID.h"
|
||||
#include "DNA_action_types.h" /* bAnimVizSettings */
|
||||
@@ -186,6 +187,40 @@ typedef struct Object_Runtime {
|
||||
void *_pad2; /* Padding is here for win32s unconventional struct alignment rules. */
|
||||
} Object_Runtime;
|
||||
|
||||
typedef struct ObjectLANPRLineType {
|
||||
int use;
|
||||
char _pad[4];
|
||||
char target_layer[128];
|
||||
char target_material[128];
|
||||
} ObjectLANPRLineType;
|
||||
|
||||
typedef struct ObjectLANPR {
|
||||
int usage;
|
||||
|
||||
/* Separate flags for LANPR shared flag values. */
|
||||
int flags;
|
||||
|
||||
struct Object *target;
|
||||
char target_layer[128];
|
||||
char target_material[128];
|
||||
|
||||
ObjectLANPRLineType crease;
|
||||
ObjectLANPRLineType contour;
|
||||
ObjectLANPRLineType material;
|
||||
ObjectLANPRLineType edge_mark;
|
||||
/* Intersection not implemented as per-object */
|
||||
|
||||
int level_start;
|
||||
int level_end;
|
||||
} ObjectLANPR;
|
||||
|
||||
enum ObjectFeatureLine_Usage {
|
||||
OBJECT_FEATURE_LINE_INHERENT = 0,
|
||||
OBJECT_FEATURE_LINE_INCLUDE = (1 << 0),
|
||||
OBJECT_FEATURE_LINE_OCCLUSION_ONLY = (1 << 1),
|
||||
OBJECT_FEATURE_LINE_EXCLUDE = (1 << 2),
|
||||
};
|
||||
|
||||
typedef struct Object {
|
||||
ID id;
|
||||
/** Animation data (must be immediately after id for utilities to use it). */
|
||||
@@ -396,6 +431,8 @@ typedef struct Object {
|
||||
|
||||
struct PreviewImage *preview;
|
||||
|
||||
ObjectLANPR lanpr;
|
||||
|
||||
/** Runtime evaluation data (keep last). */
|
||||
Object_Runtime runtime;
|
||||
} Object;
|
||||
|
@@ -1647,6 +1647,79 @@ typedef struct SceneEEVEE {
|
||||
float light_threshold;
|
||||
} SceneEEVEE;
|
||||
|
||||
/* LANPR Global Config */
|
||||
|
||||
struct LANPR_RenderBuffer;
|
||||
struct LANPR_LineLayer;
|
||||
|
||||
typedef enum LANPR_MasterMode {
|
||||
LANPR_MASTER_MODE_SOFTWARE = 0,
|
||||
LANPR_MASTER_MODE_DPIX = 1,
|
||||
LANPR_MASTER_MODE_SNAKE = 2,
|
||||
} LANPR_MasterMode;
|
||||
|
||||
typedef enum LANPR_PostProcessingStatus {
|
||||
LANPR_POST_PROCESSING_DISABLED = 0,
|
||||
LANPR_POST_PROCESSING_ENABLED = 1,
|
||||
} LANPR_PostProcessingStatus;
|
||||
|
||||
typedef enum LANPR_MainFlags {
|
||||
LANPR_ENABLED = (1 << 0),
|
||||
/* For LANPR->GP and viewport to update automatically. */
|
||||
LANPR_AUTO_UPDATE = (1 << 1),
|
||||
LANPR_SAME_TAPER = (1 << 2),
|
||||
/* Edge split modifier will cause problems in LANPR. */
|
||||
LANPR_DISABLE_EDGE_SPLITS = (1 << 3),
|
||||
LANPR_USE_CHAINING = (1 << 4),
|
||||
LANPR_USE_INTERSECTIONS = (1 << 5),
|
||||
/* Overwrite existing strokes in this frame. */
|
||||
LANPR_GPENCIL_OVERWRITE = (1 << 6),
|
||||
} LANPR_MainFlags;
|
||||
|
||||
typedef struct SceneLANPR {
|
||||
|
||||
int flags;
|
||||
|
||||
int master_mode; /* LANPR_MasterMode */
|
||||
|
||||
float taper_left_distance;
|
||||
float taper_left_strength;
|
||||
float taper_right_distance;
|
||||
float taper_right_strength;
|
||||
|
||||
/* shared */
|
||||
|
||||
float contour_fade; /* for dpix contour fading,reserved for future usage */
|
||||
float crease_threshold; /* 0-1 range for cosine angle */
|
||||
float crease_fade_threshold; /* for dpix crease fading */
|
||||
|
||||
float line_color[4];
|
||||
|
||||
float depth_width_influence;
|
||||
float depth_width_curve;
|
||||
float depth_alpha_influence;
|
||||
float depth_alpha_curve;
|
||||
|
||||
int gpu_cache_size; /* enum! */
|
||||
int _pad;
|
||||
|
||||
int enable_chain_connection;
|
||||
|
||||
/* offline render */
|
||||
ListBase line_layers;
|
||||
struct LANPR_LineLayer *active_layer;
|
||||
|
||||
float chaining_geometry_threshold;
|
||||
float chaining_image_threshold;
|
||||
} SceneLANPR;
|
||||
|
||||
enum {
|
||||
LANPR_GPU_CACHE_SIZE_512 = 0,
|
||||
LANPR_GPU_CACHE_SIZE_1K = 1, /* default */
|
||||
LANPR_GPU_CACHE_SIZE_2K = 2,
|
||||
LANPR_GPU_CACHE_SIZE_4K = 3,
|
||||
};
|
||||
|
||||
/* *************************************************************** */
|
||||
/* Scene ID-Block */
|
||||
|
||||
@@ -1777,6 +1850,9 @@ typedef struct Scene {
|
||||
|
||||
struct SceneDisplay display;
|
||||
struct SceneEEVEE eevee;
|
||||
|
||||
/* LANPR stuff */
|
||||
struct SceneLANPR lanpr;
|
||||
} Scene;
|
||||
|
||||
/* **************** RENDERDATA ********************* */
|
||||
|
@@ -195,6 +195,8 @@ typedef enum eSpaceButtons_Context {
|
||||
BCONTEXT_TOOL = 14,
|
||||
BCONTEXT_SHADERFX = 15,
|
||||
BCONTEXT_OUTPUT = 16,
|
||||
BCONTEXT_COLLECTION = 17,
|
||||
BCONTEXT_LANPR = 18,
|
||||
|
||||
/* always as last... */
|
||||
BCONTEXT_TOT,
|
||||
|
@@ -84,6 +84,7 @@ static const char *includefiles[] = {
|
||||
"DNA_mesh_types.h",
|
||||
"DNA_meshdata_types.h",
|
||||
"DNA_modifier_types.h",
|
||||
"DNA_lanpr_types.h",
|
||||
"DNA_lattice_types.h",
|
||||
"DNA_object_types.h",
|
||||
"DNA_object_force_types.h",
|
||||
@@ -1543,6 +1544,7 @@ int main(int argc, char **argv)
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_lanpr_types.h"
|
||||
#include "DNA_lattice_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_object_force_types.h"
|
||||
|
@@ -109,6 +109,7 @@ extern StructRNA RNA_CloudsTexture;
|
||||
extern StructRNA RNA_Collection;
|
||||
extern StructRNA RNA_CollectionEngineSettings;
|
||||
extern StructRNA RNA_CollectionProperty;
|
||||
extern StructRNA RNA_CollectionLANPR;
|
||||
extern StructRNA RNA_CollisionModifier;
|
||||
extern StructRNA RNA_CollisionSensor;
|
||||
extern StructRNA RNA_CollisionSettings;
|
||||
@@ -451,6 +452,7 @@ extern StructRNA RNA_NormalEditModifier;
|
||||
extern StructRNA RNA_Object;
|
||||
extern StructRNA RNA_ObjectBase;
|
||||
extern StructRNA RNA_ObjectDisplay;
|
||||
extern StructRNA RNA_ObjectLANPR;
|
||||
extern StructRNA RNA_ObstacleFluidSettings;
|
||||
extern StructRNA RNA_OceanModifier;
|
||||
extern StructRNA RNA_OceanTexData;
|
||||
@@ -523,6 +525,7 @@ extern StructRNA RNA_SPHFluidSettings;
|
||||
extern StructRNA RNA_Scene;
|
||||
extern StructRNA RNA_SceneDisplay;
|
||||
extern StructRNA RNA_SceneEEVEE;
|
||||
extern StructRNA RNA_SceneLANPR;
|
||||
extern StructRNA RNA_SceneObjects;
|
||||
extern StructRNA RNA_SceneRenderLayer;
|
||||
extern StructRNA RNA_SceneSequence;
|
||||
|
@@ -53,6 +53,7 @@ set(DEFSRC
|
||||
rna_light.c
|
||||
rna_lightprobe.c
|
||||
rna_linestyle.c
|
||||
rna_lanpr.c
|
||||
rna_main.c
|
||||
rna_mask.c
|
||||
rna_material.c
|
||||
@@ -393,6 +394,7 @@ set(LIB
|
||||
bf_editor_object
|
||||
bf_editor_physics
|
||||
bf_editor_render
|
||||
bf_editor_lanpr
|
||||
bf_editor_scene
|
||||
bf_editor_sculpt_paint
|
||||
bf_editor_space_clip
|
||||
|
@@ -4233,6 +4233,7 @@ static RNAProcessItem PROCESS_ITEMS[] = {
|
||||
{"rna_lattice.c", "rna_lattice_api.c", RNA_def_lattice},
|
||||
{"rna_layer.c", NULL, RNA_def_view_layer},
|
||||
{"rna_linestyle.c", NULL, RNA_def_linestyle},
|
||||
{"rna_lanpr.c", NULL, RNA_def_lanpr},
|
||||
{"rna_main.c", "rna_main_api.c", RNA_def_main},
|
||||
{"rna_material.c", "rna_material_api.c", RNA_def_material},
|
||||
{"rna_mesh.c", "rna_mesh_api.c", RNA_def_mesh},
|
||||
|
@@ -22,6 +22,8 @@
|
||||
|
||||
#include "DNA_collection_types.h"
|
||||
|
||||
#include "DNA_lanpr_types.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
@@ -365,6 +367,115 @@ static void rna_def_collection_children(BlenderRNA *brna, PropertyRNA *cprop)
|
||||
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||
}
|
||||
|
||||
static void rna_def_collection_lanpr(BlenderRNA *brna)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
StructRNA *srna;
|
||||
|
||||
srna = RNA_def_struct(brna, "CollectionLANPRLineType", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Collection LANPR Line Type", "Collection lanpr line type");
|
||||
RNA_def_struct_sdna(srna, "CollectionLANPRLineType");
|
||||
|
||||
prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Use", "Use this line type");
|
||||
|
||||
prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "target_layer");
|
||||
RNA_def_property_ui_text(prop, "Layer", "Grease Pencil layer to put the results into");
|
||||
|
||||
prop = RNA_def_property(srna, "material", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "target_material");
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Material", "Grease Pencil material to use to generate the results");
|
||||
|
||||
static const EnumPropertyItem rna_collection_lanpr_usage[] = {
|
||||
{COLLECTION_FEATURE_LINE_INCLUDE,
|
||||
"INCLUDE",
|
||||
0,
|
||||
"Include",
|
||||
"Collection will produce feature lines"},
|
||||
{COLLECTION_FEATURE_LINE_OCCLUSION_ONLY,
|
||||
"OCCLUSION_ONLY",
|
||||
0,
|
||||
"Occlusion Only",
|
||||
"Only use the collection to produce occlusion"},
|
||||
{COLLECTION_FEATURE_LINE_EXCLUDE,
|
||||
"EXCLUDE",
|
||||
0,
|
||||
"Exclude",
|
||||
"Don't use this collection in LANPR"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
srna = RNA_def_struct(brna, "CollectionLANPR", NULL);
|
||||
RNA_def_struct_sdna(srna, "CollectionLANPR");
|
||||
RNA_def_struct_ui_text(srna, "Collection LANPR Usage", "LANPR usage for this collection");
|
||||
|
||||
prop = RNA_def_property(srna, "usage", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_collection_lanpr_usage);
|
||||
RNA_def_property_ui_text(prop, "Usage", "How to use this collection in LANPR");
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "force", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_LINE_LAYER_COLLECTION_FORCE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Force", "Force object that has LANPR modifiers to follow collection usage flag");
|
||||
|
||||
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "target");
|
||||
RNA_def_property_ui_text(prop, "Target", "Grease Pencil object to put the stroke result");
|
||||
RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_GPencil_object_poll");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
|
||||
|
||||
prop = RNA_def_property(srna, "replace", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_LINE_LAYER_REPLACE_STROKES);
|
||||
RNA_def_property_ui_text(prop, "Replace", "Replace existing GP frames");
|
||||
|
||||
prop = RNA_def_property(srna, "target_layer", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Layer", "Grease Pencil layer to put the results into");
|
||||
|
||||
prop = RNA_def_property(srna, "target_material", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Material", "Grease Pencil material to use to generate the results");
|
||||
|
||||
prop = RNA_def_property(srna, "use_same_style", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_LINE_LAYER_USE_SAME_STYLE);
|
||||
RNA_def_property_ui_text(prop, "Same Style", "Use same style for different types");
|
||||
|
||||
prop = RNA_def_property(srna, "contour", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "CollectionLANPRLineType");
|
||||
RNA_def_property_ui_text(prop, "Contour", "Contour line type");
|
||||
|
||||
prop = RNA_def_property(srna, "crease", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "CollectionLANPRLineType");
|
||||
RNA_def_property_ui_text(prop, "Crease", "Creaseline type");
|
||||
|
||||
prop = RNA_def_property(srna, "edge_mark", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "CollectionLANPRLineType");
|
||||
RNA_def_property_ui_text(prop, "Edge Mark", "Edge mark line type");
|
||||
|
||||
prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "CollectionLANPRLineType");
|
||||
RNA_def_property_ui_text(prop, "Material", "Material separate line type");
|
||||
|
||||
prop = RNA_def_property(srna, "intersection", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "CollectionLANPRLineType");
|
||||
RNA_def_property_ui_text(prop, "Intersection", "Intersection line type");
|
||||
|
||||
prop = RNA_def_property(srna, "use_multiple_levels", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_LINE_LAYER_USE_MULTIPLE_LEVELS);
|
||||
RNA_def_property_ui_text(prop, "Multiple Levels", "Use multiple occlusion levels");
|
||||
|
||||
prop = RNA_def_property(srna, "level_start", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0, 255);
|
||||
RNA_def_property_ui_range(prop, 0, 255, 1, -1);
|
||||
RNA_def_property_ui_text(prop, "Level Start", "Occlusion level start");
|
||||
|
||||
prop = RNA_def_property(srna, "level_end", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0, 255);
|
||||
RNA_def_property_ui_range(prop, 0, 255, 1, -1);
|
||||
RNA_def_property_ui_text(prop, "Level End", "Occlusion level end");
|
||||
}
|
||||
|
||||
void RNA_def_collections(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -458,6 +569,11 @@ void RNA_def_collections(BlenderRNA *brna)
|
||||
RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, -1);
|
||||
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");
|
||||
|
||||
rna_def_collection_lanpr(brna);
|
||||
prop = RNA_def_property(srna, "lanpr", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "CollectionLANPR");
|
||||
RNA_def_property_ui_text(prop, "LANPR", "LANPR settings for the collection");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -165,6 +165,7 @@ void RNA_def_key(struct BlenderRNA *brna);
|
||||
void RNA_def_light(struct BlenderRNA *brna);
|
||||
void RNA_def_lattice(struct BlenderRNA *brna);
|
||||
void RNA_def_linestyle(struct BlenderRNA *brna);
|
||||
void RNA_def_lanpr(struct BlenderRNA *brna);
|
||||
void RNA_def_main(struct BlenderRNA *brna);
|
||||
void RNA_def_material(struct BlenderRNA *brna);
|
||||
void RNA_def_mesh(struct BlenderRNA *brna);
|
||||
|
235
source/blender/makesrna/intern/rna_lanpr.c
Normal file
235
source/blender/makesrna/intern/rna_lanpr.c
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* ***** 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.
|
||||
*
|
||||
* Contributor(s): Blender Foundation (2008).
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/makesrna/intern/rna_lanpr.c
|
||||
* \ingroup RNA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "rna_internal.h"
|
||||
|
||||
#include "DNA_lanpr_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
#include "WM_api.h"
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
#else
|
||||
|
||||
static void rna_def_lanpr_line_layer(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static const EnumPropertyItem rna_enum_lanpr_normal_mode[] = {
|
||||
{LANPR_NORMAL_DIRECTIONAL,
|
||||
"DIRECTIONAL",
|
||||
0,
|
||||
"Directional",
|
||||
"Use directional vector to control line width"},
|
||||
/* Seems working... */
|
||||
{LANPR_NORMAL_POINT, "POINT", 0, "Point", "Use Point Light Style"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
srna = RNA_def_struct(brna, "LANPR_LineLayer", NULL);
|
||||
RNA_def_struct_sdna(srna, "LANPR_LineLayer");
|
||||
RNA_def_struct_ui_text(srna, "Line Layer", "LANPR_LineLayer");
|
||||
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Name", "Name of this layer");
|
||||
|
||||
prop = RNA_def_property(srna, "normal_enabled", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_LINE_LAYER_NORMAL_ENABLED);
|
||||
RNA_def_property_ui_text(prop, "Enabled", "Enable normal controlled line weight");
|
||||
|
||||
prop = RNA_def_property(srna, "normal_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_lanpr_normal_mode);
|
||||
RNA_def_property_ui_text(prop, "Normal", "Normal controlled line weight");
|
||||
|
||||
prop = RNA_def_property(srna, "normal_effect_inverse", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_LINE_LAYER_NORMAL_INVERSE);
|
||||
RNA_def_property_ui_text(prop, "Inverse", "Inverse normal effect");
|
||||
|
||||
prop = RNA_def_property(
|
||||
srna, "normal_ramp_begin", PROP_FLOAT, PROP_FACTOR); /* begin is least strength */
|
||||
RNA_def_property_float_default(prop, 0.0f);
|
||||
RNA_def_property_ui_text(prop, "Ramp Begin", "Normal ramp begin value");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.05, 2);
|
||||
|
||||
prop = RNA_def_property(srna, "normal_ramp_end", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_default(prop, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Ramp End", "Normal ramp end value");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.05, 2);
|
||||
|
||||
prop = RNA_def_property(
|
||||
srna, "normal_thickness_start", PROP_FLOAT, PROP_NONE); /* begin is least strength */
|
||||
RNA_def_property_float_default(prop, 0.2f);
|
||||
RNA_def_property_ui_text(prop, "Thickness Begin", "Normal thickness begin value");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 5.0f, 0.05, 2);
|
||||
|
||||
prop = RNA_def_property(srna, "normal_thickness_end", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_default(prop, 1.5f);
|
||||
RNA_def_property_ui_text(prop, "Thickness End", "Normal thickness end value");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 5.0f, 0.05, 2);
|
||||
|
||||
prop = RNA_def_property(srna, "normal_control_object", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "Object");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Object", "Normal style control object");
|
||||
|
||||
prop = RNA_def_property(srna, "use_same_style", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_LINE_LAYER_USE_SAME_STYLE);
|
||||
RNA_def_property_boolean_default(prop, true);
|
||||
RNA_def_property_ui_text(prop, "Same Style", "Use same styles for multiple line types.");
|
||||
|
||||
prop = RNA_def_property(srna, "use_multiple_levels", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_LINE_LAYER_USE_MULTIPLE_LEVELS);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Use Multiple Levels", "Select lines from multiple occlusion levels");
|
||||
|
||||
/* types */
|
||||
prop = RNA_def_property(srna, "contour", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "LANPR_LineType");
|
||||
RNA_def_property_ui_text(prop, "Contour", "Contour line type");
|
||||
|
||||
prop = RNA_def_property(srna, "crease", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "LANPR_LineType");
|
||||
RNA_def_property_ui_text(prop, "Crease", "Creaseline type");
|
||||
|
||||
prop = RNA_def_property(srna, "edge_mark", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "LANPR_LineType");
|
||||
RNA_def_property_ui_text(prop, "Edge Mark", "Edge mark line type");
|
||||
|
||||
prop = RNA_def_property(srna, "material_separate", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "LANPR_LineType");
|
||||
RNA_def_property_ui_text(prop, "Material Separate", "Material separate line type");
|
||||
|
||||
prop = RNA_def_property(srna, "intersection", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "LANPR_LineType");
|
||||
RNA_def_property_ui_text(prop, "Intersection", "Intersection line type");
|
||||
|
||||
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", "Occlusion level start");
|
||||
RNA_def_property_range(prop, 0, 128);
|
||||
|
||||
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", "Occlusion level end");
|
||||
RNA_def_property_range(prop, 0, 128);
|
||||
|
||||
prop = RNA_def_property(srna, "thickness", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_default(prop, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Thickness", "Master Thickness");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 100.0f, 0.1, 2);
|
||||
|
||||
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
|
||||
RNA_def_property_float_default(prop, 1.0f);
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_ui_text(prop, "Color", "Master Color");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 2);
|
||||
|
||||
prop = RNA_def_property(srna, "components", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "components", NULL);
|
||||
RNA_def_property_struct_type(prop, "LANPR_LineLayerComponent");
|
||||
RNA_def_property_ui_text(prop, "Components", "Line Layer Components");
|
||||
}
|
||||
|
||||
static void rna_def_lanpr_line_type(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "LANPR_LineType", NULL);
|
||||
RNA_def_struct_sdna(srna, "LANPR_LineType");
|
||||
RNA_def_struct_ui_text(srna, "Line Type", "LANPR_LineType");
|
||||
|
||||
prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Use", "This line type is enabled");
|
||||
|
||||
prop = RNA_def_property(srna, "thickness", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_default(prop, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Thickness", "Relative thickness to master");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 2.0f, 0.01, 2);
|
||||
|
||||
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
|
||||
RNA_def_property_float_default(prop, 1.0f);
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_ui_text(prop, "Color", "Color of this line type");
|
||||
}
|
||||
|
||||
static void rna_def_lanpr_line_component(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static const EnumPropertyItem lanpr_line_component_modes[] = {
|
||||
{0, "ALL", 0, "All", "Show all lines, lines are already selected are not affected"},
|
||||
{1, "OBJECT", 0, "Object", "Filter lines for selected object"},
|
||||
{2, "MATERIAL", 0, "Material", "Filter lines that touches specific material"},
|
||||
{3, "COLLECTION", 0, "Collection", "Filter lines in specific collections"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
srna = RNA_def_struct(brna, "LANPR_LineLayerComponent", NULL);
|
||||
RNA_def_struct_sdna(srna, "LANPR_LineLayerComponent");
|
||||
RNA_def_struct_ui_text(srna, "Line Layer Component", "LANPR_LineLayerComponent");
|
||||
|
||||
prop = RNA_def_property(srna, "component_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, lanpr_line_component_modes);
|
||||
RNA_def_property_enum_default(prop, 0);
|
||||
RNA_def_property_ui_text(prop, "Mode", "Limit the range of displayed lines");
|
||||
|
||||
prop = RNA_def_property(srna, "object_select", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "Object");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Object", "Display lines for selected object");
|
||||
|
||||
prop = RNA_def_property(srna, "material_select", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "Material");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Material", "Display lines that touches specific material");
|
||||
|
||||
prop = RNA_def_property(srna, "collection_select", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "Collection");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Collection", "Display lines in specific collections");
|
||||
}
|
||||
|
||||
void RNA_def_lanpr(BlenderRNA *brna)
|
||||
{
|
||||
rna_def_lanpr_line_component(brna);
|
||||
rna_def_lanpr_line_type(brna);
|
||||
rna_def_lanpr_line_layer(brna);
|
||||
}
|
||||
|
||||
#endif
|
@@ -2371,6 +2371,110 @@ static void rna_def_object_display(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Shadow", "Object cast shadows in the 3d viewport");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
|
||||
}
|
||||
static void rna_def_object_lanpr(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "ObjectLANPRLineType", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Object LANPR Line Type", "Object lanpr line type");
|
||||
RNA_def_struct_sdna(srna, "ObjectLANPRLineType");
|
||||
|
||||
prop = RNA_def_property(srna, "use", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Use", "Use this line type");
|
||||
|
||||
prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "target_layer");
|
||||
RNA_def_property_ui_text(prop, "Layer", "Grease Pencil layer to put the results into");
|
||||
|
||||
prop = RNA_def_property(srna, "material", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "target_material");
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Material", "Grease Pencil material to use to generate the results");
|
||||
|
||||
static EnumPropertyItem prop_feature_line_usage_items[] = {
|
||||
{OBJECT_FEATURE_LINE_INHERENT,
|
||||
"INHEREIT",
|
||||
0,
|
||||
"Inhereit",
|
||||
"Follow settings from the parent collection"},
|
||||
{OBJECT_FEATURE_LINE_INCLUDE,
|
||||
"INCLUDE",
|
||||
0,
|
||||
"Include",
|
||||
"Include this object into LANPR calculation"},
|
||||
{OBJECT_FEATURE_LINE_OCCLUSION_ONLY,
|
||||
"OCCLUSION_ONLY",
|
||||
0,
|
||||
"Occlusion Only",
|
||||
"Don't produce lines, only used as occlusion object"},
|
||||
{OBJECT_FEATURE_LINE_EXCLUDE,
|
||||
"EXCLUDE",
|
||||
0,
|
||||
"Exclude",
|
||||
"Don't use this object for LANPR rendering"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "ObjectLANPR", NULL);
|
||||
RNA_def_struct_ui_text(srna, "Object LANPR", "Object lanpr settings");
|
||||
RNA_def_struct_sdna(srna, "ObjectLANPR");
|
||||
|
||||
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");
|
||||
|
||||
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "target");
|
||||
RNA_def_property_ui_text(prop, "Target", "GPencil object to put the stroke result");
|
||||
RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_GPencil_object_poll");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
|
||||
|
||||
prop = RNA_def_property(srna, "replace", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_LINE_LAYER_REPLACE_STROKES);
|
||||
RNA_def_property_ui_text(prop, "Replace", "Replace existing GP frames");
|
||||
|
||||
prop = RNA_def_property(srna, "target_layer", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Layer", "Grease Pencil layer to put the results into");
|
||||
|
||||
prop = RNA_def_property(srna, "target_material", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Material", "Grease Pencil material to use to generate the results");
|
||||
|
||||
prop = RNA_def_property(srna, "use_same_style", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_LINE_LAYER_USE_SAME_STYLE);
|
||||
RNA_def_property_ui_text(prop, "Same Style", "Use same style for different line types");
|
||||
|
||||
prop = RNA_def_property(srna, "contour", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "ObjectLANPRLineType");
|
||||
RNA_def_property_ui_text(prop, "Contour", "Contour line type");
|
||||
|
||||
prop = RNA_def_property(srna, "crease", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "ObjectLANPRLineType");
|
||||
RNA_def_property_ui_text(prop, "Crease", "Creaseline type");
|
||||
|
||||
prop = RNA_def_property(srna, "edge_mark", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "ObjectLANPRLineType");
|
||||
RNA_def_property_ui_text(prop, "Edge Mark", "Edge mark line type");
|
||||
|
||||
prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "ObjectLANPRLineType");
|
||||
RNA_def_property_ui_text(prop, "Material", "Material separate line type");
|
||||
|
||||
prop = RNA_def_property(srna, "use_multiple_levels", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_LINE_LAYER_USE_MULTIPLE_LEVELS);
|
||||
RNA_def_property_ui_text(prop, "Multiple Levels", "Use multiple occlusion levels");
|
||||
|
||||
prop = RNA_def_property(srna, "level_start", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0, 255);
|
||||
RNA_def_property_ui_range(prop, 0, 255, 1, -1);
|
||||
RNA_def_property_ui_text(prop, "Level Start", "Occlusion level start");
|
||||
|
||||
prop = RNA_def_property(srna, "level_end", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 0, 255);
|
||||
RNA_def_property_ui_range(prop, 0, 255, 1, -1);
|
||||
RNA_def_property_ui_text(prop, "Level End", "Occlusion level end");
|
||||
}
|
||||
|
||||
static void rna_def_object(BlenderRNA *brna)
|
||||
{
|
||||
@@ -3116,6 +3220,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");
|
||||
|
||||
/* LANPR */
|
||||
prop = RNA_def_property(srna, "lanpr", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "ObjectLANPR");
|
||||
RNA_def_property_ui_text(prop, "LANPR", "LANPR settings for the object");
|
||||
|
||||
RNA_api_object(srna);
|
||||
}
|
||||
|
||||
@@ -3128,6 +3237,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_lanpr(brna);
|
||||
RNA_define_animate_sdna(true);
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include "DNA_gpencil_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_screen_types.h" /* TransformOrientation */
|
||||
#include "DNA_lanpr_types.h"
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
@@ -2494,6 +2495,64 @@ static char *rna_UnitSettings_path(PointerRNA *UNUSED(ptr))
|
||||
return BLI_strdup("unit_settings");
|
||||
}
|
||||
|
||||
/* lanpr */
|
||||
|
||||
void rna_lanpr_active_line_layer_index_range(
|
||||
PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
|
||||
{
|
||||
SceneLANPR *lanpr = (SceneLANPR *)ptr->data;
|
||||
*min = 0;
|
||||
*max = max_ii(0, BLI_listbase_count(&lanpr->line_layers) - 1);
|
||||
}
|
||||
|
||||
int rna_lanpr_active_line_layer_index_get(PointerRNA *ptr)
|
||||
{
|
||||
SceneLANPR *lanpr = (SceneLANPR *)ptr->data;
|
||||
LANPR_LineLayer *ls;
|
||||
int i = 0;
|
||||
for (ls = lanpr->line_layers.first; ls; ls = ls->next) {
|
||||
if (ls == lanpr->active_layer)
|
||||
return i;
|
||||
i++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rna_lanpr_active_line_layer_index_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
SceneLANPR *lanpr = (SceneLANPR *)ptr->data;
|
||||
LANPR_LineLayer *ls;
|
||||
int i = 0;
|
||||
for (ls = lanpr->line_layers.first; ls; ls = ls->next) {
|
||||
if (i == value) {
|
||||
lanpr->active_layer = ls;
|
||||
return;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
lanpr->active_layer = 0;
|
||||
}
|
||||
|
||||
PointerRNA rna_lanpr_active_line_layer_get(PointerRNA *ptr)
|
||||
{
|
||||
SceneLANPR *lanpr = (SceneLANPR *)ptr->data;
|
||||
LANPR_LineLayer *ls = lanpr->active_layer;
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_LANPR_LineLayer, ls);
|
||||
}
|
||||
|
||||
void rna_lanpr_active_line_layer_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
SceneLANPR *lanpr = (SceneLANPR *)ptr->data;
|
||||
lanpr->active_layer = value.data;
|
||||
}
|
||||
|
||||
extern bool ED_lanpr_dpix_shader_error(void);
|
||||
|
||||
static bool rna_lanpr_shader_error_get(PointerRNA *UNUSED(ptr))
|
||||
{
|
||||
return ED_lanpr_dpix_shader_error();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Grease Pencil Interpolation tool settings */
|
||||
@@ -7078,6 +7137,225 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
}
|
||||
|
||||
static void rna_def_scene_lanpr(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static const EnumPropertyItem rna_enum_lanpr_master_mode[] = {
|
||||
{LANPR_MASTER_MODE_SOFTWARE, "SOFTWARE", 0, "CPU", "Software edge calculation"},
|
||||
{LANPR_MASTER_MODE_DPIX, "DPIX", 0, "GPU", "DPIX GPU edge extraction"},
|
||||
/* Temporally remove image filter mode. */
|
||||
/* {LANPR_MASTER_MODE_SNAKE, "SNAKE", 0, "Edge Detection", "Edge detection filter and
|
||||
tracing"}, */
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static const EnumPropertyItem rna_enum_lanpr_use_same_taper[] = {
|
||||
{LANPR_USE_DIFFERENT_TAPER, "DISABLED", 0, "Different", "Use different taper value"},
|
||||
{LANPR_USE_SAME_TAPER,
|
||||
"ENABLED",
|
||||
0,
|
||||
"Same",
|
||||
"Use same taper value for both sides of the line"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
static const EnumPropertyItem rna_enum_lanpr_gpu_cache_size[] = {
|
||||
{LANPR_GPU_CACHE_SIZE_512, "S512", 0, "512", "512px texture as cache"},
|
||||
{LANPR_GPU_CACHE_SIZE_1K, "S1K", 0, "1K", "1K px texture as cache"},
|
||||
{LANPR_GPU_CACHE_SIZE_2K, "S2K", 0, "2K", "2K px texture as cache"},
|
||||
{LANPR_GPU_CACHE_SIZE_4K, "S4K", 0, "4K", "4K px texture as cache"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
srna = RNA_def_struct(brna, "SceneLANPR", NULL);
|
||||
RNA_def_struct_sdna(srna, "SceneLANPR");
|
||||
RNA_def_struct_ui_text(srna, "Scene LANPR Config", "LANPR global config");
|
||||
|
||||
prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_ENABLED);
|
||||
RNA_def_property_ui_text(prop, "Enabled", "Is LANPR enabled");
|
||||
RNA_def_property_update(prop, NC_WINDOW, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "auto_update", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_AUTO_UPDATE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Auto Update", "Automatically update LANPR cache when frame changes");
|
||||
|
||||
prop = RNA_def_property(srna, "gpencil_overwrite", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_GPENCIL_OVERWRITE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"GPencil Overwrite",
|
||||
"Overwrite existing strokes in the current frame of target GP objects");
|
||||
|
||||
prop = RNA_def_property(srna, "master_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_lanpr_master_mode);
|
||||
RNA_def_property_enum_default(prop, LANPR_MASTER_MODE_DPIX);
|
||||
RNA_def_property_ui_text(prop, "Master Mode", "Choose calculation mode for NPR Line");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "gpu_cache_size", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_lanpr_gpu_cache_size);
|
||||
RNA_def_property_enum_default(prop, LANPR_GPU_CACHE_SIZE_512);
|
||||
RNA_def_property_ui_text(prop, "GPU Cache Size", "Texture cache size for DPIX algorithm");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "depth_width_influence", PROP_FLOAT, PROP_PERCENTAGE);
|
||||
RNA_def_property_float_default(prop, 0.3f);
|
||||
RNA_def_property_ui_text(prop, "Width Influence", "Use camera distance to control line width.");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.05, 2);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "depth_width_curve", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_default(prop, 0.3f);
|
||||
RNA_def_property_ui_text(prop, "Width Curve", "Width curve");
|
||||
RNA_def_property_ui_range(prop, -5.0f, 0.90f, 0.1, 1);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "depth_alpha_influence", PROP_FLOAT, PROP_PERCENTAGE);
|
||||
RNA_def_property_float_default(prop, 0.3f);
|
||||
RNA_def_property_ui_text(prop, "Alpha Influence", "Use camera distance to control line alpha.");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.05, 2);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "depth_alpha_curve", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_default(prop, 0.3f);
|
||||
RNA_def_property_ui_text(prop, "Alpha Curve", "alpha curve");
|
||||
RNA_def_property_ui_range(prop, -5.0f, 0.90f, 0.1, 1);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "taper_left_distance", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_default(prop, 20.0f);
|
||||
RNA_def_property_ui_text(prop, "Left Distance", "Left side taper distance");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 100.0f, 0.1, 2);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "taper_right_distance", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_default(prop, 20.0f);
|
||||
RNA_def_property_ui_text(prop, "Right Distance", "Right side taper distance");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 100.0f, 0.1, 2);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "taper_left_strength", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_default(prop, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Left Strength", "Left side taper strength");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 2);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "taper_right_strength", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_default(prop, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Right Strength", "Right side taper strength");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 2);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_same_taper", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_SAME_TAPER);
|
||||
RNA_def_property_ui_text(prop, "Same Taper", "Same/Different taper value");
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "line_color", PROP_FLOAT, PROP_COLOR);
|
||||
RNA_def_property_float_default(prop, 1.0f);
|
||||
RNA_def_property_array(prop, 4);
|
||||
RNA_def_property_ui_text(prop, "Line Color", "Drawing lines using this color");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 2);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "crease_threshold", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_default(prop, 0.5f);
|
||||
RNA_def_property_ui_text(prop, "Crease Threshold", "cosine value of face angle");
|
||||
RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.01, 2);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "crease_fade_threshold", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_default(prop, 0.5f);
|
||||
RNA_def_property_ui_text(prop, "Crease Fade", "cosine value of face angle");
|
||||
RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.01, 2);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_intersections", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_USE_INTERSECTIONS);
|
||||
RNA_def_property_boolean_default(prop, 1);
|
||||
RNA_def_property_ui_text(prop, "Calculate Intersections", "Calculate Intersections or not");
|
||||
|
||||
prop = RNA_def_property(srna, "enable_chaining", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flags", LANPR_USE_CHAINING);
|
||||
RNA_def_property_boolean_default(prop, 1);
|
||||
RNA_def_property_ui_text(prop, "Enable Chaining", "Chain Feature Lines After Occlusion Test");
|
||||
|
||||
prop = RNA_def_property(srna, "enable_chain_connection", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 1);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Enable Chain Connection",
|
||||
"Connect short chains in the image space into one longer chain");
|
||||
|
||||
/* should be read-only */
|
||||
prop = RNA_def_property(srna, "shader_error", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_default(prop, 0);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_lanpr_shader_error_get", "");
|
||||
RNA_def_property_ui_text(
|
||||
prop, "DPIX Shader Error", "Can't compile DPIX transform shader on your GPU.");
|
||||
|
||||
prop = RNA_def_property(srna, "chaining_geometry_threshold", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_default(prop, 0.1f);
|
||||
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, 1.0f, 0.01, 3);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
|
||||
prop = RNA_def_property(srna, "chaining_image_threshold", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_default(prop, 0.01f);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Image Threshold",
|
||||
"Segments where their image distance between them lower than this will be chained together");
|
||||
RNA_def_property_ui_range(prop, 0.0f, 0.3f, 0.001, 4);
|
||||
RNA_def_property_range(prop, 0.0f, 0.3f);
|
||||
|
||||
/* here's the collection stuff.... */
|
||||
|
||||
prop = RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "line_layers", NULL);
|
||||
RNA_def_property_struct_type(prop, "LANPR_LineLayer");
|
||||
RNA_def_property_ui_text(prop, "Line Layers", "LANPR Line Layers");
|
||||
|
||||
/* this part I refered to gpencil's and freestyle's and it seems that there's no difference */
|
||||
RNA_def_property_srna(prop, "LineLayers");
|
||||
srna = RNA_def_struct(brna, "LineLayers", NULL);
|
||||
RNA_def_struct_sdna(srna, "SceneLANPR");
|
||||
RNA_def_struct_ui_text(srna, "LANPR Line Layers", "");
|
||||
|
||||
prop = RNA_def_property(srna, "active_layer", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "LANPR_LineLayer");
|
||||
RNA_def_property_pointer_funcs(
|
||||
prop, "rna_lanpr_active_line_layer_get", "rna_lanpr_active_line_layer_set", NULL, NULL);
|
||||
RNA_def_property_ui_text(prop, "Active Line Layer", "Active line layer being displayed");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "active_layer_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_funcs(prop,
|
||||
"rna_lanpr_active_line_layer_index_get",
|
||||
"rna_lanpr_active_line_layer_index_set",
|
||||
"rna_lanpr_active_line_layer_index_range");
|
||||
RNA_def_property_ui_text(prop, "Active Line Layer Index", "Index of active line layer slot");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
|
||||
}
|
||||
|
||||
void RNA_def_scene(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -7551,6 +7829,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");
|
||||
|
||||
/* LANPR */
|
||||
prop = RNA_def_property(srna, "lanpr", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "SceneLANPR");
|
||||
RNA_def_property_ui_text(prop, "LANPR", "LANPR settings for the scene");
|
||||
|
||||
/* Nestled Data */
|
||||
/* *** Non-Animated *** */
|
||||
RNA_define_animate_sdna(false);
|
||||
@@ -7568,6 +7851,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_lanpr(brna);
|
||||
RNA_define_animate_sdna(true);
|
||||
/* *** Animated *** */
|
||||
rna_def_scene_render_data(brna);
|
||||
|
@@ -384,26 +384,24 @@ const EnumPropertyItem rna_enum_clip_editor_mode_items[] = {
|
||||
* but helps for context-less access (e.g. doc, i18n...). */
|
||||
static const EnumPropertyItem buttons_context_items[] = {
|
||||
{BCONTEXT_TOOL, "TOOL", ICON_TOOL_SETTINGS, "Tool", "Active Tool and Workspace settings"},
|
||||
{BCONTEXT_SCENE, "SCENE", ICON_SCENE_DATA, "Scene", "Scene Properties"},
|
||||
{BCONTEXT_RENDER, "RENDER", ICON_SCENE, "Render", "Render Properties"},
|
||||
{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_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_DATA, "DATA", ICON_NONE, "Data", "Object Data Properties"},
|
||||
{BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone Properties"},
|
||||
{BCONTEXT_SCENE, "SCENE", ICON_SCENE_DATA, "Scene", "Scene"},
|
||||
{BCONTEXT_RENDER, "RENDER", ICON_SCENE, "Render", "Render"},
|
||||
{BCONTEXT_OUTPUT, "OUTPUT", ICON_OUTPUT, "Output", "Output"},
|
||||
{BCONTEXT_VIEW_LAYER, "VIEW_LAYER", ICON_RENDER_RESULT, "View Layer", "View Layer"},
|
||||
{BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"},
|
||||
{BCONTEXT_COLLECTION, "COLLECTION", ICON_GROUP, "Collection", "Collection"},
|
||||
{BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"},
|
||||
{BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Object Constraints"},
|
||||
{BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Modifiers"},
|
||||
{BCONTEXT_DATA, "DATA", ICON_NONE, "Data", "Object Data"},
|
||||
{BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"},
|
||||
{BCONTEXT_BONE_CONSTRAINT,
|
||||
"BONE_CONSTRAINT",
|
||||
ICON_CONSTRAINT_BONE,
|
||||
"Bone Constraints",
|
||||
"Bone Constraint Properties"},
|
||||
{BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material Properties"},
|
||||
{BCONTEXT_LANPR, "LANPR", ICON_SHADING_RENDERED, "LANPR", "LANPR Data"},
|
||||
{BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture Properties"},
|
||||
{BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle Properties"},
|
||||
{BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics Properties"},
|
||||
@@ -1655,6 +1653,14 @@ static const EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *UNUSE
|
||||
RNA_enum_item_add_separator(&item, &totitem);
|
||||
}
|
||||
|
||||
if (sbuts->pathflag & (1 << BCONTEXT_COLLECTION)) {
|
||||
RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_COLLECTION);
|
||||
}
|
||||
|
||||
if (totitem) {
|
||||
RNA_enum_item_add_separator(&item, &totitem);
|
||||
}
|
||||
|
||||
if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) {
|
||||
RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_OBJECT);
|
||||
}
|
||||
@@ -1696,6 +1702,10 @@ static const EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *UNUSE
|
||||
RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MATERIAL);
|
||||
}
|
||||
|
||||
if (sbuts->pathflag & (1 << BCONTEXT_LANPR)) {
|
||||
RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_LANPR);
|
||||
}
|
||||
|
||||
if (totitem) {
|
||||
RNA_enum_item_add_separator(&item, &totitem);
|
||||
}
|
||||
|
Submodule source/tools updated: 7b740545cd...2afbb8ec47
Reference in New Issue
Block a user