feat(shaders_lab): visual node editor (imgui-node-editor) + multi-source

- cpp/vendor/imgui-node-editor: vendorized thedmd/imgui-node-editor v0.9.4
- cpp/functions/gfx/dag_node_editor: new visual pipeline editor replacing dag_panel
- DagStep: source_ids[4] + editor_pos + editor_uid (multi-input support)
- DagNodeDef: num_inputs explicit; circle reclassified as Op
- dag_compile: N inputs per node, topological ordering preserved
- main: use node editor; destroy on shutdown
- patch imgui_extra_math.inl: guard operator*(float, ImVec2) for imgui >= 18955

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-24 21:55:43 +02:00
parent bf5011de93
commit 88fca7b128
89 changed files with 22289 additions and 41 deletions
@@ -0,0 +1,17 @@
if (TARGET ScopeGuard)
return()
endif()
set(_ScopeGuard_SourceDir ${IMGUI_NODE_EDITOR_ROOT_DIR}/external/ScopeGuard)
set(_ScopeGuard_BinaryDir ${CMAKE_BINARY_DIR}/external/ScopeGuard)
add_subdirectory(${_ScopeGuard_SourceDir} ${_ScopeGuard_BinaryDir})
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(
ScopeGuard
REQUIRED_VARS
_ScopeGuard_SourceDir
)
@@ -0,0 +1,17 @@
if (TARGET gl3w)
return()
endif()
set(_gl3w_SourceDir ${IMGUI_NODE_EDITOR_ROOT_DIR}/external/gl3w)
set(_gl3w_BinaryDir ${CMAKE_BINARY_DIR}/external/gl3w)
add_subdirectory(${_gl3w_SourceDir} ${_gl3w_BinaryDir})
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(
gl3w
REQUIRED_VARS
_gl3w_SourceDir
)
@@ -0,0 +1,17 @@
if (TARGET imgui)
return()
endif()
set(_imgui_SourceDir ${IMGUI_NODE_EDITOR_ROOT_DIR}/external/imgui)
set(_imgui_BinaryDir ${CMAKE_BINARY_DIR}/external/imgui)
add_subdirectory(${_imgui_SourceDir} ${_imgui_BinaryDir})
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(
imgui
REQUIRED_VARS
_imgui_SourceDir
)
@@ -0,0 +1,49 @@
if (TARGET imgui_node_editor)
return()
endif()
#set(_imgui_node_editor_SourceDir ${IMGUI_NODE_EDITOR_ROOT_DIR})
#set(_imgui_node_editor_BinaryDir ${CMAKE_BINARY_DIR}/NodeEditor)
#add_subdirectory(${_imgui_node_editor_SourceDir} ${_imgui_node_editor_BinaryDir})
find_package(imgui REQUIRED)
set(_imgui_node_editor_Sources
${IMGUI_NODE_EDITOR_ROOT_DIR}/crude_json.cpp
${IMGUI_NODE_EDITOR_ROOT_DIR}/crude_json.h
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_bezier_math.h
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_bezier_math.inl
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_canvas.cpp
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_canvas.cpp
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_canvas.h
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_canvas.h
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_extra_math.h
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_extra_math.inl
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_node_editor_api.cpp
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_node_editor_internal.h
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_node_editor_internal.inl
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_node_editor.cpp
${IMGUI_NODE_EDITOR_ROOT_DIR}/imgui_node_editor.h
${IMGUI_NODE_EDITOR_ROOT_DIR}/misc/imgui_node_editor.natvis
)
add_library(imgui_node_editor STATIC
${_imgui_node_editor_Sources}
)
target_include_directories(imgui_node_editor PUBLIC
${IMGUI_NODE_EDITOR_ROOT_DIR}
)
target_link_libraries(imgui_node_editor PUBLIC imgui)
source_group(TREE ${IMGUI_NODE_EDITOR_ROOT_DIR} FILES ${_imgui_node_editor_Sources})
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(
imgui_node_editor
REQUIRED_VARS
IMGUI_NODE_EDITOR_ROOT_DIR
)
@@ -0,0 +1,17 @@
if (TARGET stb_image)
return()
endif()
set(_stb_image_SourceDir ${IMGUI_NODE_EDITOR_ROOT_DIR}/external/stb_image)
set(_stb_image_BinaryDir ${CMAKE_BINARY_DIR}/external/stb_image)
add_subdirectory(${_stb_image_SourceDir} ${_stb_image_BinaryDir})
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(
stb_image
REQUIRED_VARS
_stb_image_SourceDir
)
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="crude_json::value">
<DisplayString Condition="m_Type == 1">{m_Type,en} {*(crude_json::object*)&amp;m_Storage,view(simple)}</DisplayString>
<DisplayString Condition="m_Type == 2">{m_Type,en} {*(crude_json::array*)&amp;m_Storage,view(simple)}</DisplayString>
<DisplayString Condition="m_Type == 3">{*(crude_json::string*)&amp;m_Storage,view(simple)}</DisplayString>
<DisplayString Condition="m_Type == 4">{*(crude_json::boolean*)&amp;m_Storage}</DisplayString>
<DisplayString Condition="m_Type == 5">{*(crude_json::number*)&amp;m_Storage,g}</DisplayString>
<DisplayString>{m_Type,en}</DisplayString>
<StringView Condition="m_Type == 3">*(crude_json::string*)&amp;m_Storage</StringView>
<Expand>
<ExpandedItem Condition="m_Type == 1">*(crude_json::object*)&amp;m_Storage,view(simple)</ExpandedItem>
<ExpandedItem Condition="m_Type == 2">*(crude_json::array*)&amp;m_Storage,view(simple)</ExpandedItem>
</Expand>
</Type>
</AutoVisualizer>
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="ax::NodeEditor::Details::SafePointerType&lt;*&gt;">
<DisplayString>{m_Value}</DisplayString>
<Expand>
<Item Name="[Value]">m_Value</Item>
<Item Name="[Pointer]">($T1*)m_Value</Item>
</Expand>
</Type>
<Type Name="ax::NodeEditor::NodeId">
<DisplayString>Node {m_Value}</DisplayString>
<Expand>
<Item Name="[Value]">m_Value</Item>
</Expand>
</Type>
<Type Name="ax::NodeEditor::LinkId">
<DisplayString>Link {m_Value}</DisplayString>
<Expand>
<Item Name="[Value]">m_Value</Item>
</Expand>
</Type>
<Type Name="ax::NodeEditor::PinId">
<DisplayString>Pin {m_Value}</DisplayString>
<Expand>
<Item Name="[Value]">m_Value</Item>
</Expand>
</Type>
<Type Name="std::pair&lt;*, crude_json::value&gt;" IncludeView="MapHelper" Priority="High">
<DisplayString>{second}</DisplayString>
<Expand HideRawView="true">
<ExpandedItem>second</ExpandedItem>
</Expand>
</Type>
<Type Name="crude_json::value">
<Intrinsic Name="object_ptr" Expression="(crude_json::object*)&amp;m_Storage" />
<Intrinsic Name="array_ptr" Expression="(crude_json::array*)&amp;m_Storage" />
<Intrinsic Name="string_ptr" Expression="(crude_json::string*)&amp;m_Storage" />
<Intrinsic Name="boolean_ptr" Expression="(crude_json::boolean*)&amp;m_Storage" />
<Intrinsic Name="number_ptr" Expression="(crude_json::number*)&amp;m_Storage" />
<DisplayString Condition="m_Type == crude_json::type_t::null">null</DisplayString>
<DisplayString Condition="m_Type == crude_json::type_t::object">{*object_ptr()} : object</DisplayString>
<DisplayString Condition="m_Type == crude_json::type_t::array">{*array_ptr()} : array</DisplayString>
<DisplayString Condition="m_Type == crude_json::type_t::string">{*string_ptr()} : string</DisplayString>
<DisplayString Condition="m_Type == crude_json::type_t::boolean">{*boolean_ptr()} : boolean</DisplayString>
<DisplayString Condition="m_Type == crude_json::type_t::number">{*number_ptr(),g} : number</DisplayString>
<DisplayString Condition="m_Type == crude_json::type_t::discarded">discarded</DisplayString>
<Expand HideRawView="true">
<!--<Synthetic Name="[type]"><DisplayString>{m_Type,en}</DisplayString></Synthetic>-->
<ExpandedItem Condition="m_Type == crude_json::type_t::object">*object_ptr(),view(simple)</ExpandedItem>
<ExpandedItem Condition="m_Type == crude_json::type_t::array">*array_ptr(),view(simple)</ExpandedItem>
<Item Name="[value]" Condition="m_Type == crude_json::type_t::string">*string_ptr(),view(simple)</Item>
<Item Name="[value]" Condition="m_Type == crude_json::type_t::boolean">*boolean_ptr()</Item>
<Item Name="[value]" Condition="m_Type == crude_json::type_t::number">*number_ptr()</Item>
</Expand>
</Type>
</AutoVisualizer>