4cf4a5665d
Following the export declarations in Dear ImGui and ImPlot METADATA, this change updates MuJoCo's Copybara configuration (copy.bara.sky) to export and transform the Python bindings. `//third_party/dear_imgui/google/py` exports to `python/mujoco/experimental/dear_imgui` and `//third_party/implot/google/py` exports to `python/mujoco/experimental/implot`. PiperOrigin-RevId: 925293624 Change-Id: Ie6e32d247a6f7fc24bb36ae7060f2075d8efeb26
327 lines
15 KiB
C++
327 lines
15 KiB
C++
// Copyright 2026 DeepMind Technologies Limited
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#ifndef MUJOCO_PYTHON_EXPERIMENTAL_DEAR_IMGUI_DEAR_IMGUI_MACROS_H_
|
|
#define MUJOCO_PYTHON_EXPERIMENTAL_DEAR_IMGUI_DEAR_IMGUI_MACROS_H_
|
|
|
|
// WARNING: This file is intended for internal use by dear_imgui libraries ONLY!
|
|
//
|
|
// The macros defined here use short, generic names (DEF0, ARG_ID, etc.) and
|
|
// are NOT #undef'd. Including this header elsewhere may cause naming conflicts.
|
|
//
|
|
// Define NAMESPACE to be the ImGui library you're binding before including this
|
|
// header, e.g. #define NAMESPACE ImGui
|
|
//
|
|
// ============================================================================
|
|
// Quick Reference
|
|
// ============================================================================
|
|
//
|
|
// DEFn(Name, Args...) // Binds NAMESPACE::Name as Name in Python
|
|
// DEFn_AS(CppName, PyName, Args...) // Binds NAMESPACE::CppName as PyName
|
|
// DEFn_F(PyName, Args..., { CppBody }) // Custom implementation
|
|
//
|
|
// Where 'n' is the number of arguments (0-9).
|
|
//
|
|
// ============================================================================
|
|
// Argument Format
|
|
// ============================================================================
|
|
//
|
|
// Each argument is a tuple: (Type, name, DefaultValue)
|
|
//
|
|
// - No default value: (ImString, label, ) // trailing comma required
|
|
// - With default value: (int, flags, = 0) // include the '='
|
|
// - Complex defaults: (const ImVec2&, size, = ImVec2_Zero)
|
|
//
|
|
// NOTE: Default values cannot contain commas. Use predefined constants like
|
|
// ImVec2_Zero, ImVec4_One, etc.
|
|
//
|
|
// ============================================================================
|
|
// Examples (from dear_imgui.cc)
|
|
// ============================================================================
|
|
//
|
|
// Simple binding - NAMESPACE::End() exposed as End():
|
|
// DEF0(End);
|
|
//
|
|
// Binding with arguments:
|
|
// DEF4(BeginChild,
|
|
// (ImString, str_id, ),
|
|
// (const ImVec2&, size, = ImVec2_Zero),
|
|
// (ImGuiChildFlags, child_flags, = 0),
|
|
// (ImGuiWindowFlags, window_flags, = 0));
|
|
//
|
|
// Overloaded function - NAMESPACE::BeginChild(ImGuiID) exposed as BeginChildId():
|
|
// DEF4_AS(BeginChild, BeginChildId,
|
|
// (ImGuiID, id, ),
|
|
// (const ImVec2&, size, = ImVec2_Zero),
|
|
// (ImGuiChildFlags, child_flags, = 0),
|
|
// (ImGuiWindowFlags, window_flags, = 0));
|
|
//
|
|
// Custom implementation using DEFn_F is needed when:
|
|
//
|
|
// 1. Variadic functions (e.g., Text, TextColored)
|
|
//
|
|
// C++ variadic functions (those with "...") cannot be bound directly
|
|
// because the type/count of arguments is unknown at compile time. Use a
|
|
// wrapper that calls the function with a fixed format. Also note that
|
|
// user-controlled format strings are a security risk (format string
|
|
// attacks). Always use "%s":
|
|
//
|
|
// DEF1_F(Text, (ImString, txt, ), {
|
|
// return NAMESPACE::Text("%s", txt);
|
|
// });
|
|
//
|
|
// 2. Output pointer parameters (e.g., Checkbox, SliderFloat)
|
|
//
|
|
// Python doesn't have output pointers, so return modified values as a
|
|
// tuple:
|
|
//
|
|
// DEF2_F(Checkbox, (ImString, label, ), (bool*, v, ), {
|
|
// auto result = NAMESPACE::Checkbox(label, v);
|
|
// return std::make_tuple(result, *v);
|
|
// });
|
|
//
|
|
// 3. Type conversions (e.g., Image, ImageButton)
|
|
//
|
|
// Some C++ types don't have Python equivalents. For example, ImTextureID
|
|
// is a void* (opaque pointer), which pybind11 can't automatically convert.
|
|
// Accept a Python-friendly type (like long) and cast it:
|
|
//
|
|
// DEF2_F(Image, (long, tex_id, ), (const ImVec2&, size, ), {
|
|
// return NAMESPACE::Image(reinterpret_cast<void*>(tex_id), size);
|
|
// });
|
|
|
|
// ============================================================================
|
|
// Internal helper macros (not intended to be called directly by binding code)
|
|
// ============================================================================
|
|
|
|
// Extracts the type and name of an argument tuple.
|
|
// Example: ARG_DECL((float, alpha, = 1.0f)) -> float alpha
|
|
#define ARG_DECL_X(T_, N_, V_) T_ N_
|
|
#define ARG_DECL(A_) ARG_DECL_X A_
|
|
|
|
// Extracts the identifier of an argument tuple.
|
|
// Example: ARG_ID((float, alpha, = 1.0f)) -> alpha
|
|
#define ARG_ID_X(T_, N_, V_) N_
|
|
#define ARG_ID(A_) ARG_ID_X A_
|
|
|
|
// Extracts the name of an argument tuple as a quoted string literal.
|
|
// Example: ARG_NAME((float, alpha, = 1.0f)) -> "alpha"
|
|
#define ARG_NAME_X(T_, N_, V_) #N_
|
|
#define ARG_NAME(A_) ARG_NAME_X A_
|
|
|
|
// Extracts the default value of an argument tuple.
|
|
// Example: ARG_DEFVAL((float, alpha, = 1.0f)) -> = 1.0f
|
|
#define ARG_DEFVAL_X(T_, N_, V_) V_
|
|
#define ARG_DEFVAL(A_) ARG_DEFVAL_X A_
|
|
|
|
// ============================================================================
|
|
// Public macros for binding code
|
|
// ============================================================================
|
|
|
|
//
|
|
#define DEF0_F(N, FN) \
|
|
m.def(#N, []( \
|
|
) FN \
|
|
);
|
|
|
|
#define DEF1_F(N, A1, FN) \
|
|
m.def(#N, []( \
|
|
ARG_DECL(A1) \
|
|
) FN, \
|
|
py::arg(ARG_NAME(A1)) ARG_DEFVAL(A1) \
|
|
);
|
|
|
|
#define DEF2_F(N, A1, A2, FN) \
|
|
m.def(#N, []( \
|
|
ARG_DECL(A1), \
|
|
ARG_DECL(A2) \
|
|
) FN, \
|
|
py::arg(ARG_NAME(A1)) ARG_DEFVAL(A1), \
|
|
py::arg(ARG_NAME(A2)) ARG_DEFVAL(A2) \
|
|
);
|
|
|
|
#define DEF3_F(N, A1, A2, A3, FN) \
|
|
m.def(#N, []( \
|
|
ARG_DECL(A1), \
|
|
ARG_DECL(A2), \
|
|
ARG_DECL(A3) \
|
|
) FN, \
|
|
py::arg(ARG_NAME(A1)) ARG_DEFVAL(A1), \
|
|
py::arg(ARG_NAME(A2)) ARG_DEFVAL(A2), \
|
|
py::arg(ARG_NAME(A3)) ARG_DEFVAL(A3) \
|
|
);
|
|
|
|
#define DEF4_F(N, A1, A2, A3, A4, FN) \
|
|
m.def(#N, []( \
|
|
ARG_DECL(A1), \
|
|
ARG_DECL(A2), \
|
|
ARG_DECL(A3), \
|
|
ARG_DECL(A4) \
|
|
) FN, \
|
|
py::arg(ARG_NAME(A1)) ARG_DEFVAL(A1), \
|
|
py::arg(ARG_NAME(A2)) ARG_DEFVAL(A2), \
|
|
py::arg(ARG_NAME(A3)) ARG_DEFVAL(A3), \
|
|
py::arg(ARG_NAME(A4)) ARG_DEFVAL(A4) \
|
|
);
|
|
|
|
#define DEF5_F(N, A1, A2, A3, A4, A5, FN) \
|
|
m.def(#N, []( \
|
|
ARG_DECL(A1), \
|
|
ARG_DECL(A2), \
|
|
ARG_DECL(A3), \
|
|
ARG_DECL(A4), \
|
|
ARG_DECL(A5) \
|
|
) FN, \
|
|
py::arg(ARG_NAME(A1)) ARG_DEFVAL(A1), \
|
|
py::arg(ARG_NAME(A2)) ARG_DEFVAL(A2), \
|
|
py::arg(ARG_NAME(A3)) ARG_DEFVAL(A3), \
|
|
py::arg(ARG_NAME(A4)) ARG_DEFVAL(A4), \
|
|
py::arg(ARG_NAME(A5)) ARG_DEFVAL(A5) \
|
|
);
|
|
|
|
#define DEF6_F(N, A1, A2, A3, A4, A5, A6, FN) \
|
|
m.def(#N, []( \
|
|
ARG_DECL(A1), \
|
|
ARG_DECL(A2), \
|
|
ARG_DECL(A3), \
|
|
ARG_DECL(A4), \
|
|
ARG_DECL(A5), \
|
|
ARG_DECL(A6) \
|
|
) FN, \
|
|
py::arg(ARG_NAME(A1)) ARG_DEFVAL(A1), \
|
|
py::arg(ARG_NAME(A2)) ARG_DEFVAL(A2), \
|
|
py::arg(ARG_NAME(A3)) ARG_DEFVAL(A3), \
|
|
py::arg(ARG_NAME(A4)) ARG_DEFVAL(A4), \
|
|
py::arg(ARG_NAME(A5)) ARG_DEFVAL(A5), \
|
|
py::arg(ARG_NAME(A6)) ARG_DEFVAL(A6) \
|
|
);
|
|
|
|
#define DEF7_F(N, A1, A2, A3, A4, A5, A6, A7, FN) \
|
|
m.def(#N, []( \
|
|
ARG_DECL(A1), \
|
|
ARG_DECL(A2), \
|
|
ARG_DECL(A3), \
|
|
ARG_DECL(A4), \
|
|
ARG_DECL(A5), \
|
|
ARG_DECL(A6), \
|
|
ARG_DECL(A7) \
|
|
) FN, \
|
|
py::arg(ARG_NAME(A1)) ARG_DEFVAL(A1), \
|
|
py::arg(ARG_NAME(A2)) ARG_DEFVAL(A2), \
|
|
py::arg(ARG_NAME(A3)) ARG_DEFVAL(A3), \
|
|
py::arg(ARG_NAME(A4)) ARG_DEFVAL(A4), \
|
|
py::arg(ARG_NAME(A5)) ARG_DEFVAL(A5), \
|
|
py::arg(ARG_NAME(A6)) ARG_DEFVAL(A6), \
|
|
py::arg(ARG_NAME(A7)) ARG_DEFVAL(A7) \
|
|
);
|
|
|
|
#define DEF8_F(N, A1, A2, A3, A4, A5, A6, A7, A8, FN) \
|
|
m.def(#N, []( \
|
|
ARG_DECL(A1), \
|
|
ARG_DECL(A2), \
|
|
ARG_DECL(A3), \
|
|
ARG_DECL(A4), \
|
|
ARG_DECL(A5), \
|
|
ARG_DECL(A6), \
|
|
ARG_DECL(A7), \
|
|
ARG_DECL(A8) \
|
|
) FN, \
|
|
py::arg(ARG_NAME(A1)) ARG_DEFVAL(A1), \
|
|
py::arg(ARG_NAME(A2)) ARG_DEFVAL(A2), \
|
|
py::arg(ARG_NAME(A3)) ARG_DEFVAL(A3), \
|
|
py::arg(ARG_NAME(A4)) ARG_DEFVAL(A4), \
|
|
py::arg(ARG_NAME(A5)) ARG_DEFVAL(A5), \
|
|
py::arg(ARG_NAME(A6)) ARG_DEFVAL(A6), \
|
|
py::arg(ARG_NAME(A7)) ARG_DEFVAL(A7), \
|
|
py::arg(ARG_NAME(A8)) ARG_DEFVAL(A8) \
|
|
);
|
|
|
|
#define DEF9_F(N, A1, A2, A3, A4, A5, A6, A7, A8, A9, FN) \
|
|
m.def(#N, []( \
|
|
ARG_DECL(A1), \
|
|
ARG_DECL(A2), \
|
|
ARG_DECL(A3), \
|
|
ARG_DECL(A4), \
|
|
ARG_DECL(A5), \
|
|
ARG_DECL(A6), \
|
|
ARG_DECL(A7), \
|
|
ARG_DECL(A8), \
|
|
ARG_DECL(A9) \
|
|
) FN, \
|
|
py::arg(ARG_NAME(A1)) ARG_DEFVAL(A1), \
|
|
py::arg(ARG_NAME(A2)) ARG_DEFVAL(A2), \
|
|
py::arg(ARG_NAME(A3)) ARG_DEFVAL(A3), \
|
|
py::arg(ARG_NAME(A4)) ARG_DEFVAL(A4), \
|
|
py::arg(ARG_NAME(A5)) ARG_DEFVAL(A5), \
|
|
py::arg(ARG_NAME(A6)) ARG_DEFVAL(A6), \
|
|
py::arg(ARG_NAME(A7)) ARG_DEFVAL(A7), \
|
|
py::arg(ARG_NAME(A8)) ARG_DEFVAL(A8), \
|
|
py::arg(ARG_NAME(A9)) ARG_DEFVAL(A9) \
|
|
);
|
|
|
|
#define DEF10_F(N, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, FN) \
|
|
m.def(#N, []( \
|
|
ARG_DECL(A1), \
|
|
ARG_DECL(A2), \
|
|
ARG_DECL(A3), \
|
|
ARG_DECL(A4), \
|
|
ARG_DECL(A5), \
|
|
ARG_DECL(A6), \
|
|
ARG_DECL(A7), \
|
|
ARG_DECL(A8), \
|
|
ARG_DECL(A9), \
|
|
ARG_DECL(A10) \
|
|
) FN, \
|
|
py::arg(ARG_NAME(A1)) ARG_DEFVAL(A1), \
|
|
py::arg(ARG_NAME(A2)) ARG_DEFVAL(A2), \
|
|
py::arg(ARG_NAME(A3)) ARG_DEFVAL(A3), \
|
|
py::arg(ARG_NAME(A4)) ARG_DEFVAL(A4), \
|
|
py::arg(ARG_NAME(A5)) ARG_DEFVAL(A5), \
|
|
py::arg(ARG_NAME(A6)) ARG_DEFVAL(A6), \
|
|
py::arg(ARG_NAME(A7)) ARG_DEFVAL(A7), \
|
|
py::arg(ARG_NAME(A8)) ARG_DEFVAL(A8), \
|
|
py::arg(ARG_NAME(A9)) ARG_DEFVAL(A9), \
|
|
py::arg(ARG_NAME(A10)) ARG_DEFVAL(A10) \
|
|
);
|
|
|
|
// NOLINTBEGIN(whitespace/line_length)
|
|
|
|
#define DEF0_AS(N, AS) DEF0_F(AS, { return NAMESPACE::N(); } )
|
|
#define DEF1_AS(N, AS, A1) DEF1_F(AS, A1, { return NAMESPACE::N(ARG_ID(A1)); } )
|
|
#define DEF2_AS(N, AS, A1, A2) DEF2_F(AS, A1, A2, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2)); } )
|
|
#define DEF3_AS(N, AS, A1, A2, A3) DEF3_F(AS, A1, A2, A3, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3)); } )
|
|
#define DEF4_AS(N, AS, A1, A2, A3, A4) DEF4_F(AS, A1, A2, A3, A4, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4)); } )
|
|
#define DEF5_AS(N, AS, A1, A2, A3, A4, A5) DEF5_F(AS, A1, A2, A3, A4, A5, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4), ARG_ID(A5)); } )
|
|
#define DEF6_AS(N, AS, A1, A2, A3, A4, A5, A6) DEF6_F(AS, A1, A2, A3, A4, A5, A6, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4), ARG_ID(A5), ARG_ID(A6)); } )
|
|
#define DEF7_AS(N, AS, A1, A2, A3, A4, A5, A6, A7) DEF7_F(AS, A1, A2, A3, A4, A5, A6, A7, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4), ARG_ID(A5), ARG_ID(A6), ARG_ID(A7)); } )
|
|
#define DEF8_AS(N, AS, A1, A2, A3, A4, A5, A6, A7, A8) DEF8_F(AS, A1, A2, A3, A4, A5, A6, A7, A8, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4), ARG_ID(A5), ARG_ID(A6), ARG_ID(A7), ARG_ID(A8)); } )
|
|
#define DEF9_AS(N, AS, A1, A2, A3, A4, A5, A6, A7, A8, A9) DEF9_F(AS, A1, A2, A3, A4, A5, A6, A7, A8, A9, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4), ARG_ID(A5), ARG_ID(A6), ARG_ID(A7), ARG_ID(A8), ARG_ID(A9)); } )
|
|
#define DEF10_AS(N, AS, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) DEF10_F(AS, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4), ARG_ID(A5), ARG_ID(A6), ARG_ID(A7), ARG_ID(A8), ARG_ID(A9), ARG_ID(A10)); } )
|
|
|
|
#define DEF0(N) DEF0_F(N, { return NAMESPACE::N(); } )
|
|
#define DEF1(N, A1) DEF1_F(N, A1, { return NAMESPACE::N(ARG_ID(A1)); } )
|
|
#define DEF2(N, A1, A2) DEF2_F(N, A1, A2, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2)); } )
|
|
#define DEF3(N, A1, A2, A3) DEF3_F(N, A1, A2, A3, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3)); } )
|
|
#define DEF4(N, A1, A2, A3, A4) DEF4_F(N, A1, A2, A3, A4, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4)); } )
|
|
#define DEF5(N, A1, A2, A3, A4, A5) DEF5_F(N, A1, A2, A3, A4, A5, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4), ARG_ID(A5)); } )
|
|
#define DEF6(N, A1, A2, A3, A4, A5, A6) DEF6_F(N, A1, A2, A3, A4, A5, A6, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4), ARG_ID(A5), ARG_ID(A6)); } )
|
|
#define DEF7(N, A1, A2, A3, A4, A5, A6, A7) DEF7_F(N, A1, A2, A3, A4, A5, A6, A7, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4), ARG_ID(A5), ARG_ID(A6), ARG_ID(A7)); } )
|
|
#define DEF8(N, A1, A2, A3, A4, A5, A6, A7, A8) DEF8_F(N, A1, A2, A3, A4, A5, A6, A7, A8, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4), ARG_ID(A5), ARG_ID(A6), ARG_ID(A7), ARG_ID(A8)); } )
|
|
#define DEF9(N, A1, A2, A3, A4, A5, A6, A7, A8, A9) DEF9_F(N, A1, A2, A3, A4, A5, A6, A7, A8, A9, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4), ARG_ID(A5), ARG_ID(A6), ARG_ID(A7), ARG_ID(A8), ARG_ID(A9)); } )
|
|
#define DEF10(N, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10) DEF10_F(N, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, { return NAMESPACE::N(ARG_ID(A1), ARG_ID(A2), ARG_ID(A3), ARG_ID(A4), ARG_ID(A5), ARG_ID(A6), ARG_ID(A7), ARG_ID(A8), ARG_ID(A9), ARG_ID(A10)); } )
|
|
|
|
// NOLINTEND(whitespace/line_length)
|
|
|
|
#endif // MUJOCO_PYTHON_EXPERIMENTAL_DEAR_IMGUI_DEAR_IMGUI_MACROS_H_
|