Skip to content

Commit 083e07d

Browse files
committed
Add support for non Vec3d arguments.
1 parent eda0846 commit 083e07d

File tree

5 files changed

+71
-34
lines changed

5 files changed

+71
-34
lines changed

bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DrawTool.cpp

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -63,63 +63,89 @@ sofa::type::vector<sofa::type::Vec3> getPoints(const py::array_t<double>& array)
6363
return points;
6464
}
6565

66+
sofa::type::vector<sofa::type::Quatd> getOrientations(const py::array_t<double>& array)
67+
{
68+
py::buffer_info buf = array.request();
69+
70+
if (buf.ndim != 2)
71+
throw std::runtime_error("Invalid argument, expecting an array with ndim=2");
72+
73+
size_t rows = buf.shape[0];
74+
size_t cols = buf.shape[1];
75+
76+
double* ptr = static_cast<double*>(buf.ptr);
77+
78+
std::vector<sofa::type::Quatd> orientations;
79+
orientations.resize(rows);
80+
for (size_t i = 0; i < rows; ++i)
81+
for (size_t j = 0; j < cols; ++j)
82+
orientations[i][j] = ptr[i * cols + j];
83+
84+
return orientations;
85+
}
86+
6687

6788
void moduleAddDrawTool(py::module &m)
6889
{
6990
py::class_<DrawTool> dt(m, "DrawTool", sofapython3::doc::drawtool::baseDrawToolClass);
7091

71-
// Draw points from vectors...
7292
dt.def("drawPoints", [](DrawTool *self, py::array_t<double> points, float size, sofa::type::RGBAColor& color)
7393
{
7494
self->drawPoints(getPoints(points), size, color);
7595
});
7696

77-
// Draw points from a base data that can be casted to a vector of Vec3
78-
dt.def("drawPoints", [](DrawTool *self, BaseData* dpositions, float size ){
97+
dt.def("drawPoints", [](DrawTool *self, BaseData* dpositions, float size, sofa::type::RGBAColor& color){
7998
auto positions = dynamic_cast<Data<sofa::type::vector<sofa::type::Vec3>>*>(dpositions);
8099
if(!positions)
81100
throw std::runtime_error("Invalid argument, a base data of type vector<Vec3> was expected, got "+dpositions->getValueTypeString());
82101

83-
self->drawPoints(positions->getValue(), size, sofa::type::RGBAColor::white());
102+
self->drawPoints(positions->getValue(), size, color);
84103
});
85104

86-
dt.def("drawLines", [](DrawTool *self, const std::vector<sofa::type::Vec3> &points, float size ){
87-
self->drawLines(points, size, sofa::type::RGBAColor::white());
105+
dt.def("drawLines", [](DrawTool *self, const py::array_t<double>& positions, const float size, sofa::type::RGBAColor& color){
106+
self->drawLines(getPoints(positions), size, color);
88107
});
89108

90-
91109
dt.def("drawFrames", [](DrawTool* self,
92-
const std::vector<sofa::type::Vec3d>& points,
93-
const std::vector<sofa::type::Quatd>& orientations,
94-
const sofa::type::Vec3& size ){
95-
for(unsigned int i=0;i<points.size();i++)
110+
const py::array_t<double>& points,
111+
const py::array_t<double>& orientations,
112+
const std::array<double,3>& size){
113+
auto cpoints = getPoints(points);
114+
auto corientations = getOrientations(orientations);
115+
sofa::type::Vec3 csize {size[0],size[1],size[2]};
116+
for(unsigned int i=0;i<cpoints.size();i++)
96117
{
97-
self->drawFrame(points[i], orientations[i], size);
118+
self->drawFrame(cpoints[i], corientations[i], csize);
98119
}
99120
});
100-
dt.def("drawFrames", [](DrawTool* self, BaseData* dpositions, const sofa::type::Vec3& size ){
121+
122+
dt.def("drawFrames", [](DrawTool* self, BaseData* dpositions, std::array<double, 3>& size ){
101123
using sofa::defaulttype::Rigid3Types;
102124
using Coord = sofa::defaulttype::Rigid3Types::Coord;
103125
auto positions = dynamic_cast<Data<sofa::type::vector<Coord>>*>(dpositions);
126+
sofa::type::Vec3 csize {size[0],size[1],size[2]};
104127
if(!positions)
105128
throw std::runtime_error("Invalid argument");
106129

107130
for(auto& position : positions->getValue())
108131
{
109132
self->drawFrame(Rigid3Types::getCPos(position),
110-
Rigid3Types::getCRot(position), size);
133+
Rigid3Types::getCRot(position), csize);
111134
}
112135
});
136+
113137
dt.def("drawText", [](DrawTool* self,
114-
const sofa::type::Vec3d& point,
115-
const float size,
116-
const std::string& text)
138+
const std::array<double,3>& point,
139+
const float size,
140+
const std::string& text,
141+
const sofa::type::RGBAColor& color)
117142
{
118-
self->draw3DText(point, size, sofa::type::RGBAColor::white(), text.c_str());
143+
self->draw3DText(point, size, color, text.c_str());
119144
});
120145

121-
dt.def("drawOverlayText", [](DrawTool* self, int x, int y, int fontSize, char* text){
122-
self->writeOverlayText(x,y, fontSize, sofa::type::RGBAColor::white(), text);
146+
dt.def("drawOverlayText", [](DrawTool* self, const std::array<double,2>& point,
147+
int fontSize, char* text, sofa::type::RGBAColor& color){
148+
self->writeOverlayText(point[0],point[1], fontSize, color, text);
123149
});
124150
}
125151

bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_DrawTool_doc.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
*******************************************************************************
1818
* Contact information: [email protected] *
1919
******************************************************************************/
20-
2120
#pragma once
2221

23-
namespace sofapython3::doc::drawtool {
22+
namespace sofapython3::doc::drawtool
23+
{
2424

2525
static auto baseDrawToolClass =
2626
R"(DrawTool is a wrapper for low-level rendering draw calls.
2727
It provides higher-level drawing functions like drawing lines, points, spheres, arrows, etc., without
2828
needing to write raw OpenGL each time.)";
2929

30-
} // namespace sofapython3::doc::drawtool
30+
}

bindings/Sofa/src/SofaPython3/Sofa/Types/Binding_RGBAColor.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ void moduleAddRGBAColor(py::module& m)
4242
c.def(py::init([](double r, double g, double b, double a) {
4343
return std::make_unique<sofa::type::RGBAColor>( r,g,b,a );
4444
}));
45-
45+
c.def(py::init([](const std::string& colorname) {
46+
return std::make_unique<sofa::type::RGBAColor>( RGBAColor::fromString(colorname) );
47+
}));
4648
c.def(py::init([](std::array<double,4>& v) {
4749
return std::make_unique<sofa::type::RGBAColor>( v[0], v[1], v[2], v[3] );
4850
}));
@@ -52,7 +54,7 @@ void moduleAddRGBAColor(py::module& m)
5254
c.def("b", [](const RGBAColor& color) { return color.b(); });
5355
c.def("a", [](const RGBAColor& color) { return color.a(); });
5456

55-
c.def("lighten", [](const RGBAColor& color, const SReal factor){
57+
c.def("lighten", [](const RGBAColor& color, const SReal factor) -> RGBAColor {
5658
return RGBAColor::lighten(color, factor);
5759
});
5860

@@ -71,6 +73,7 @@ void moduleAddRGBAColor(py::module& m)
7173
// Dark magic to define comparison operator using the c++ == and != operator.
7274
c.def(pybind11::self==pybind11::self);
7375
c.def(pybind11::self!=pybind11::self);
76+
7477
}
7578

7679
} // namespace sofapython3

bindings/Sofa/tests/Types/RGBAColor.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ def test_constructor_fromList(self):
1818
self.assertEqual( v0.b(), 3.0 )
1919
self.assertEqual( v0.a(), 4.0 )
2020

21+
def test_constructor_fromString(self):
22+
v0 = Sofa.Types.RGBAColor("red")
23+
self.assertEqual( v0.r(), 1.0 )
24+
self.assertEqual( v0.g(), 0.0 )
25+
self.assertEqual( v0.b(), 0.0 )
26+
self.assertEqual( v0.a(), 1.0 )
27+
2128
def test_constructor_fromInvalidList(self):
2229
self.assertRaises(TypeError, Sofa.Types.RGBAColor, [1.0,2.0,3.0])
2330
self.assertRaises(TypeError, Sofa.Types.RGBAColor, [1.0,2.0,3.0,10,100])

examples/example-drawing-controller.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Sofa
22
import SofaTypes
3+
from Sofa.Types import RGBAColor
34

45
class DrawingExamples(Sofa.Core.Controller):
56
def __init__(self, *args, **kwargs):
@@ -11,18 +12,18 @@ def __init__(self, *args, **kwargs):
1112

1213
def draw(self, visual_context):
1314
dt = visual_context.getDrawTool()
14-
dt.drawPoints([SofaTypes.Vec3d(-1.5,0,-1)], 5.0)
15-
dt.drawPoints([SofaTypes.Vec3d(-1.3,0,-1), SofaTypes.Vec3d(1.3,0,-1)], 5.0)
16-
dt.drawLines([SofaTypes.Vec3d(-1.3,0,-1), SofaTypes.Vec3d(1.3,0,-1)], 1.0)
17-
dt.drawFrames([SofaTypes.Vec3d(-1.5,0.1,-1)], [SofaTypes.Quat(0.0,0,0,1.0)], SofaTypes.Vec3d(0.1,0.1,0.1))
15+
dt.drawPoints([[-1.5,0,-1]], 5.0, RGBAColor("red"))
16+
dt.drawPoints([[-1.3,0,-1], [1.3,0,-1]], 10.0, RGBAColor("green"))
17+
dt.drawLines([[-1.3,0,-1], [1.3,0,-1]], 1.0, RGBAColor("green"))
18+
dt.drawFrames([[-1.5,0.1,-1]], [[0.0,0,0,1.0]], [0.1,0.1,0.1])
1819

1920
if self.target is not None:
20-
dt.drawPoints(self.target.position, 2.0)
21-
22-
dt.draw3DText(SofaTypes.Vec3d(-2.0,0.0,0.0), 0.5, "This is not a raptor")
23-
dt.drawText(10,10, 12, "Overlay text")
21+
dt.drawPoints(self.target.position, 2.0, RGBAColor("blue"))
22+
23+
dt.drawText([-2.0,0.0,0.0], 0.5, "This is not a raptor", RGBAColor("white"))
24+
dt.drawOverlayText([10, 10], 12, "Overlay text", RGBAColor("pink"))
2425

25-
dt.drawFrames(self.mo.position, SofaTypes.Vec3d(0.1,0.1,0.1))
26+
dt.drawFrames(self.mo.position, [0.1,0.1,0.1])
2627

2728
def createScene(root):
2829
root.dt = 0.01

0 commit comments

Comments
 (0)