14 #include "polypartition/polypartition.h"
15 #include <opencv2/imgproc/imgproc.hpp>
16 #include <opencv2/highgui/highgui.hpp>
40 if (!item.
empty() && item[0] != delimeter)
43 return splittedStrings;
54 std::string::size_type i = type.
find(file_prefix);
55 if (i != std::string::npos)
61 i = uri.
find(model_prefix);
62 if (i != std::string::npos)
80 static const char * mpath = ::getenv(
"GAZEBO_MODEL_PATH");
81 static const char * rpath = ::getenv(
"GAZEBO_RESOURCE_PATH");
97 model_paths.
erase(unique(model_paths.
begin(), model_paths.
end()), model_paths.
end());
105 file_paths.
erase(unique(file_paths.
begin(), file_paths.
end()), file_paths.
end());
111 if (parsed_uri.
empty())
116 if (uri_type ==
MODEL)
117 type_paths = &model_paths;
119 type_paths = &file_paths;
125 return file_path.
string();
146 static int dx[4] = {1, 0, -1, 0 };
147 static int dy[4] = {0, 1, 0, -1 };
149 unsigned char v =
image.at<
unsigned char>(p_start.
y, p_start.
x);
160 contour_map.at<
unsigned char>(p.
y, p.
x - 1) = 1;
162 contour_map.at<
unsigned char>(p.
y, p.
x) = 1;
164 if (
image.at<
unsigned char>(p.
y + dy[(d + 3) % 4], p.
x + dx[(d + 3) % 4]) == v)
178 else if (
image.at<
unsigned char>(p.
y + dy[d], p.
x + dx[d]) == v)
197 if (p.
x == p_start.
x && p.
y == p_start.
y && d == d_start)
215 double resolution_x = size.x/image_orig.cols;
216 double resolution_y = size.y/image_orig.rows;
217 double blockheight = size.z;
222 for (
int i = 0; i < image_orig.rows; i++)
224 for (
int j = 0; j < image_orig.cols; j++)
226 image_orig.at<uchar>(i, j) = 255 - image_orig.at<uchar>(i, j);
232 cv::Mat
image(image_orig.rows + 2, image_orig.cols + 2, CV_8UC1, cv::Scalar(255));
233 image_orig.copyTo(
image(cv::Rect(cv::Point(1, 1), cv::Size(image_orig.cols, image_orig.rows))));
235 cv::Mat vertex_index_map(
image.rows,
image.cols, CV_32SC1, -1);
236 cv::Mat contour_map(
image.rows,
image.cols, CV_8UC1, cv::Scalar(0));
240 for(
int y = 0; y <
image.rows; ++y)
242 for(
int x = 0; x <
image.cols; ++x)
244 unsigned char v =
image.at<
unsigned char>(y, x);
251 unsigned int num_points = (
unsigned int) points.
size();
257 double min_z = pos.
z;
258 double max_z = pos.
z + (double)(255 - v) / 255 * blockheight;
263 poly.Init(num_points);
265 for(
unsigned int i = 0; i < num_points; ++i)
267 poly[i].x = points[i].x;
268 poly[i].y = points[i].y;
271 double wx = points[i].x * resolution_x + pos.
x;
272 double wy = (
image.rows - points[i].y - 2) * resolution_y + pos.
y;
274 vertex_index_map.at<
int>(points[i].y, points[i].x) = mesh.
addPoint(
geo::Vector3(wx, wy, min_z));
281 for(
unsigned int i = 0; i < num_points; ++i)
283 int j = (i + 1) % num_points;
288 for(
unsigned int i = 0; i < line_starts.
size(); ++i)
290 int x2 = line_starts[i].x;
291 int y2 = line_starts[i].y;
293 while(
image.at<
unsigned char>(y2, x2) == v)
296 if (contour_map.at<
unsigned char>(y2, x2 - 1) == 0)
302 if (hole_points.
size() > 2)
305 poly_hole.Init(hole_points.
size());
306 poly_hole.SetHole(
true);
308 for(
unsigned int j = 0; j < hole_points.
size(); ++j)
310 poly_hole[j].x = hole_points[j].x;
311 poly_hole[j].y = hole_points[j].y;
314 double wx = hole_points[j].x * resolution_x + pos.
x;
315 double wy = (
image.rows - hole_points[j].y - 2) * resolution_y + pos.
y;
317 vertex_index_map.at<
int>(hole_points[j].y, hole_points[j].x) = mesh.
addPoint(
geo::Vector3(wx, wy, min_z));
323 for(
unsigned int j = 0; j < hole_points.
size(); ++j)
326 const geo::Vec2i& hp2 = hole_points[(j + 1) % hole_points.
size()];
328 int i1 = vertex_index_map.
at<
int>(hp1.
y, hp1.
x);
329 int i2 = vertex_index_map.at<
int>(hp2.
y, hp2.
x);
341 if (!pp.Triangulate_EC(&testpolys, &result))
343 error <<
"[ED::MODELS::LOADSHAPE] Error while creating heightmap: could not triangulate polygon." <<
std::endl;
351 int i1 = vertex_index_map.at<
int>(cp[0].y, cp[0].x) + 1;
352 int i2 = vertex_index_map.at<
int>(cp[1].y, cp[1].x) + 1;
353 int i3 = vertex_index_map.at<
int>(cp[2].y, cp[2].x) + 1;
363 cv::floodFill(
image, cv::Point(x, y), 255);
386 cv::Mat image_orig = cv::imread(image_filename, cv::IMREAD_GRAYSCALE);
388 if (!image_orig.data)
390 error <<
"[ED::MODELS::LOADSHAPE] Error while loading heightmap '" << image_filename <<
"'. Image could not be loaded." <<
std::endl;
403 cv::Mat image_orig = cv::imread(image_filename, cv::IMREAD_GRAYSCALE);
405 if (!image_orig.data)
407 error <<
"[ED::MODELS::LOADSHAPE] Error while loading heightmap '" << image_filename <<
"'. Image could not be loaded." <<
std::endl;
411 double size_x = resolution_x * image_orig.cols;
412 double size_y = resolution_y * image_orig.rows;
413 geo::Vec3 size(size_x, size_y, blockheight);
430 double resolution, origin_x, origin_y, origin_z, blockheight;
431 if (!(cfg.
value(
"origin_x", origin_x) &&
432 cfg.
value(
"origin_y", origin_y) &&
433 cfg.
value(
"origin_z", origin_z) &&
434 cfg.
value(
"resolution", resolution) &&
435 cfg.
value(
"blockheight", blockheight)))
437 error <<
"[ED::MODELS::LOADSHAPE] Error while loading heightmap parameters at '" << image_filename
438 <<
"'. Required shape parameters: resolution, origin_x, origin_y, origin_z, blockheight" <<
std::endl;
443 cfg.
value(
"inverted", inverted);
446 static_cast<bool>(inverted),
error);
454 poly.Init((
unsigned int) points.
size());
456 double min_z = -height / 2;
457 double max_z = height / 2;
461 for(
unsigned int i = 0; i < points.
size(); ++i)
463 poly[i].x = points[i].x;
464 poly[i].y = points[i].y;
471 for(
unsigned int i = 0; i < points.
size(); ++i)
473 int j = (i + 1) % points.
size();
484 if (!pp.Triangulate_EC(&polys, &result))
486 error <<
"[ED::MODELS::LOADSHAPE](createPolygon) TRIANGULATION FAILED" <<
std::endl;
494 int i1 = mesh.
addPoint(cp[0].x, cp[0].y, max_z);
495 int i2 = mesh.
addPoint(cp[1].x, cp[1].y, max_z);
496 int i3 = mesh.
addPoint(cp[2].x, cp[2].y, max_z);
501 int i1 = mesh.
addPoint(cp[0].x, cp[0].y, min_z);
502 int i2 = mesh.
addPoint(cp[1].x, cp[1].y, min_z);
503 int i3 = mesh.
addPoint(cp[2].x, cp[2].y, min_z);
523 cfg.
value(
"x", v.
x, pos_req);
524 cfg.
value(
"y", v.
y, pos_req);
525 cfg.
value(
"z", v.
z, pos_req);
546 else if (cfg.
value(vector_name, vector_string))
563 double roll = 0, pitch = 0, yaw = 0;
569 cfg.
value(
"X", roll, rot_req);
570 cfg.
value(
"Y", pitch, rot_req);
571 cfg.
value(
"Z", yaw, rot_req);
572 cfg.
value(
"roll", roll, rot_req);
573 cfg.
value(
"pitch", pitch, rot_req);
574 cfg.
value(
"yaw", yaw, rot_req);
578 else if (cfg.
value(
"pose", pose_string, pos_req))
582 if (pose_vector.
size() == 6)
595 else if (cfg.
value(
"pos", pose_string, pos_req))
599 if (pose_vector.
size() == 3)
615 pose.
R.
setRPY(roll, pitch, yaw);
628 if (cfg.
value(
"path", path))
632 error <<
"[ED::MODELS::LOADSHAPE] Error while loading shape: provided path is empty.";
638 if (model_path.
empty() || path[0] ==
'/')
641 shape_path = model_path +
"/" + path;
645 if (it != shape_cache.
end())
651 if (xt ==
".pgm" || xt ==
".png")
655 else if (xt ==
".geo")
657 geo::serialization::registerDeserializer<geo::Shape>();
660 else if (xt ==
".3ds" || xt ==
".stl" || xt ==
".dae")
664 else if (xt ==
".xml")
671 error <<
"[ED::MODELS::LOADSHAPE] Error while loading shape at " << shape_path.
string() <<
std::endl;
674 shape_cache[shape_path.
string()] = shape;
678 error <<
"[ED::MODELS::LOADSHAPE] Error while loading shape at " << shape_path.
string() <<
" ; file does not exist" <<
std::endl;
692 error <<
"[ED::MODELS::LOADSHAPE] Error while loading shape: box must contain 'min' and 'max' (only 'min' specified)";
699 error <<
"[ED::MODELS::LOADSHAPE] Error while loading shape: box must contain 'min' and 'max' or 'size'.";
710 double radius = 0, height = 0;
711 if (cfg.
value(
"radius", radius) && (cfg.
value(
"height", height) || cfg.
value(
"length", height)))
736 if (cfg.
value(
"height", height))
752 cfg.
value(
"point", point_string);
763 if (cfg.
value(
"height", height))
774 if (cfg.
value(
"uri", uri_path))
778 if (cfg.
value(
"scale", scale_str))
781 if(scale_vector.
size() != 3)
783 error <<
"[ED::MODELS::LOADSHAPE] Mesh scale: '" << scale_str <<
"' should have 3 members." <<
std::endl;
794 error <<
"[ED::MODELS::LOADSHAPE] Mesh File: '" << mesh_path.
string() <<
"' doesn't exist." <<
std::endl;
797 error <<
"[ED::MODELS::LOADSHAPE] No uri found for mesh." <<
std::endl;
800 if (cfg.
value(
"submesh", dummy))
801 error <<
"[ED::MODELS::LOADSHAPE] 'submesh' of mesh is not supported by ED " <<
std::endl;
808 double height, resolution;
811 if ((cfg.
value(
"image", image_filename) && !image_filename.
empty() && cfg.
value(
"resolution", resolution) &&
812 cfg.
value(
"height", height)))
837 error <<
"[ED::MODELS::LOADSHAPE] Error while loading shape: heightmap must contain 'image', 'resolution' and 'height'." <<
std::endl;
844 if (!cfg.
value(
"radius", radius))
845 error <<
"[ED::MODELS::LOADSHAPE] Error while loading shape: sphere must contain 'radius'." <<
std::endl;
846 int recursion_level = 1;
875 shape_tr->setMesh(shape->getMesh().getTransformed(pose));
889 for(
int i = 0; i < num_corners; ++i)
891 double a = 2 * M_PI * i / num_corners;
892 double x = sin(
a) * radius;
893 double y = cos(
a) * radius;
900 for(
int i = 1; i < num_corners - 1; ++i)
912 for(
int i = 0; i < num_corners; ++i)
914 int j = (i + 1) % num_corners;
927 bool firstIsSmaller = i1 < i2;
928 unsigned long smallerIndex = firstIsSmaller ? i1 : i2;
929 unsigned long greaterIndex = firstIsSmaller ? i2 : i1;
930 unsigned long key = (smallerIndex << 32) + greaterIndex;
933 if (it != cache.
end())
958 double t = (1.0 + sqrt(5.0)) / 2.0;
1004 for (uint i = 0; i < recursion_level; i++)