Skip to content

Commit 384da63

Browse files
committed
mesh: make TRasterMesh multithread-safe
(cherry picked from commit bbfae87948dc0fa128b1a42c040c5d5e58e4ec0c)
1 parent 9609fd9 commit 384da63

File tree

5 files changed

+107
-72
lines changed

5 files changed

+107
-72
lines changed

libs/MVS/DepthMap.cpp

+21-18
Original file line numberDiff line numberDiff line change
@@ -1107,18 +1107,17 @@ bool MVS::TriangulatePoints2DepthMap(
11071107
// rasterize triangles onto depthmap
11081108
struct RasterDepth : TRasterMeshBase<RasterDepth> {
11091109
typedef TRasterMeshBase<RasterDepth> Base;
1110+
using Base::Triangle;
11101111
using Base::camera;
11111112
using Base::depthMap;
1112-
using Base::ptc;
1113-
using Base::pti;
11141113
const Mesh::NormalArr& vertexNormals;
11151114
NormalMap& normalMap;
11161115
Mesh::Face face;
11171116
RasterDepth(const Mesh::NormalArr& _vertexNormals, const Camera& _camera, DepthMap& _depthMap, NormalMap& _normalMap)
11181117
: Base(_camera, _depthMap), vertexNormals(_vertexNormals), normalMap(_normalMap) {}
1119-
inline void operator()(const ImageRef& pt, const Point3f& bary) {
1120-
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(bary));
1121-
const Depth z(ComputeDepth(pbary));
1118+
inline void Raster(const ImageRef& pt, const Triangle& t, const Point3f& bary) {
1119+
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(t, bary));
1120+
const Depth z(ComputeDepth(t, pbary));
11221121
ASSERT(z > Depth(0));
11231122
depthMap(pt) = z;
11241123
normalMap(pt) = normalized(
@@ -1128,16 +1127,18 @@ bool MVS::TriangulatePoints2DepthMap(
11281127
);
11291128
}
11301129
};
1131-
RasterDepth rasterer = {mesh.vertexNormals, camera, depthMap, normalMap};
1130+
RasterDepth rasterer {mesh.vertexNormals, camera, depthMap, normalMap};
1131+
RasterDepth::Triangle triangle;
1132+
RasterDepth::TriangleRasterizer triangleRasterizer(triangle, rasterer);
11321133
for (const Mesh::Face& face : mesh.faces) {
11331134
rasterer.face = face;
1134-
rasterer.ptc[0].z = mesh.vertices[face[0]].z;
1135-
rasterer.ptc[1].z = mesh.vertices[face[1]].z;
1136-
rasterer.ptc[2].z = mesh.vertices[face[2]].z;
1135+
triangle.ptc[0].z = mesh.vertices[face[0]].z;
1136+
triangle.ptc[1].z = mesh.vertices[face[1]].z;
1137+
triangle.ptc[2].z = mesh.vertices[face[2]].z;
11371138
Image8U::RasterizeTriangleBary(
11381139
projs[face[0]],
11391140
projs[face[1]],
1140-
projs[face[2]], rasterer);
1141+
projs[face[2]], triangleRasterizer);
11411142
}
11421143
}
11431144
return true;
@@ -1181,22 +1182,24 @@ bool MVS::TriangulatePoints2DepthMap(
11811182
using Base::depthMap;
11821183
RasterDepth(const Camera& _camera, DepthMap& _depthMap)
11831184
: Base(_camera, _depthMap) {}
1184-
inline void operator()(const ImageRef& pt, const Point3f& bary) {
1185-
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(bary));
1186-
const Depth z(ComputeDepth(pbary));
1185+
inline void Raster(const ImageRef& pt, const Triangle& t, const Point3f& bary) {
1186+
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(t, bary));
1187+
const Depth z(ComputeDepth(t, pbary));
11871188
ASSERT(z > Depth(0));
11881189
depthMap(pt) = z;
11891190
}
11901191
};
1191-
RasterDepth rasterer = {camera, depthMap};
1192+
RasterDepth rasterer {camera, depthMap};
1193+
RasterDepth::Triangle triangle;
1194+
RasterDepth::TriangleRasterizer triangleRasterizer(triangle, rasterer);
11921195
for (const Mesh::Face& face : mesh.faces) {
1193-
rasterer.ptc[0].z = mesh.vertices[face[0]].z;
1194-
rasterer.ptc[1].z = mesh.vertices[face[1]].z;
1195-
rasterer.ptc[2].z = mesh.vertices[face[2]].z;
1196+
triangle.ptc[0].z = mesh.vertices[face[0]].z;
1197+
triangle.ptc[1].z = mesh.vertices[face[1]].z;
1198+
triangle.ptc[2].z = mesh.vertices[face[2]].z;
11961199
Image8U::RasterizeTriangleBary(
11971200
projs[face[0]],
11981201
projs[face[1]],
1199-
projs[face[2]], rasterer);
1202+
projs[face[2]], triangleRasterizer);
12001203
}
12011204
}
12021205
return true;

libs/MVS/Mesh.cpp

+33-23
Original file line numberDiff line numberDiff line change
@@ -4078,9 +4078,11 @@ void Mesh::Project(const Camera& camera, DepthMap& depthMap) const
40784078
: Base(_vertices, _camera, _depthMap) {}
40794079
};
40804080
RasterMesh rasterer(vertices, camera, depthMap);
4081+
RasterMesh::Triangle triangle;
4082+
RasterMesh::TriangleRasterizer triangleRasterizer(triangle, rasterer);
40814083
rasterer.Clear();
40824084
for (const Face& facet: faces)
4083-
rasterer.Project(facet);
4085+
rasterer.Project(facet, triangleRasterizer);
40844086
}
40854087
void Mesh::Project(const Camera& camera, DepthMap& depthMap, Image8U3& image) const
40864088
{
@@ -4097,9 +4099,9 @@ void Mesh::Project(const Camera& camera, DepthMap& depthMap, Image8U3& image) co
40974099
Base::Clear();
40984100
image.memset(0);
40994101
}
4100-
void Raster(const ImageRef& pt, const Point3f& bary) {
4101-
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(bary));
4102-
const Depth z(ComputeDepth(pbary));
4102+
void Raster(const ImageRef& pt, const Triangle& t, const Point3f& bary) {
4103+
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(t, bary));
4104+
const Depth z(ComputeDepth(t, pbary));
41034105
ASSERT(z > Depth(0));
41044106
Depth& depth = depthMap(pt);
41054107
if (depth == 0 || depth > z) {
@@ -4115,11 +4117,13 @@ void Mesh::Project(const Camera& camera, DepthMap& depthMap, Image8U3& image) co
41154117
if (image.size() != depthMap.size())
41164118
image.create(depthMap.size());
41174119
RasterMesh rasterer(*this, camera, depthMap, image);
4120+
RasterMesh::Triangle triangle;
4121+
RasterMesh::TriangleRasterizer triangleRasterizer(triangle, rasterer);
41184122
rasterer.Clear();
41194123
FOREACH(idxFace, faces) {
41204124
const Face& facet = faces[idxFace];
41214125
rasterer.idxFaceTex = idxFace*3;
4122-
rasterer.Project(facet);
4126+
rasterer.Project(facet, triangleRasterizer);
41234127
}
41244128
}
41254129
// project mesh to the given camera plane, computing also the normal-map (in camera space)
@@ -4138,13 +4142,13 @@ void Mesh::Project(const Camera& camera, DepthMap& depthMap, NormalMap& normalMa
41384142
Base::Clear();
41394143
normalMap.memset(0);
41404144
}
4141-
inline void Project(const Face& facet) {
4145+
inline void Project(const Face& facet, TriangleRasterizer& tr) {
41424146
idxVerts = facet.ptr();
4143-
Base::Project(facet);
4147+
Base::Project(facet, tr);
41444148
}
4145-
void Raster(const ImageRef& pt, const Point3f& bary) {
4146-
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(bary));
4147-
const Depth z(ComputeDepth(pbary));
4149+
void Raster(const ImageRef& pt, const Triangle& t, const Point3f& bary) {
4150+
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(t, bary));
4151+
const Depth z(ComputeDepth(t, pbary));
41484152
ASSERT(z > Depth(0));
41494153
Depth& depth = depthMap(pt);
41504154
if (depth == Depth(0) || depth > z) {
@@ -4160,10 +4164,12 @@ void Mesh::Project(const Camera& camera, DepthMap& depthMap, NormalMap& normalMa
41604164
if (normalMap.size() != depthMap.size())
41614165
normalMap.create(depthMap.size());
41624166
RasterMesh rasterer(*this, camera, depthMap, normalMap);
4167+
RasterMesh::Triangle triangle;
4168+
RasterMesh::TriangleRasterizer triangleRasterizer(triangle, rasterer);
41634169
rasterer.Clear();
41644170
// render the entire mesh
41654171
for (const Face& facet: faces)
4166-
rasterer.Project(facet);
4172+
rasterer.Project(facet, triangleRasterizer);
41674173
}
41684174
// project mesh to the given camera plane using orthographic projection
41694175
void Mesh::ProjectOrtho(const Camera& camera, DepthMap& depthMap) const
@@ -4172,22 +4178,24 @@ void Mesh::ProjectOrtho(const Camera& camera, DepthMap& depthMap) const
41724178
typedef TRasterMesh<RasterMesh> Base;
41734179
RasterMesh(const VertexArr& _vertices, const Camera& _camera, DepthMap& _depthMap)
41744180
: Base(_vertices, _camera, _depthMap) {}
4175-
inline bool ProjectVertex(const Mesh::Vertex& pt, int v) {
4176-
return (ptc[v] = camera.TransformPointW2C(Cast<REAL>(pt))).z > 0 &&
4177-
depthMap.isInsideWithBorder<float,3>(pti[v] = camera.TransformPointOrthoC2I(ptc[v]));
4181+
inline bool ProjectVertex(const Mesh::Vertex& pt, int v, Triangle& t) {
4182+
return (t.ptc[v] = camera.TransformPointW2C(Cast<REAL>(pt))).z > 0 &&
4183+
depthMap.isInsideWithBorder<float,3>(t.pti[v] = camera.TransformPointOrthoC2I(t.ptc[v]));
41784184
}
4179-
void Raster(const ImageRef& pt, const Point3f& bary) {
4180-
const Depth z(ComputeDepth(bary));
4185+
void Raster(const ImageRef& pt, const Triangle& t, const Point3f& bary) {
4186+
const Depth z(ComputeDepth(t, bary));
41814187
ASSERT(z > Depth(0));
41824188
Depth& depth = depthMap(pt);
41834189
if (depth == 0 || depth > z)
41844190
depth = z;
41854191
}
41864192
};
41874193
RasterMesh rasterer(vertices, camera, depthMap);
4194+
RasterMesh::Triangle triangle;
4195+
RasterMesh::TriangleRasterizer triangleRasterizer(triangle, rasterer);
41884196
rasterer.Clear();
41894197
for (const Face& facet: faces)
4190-
rasterer.Project(facet);
4198+
rasterer.Project(facet, triangleRasterizer);
41914199
}
41924200
void Mesh::ProjectOrtho(const Camera& camera, DepthMap& depthMap, Image8U3& image) const
41934201
{
@@ -4204,12 +4212,12 @@ void Mesh::ProjectOrtho(const Camera& camera, DepthMap& depthMap, Image8U3& imag
42044212
Base::Clear();
42054213
image.memset(0);
42064214
}
4207-
inline bool ProjectVertex(const Mesh::Vertex& pt, int v) {
4208-
return (ptc[v] = camera.TransformPointW2C(Cast<REAL>(pt))).z > 0 &&
4209-
depthMap.isInsideWithBorder<float,3>(pti[v] = camera.TransformPointOrthoC2I(ptc[v]));
4215+
inline bool ProjectVertex(const Mesh::Vertex& pt, int v, Triangle& t) {
4216+
return (t.ptc[v] = camera.TransformPointW2C(Cast<REAL>(pt))).z > 0 &&
4217+
depthMap.isInsideWithBorder<float,3>(t.pti[v] = camera.TransformPointOrthoC2I(t.ptc[v]));
42104218
}
4211-
void Raster(const ImageRef& pt, const Point3f& bary) {
4212-
const Depth z(ComputeDepth(bary));
4219+
void Raster(const ImageRef& pt, const Triangle& t, const Point3f& bary) {
4220+
const Depth z(ComputeDepth(t, bary));
42134221
ASSERT(z > Depth(0));
42144222
Depth& depth = depthMap(pt);
42154223
if (depth == 0 || depth > z) {
@@ -4225,11 +4233,13 @@ void Mesh::ProjectOrtho(const Camera& camera, DepthMap& depthMap, Image8U3& imag
42254233
if (image.size() != depthMap.size())
42264234
image.create(depthMap.size());
42274235
RasterMesh rasterer(*this, camera, depthMap, image);
4236+
RasterMesh::Triangle triangle;
4237+
RasterMesh::TriangleRasterizer triangleRasterizer(triangle, rasterer);
42284238
rasterer.Clear();
42294239
FOREACH(idxFace, faces) {
42304240
const Face& facet = faces[idxFace];
42314241
rasterer.idxFaceTex = idxFace*3;
4232-
rasterer.Project(facet);
4242+
rasterer.Project(facet, triangleRasterizer);
42334243
}
42344244
}
42354245
// assuming the mesh is properly oriented, ortho-project it to a camera looking from top to down

libs/MVS/Mesh.h

+40-22
Original file line numberDiff line numberDiff line change
@@ -287,13 +287,16 @@ class MVS_API Mesh
287287
// used to render a 3D triangle
288288
template <typename DERIVED>
289289
struct TRasterMeshBase {
290-
const Camera& camera;
290+
typedef DERIVED Rasterizer;
291291

292+
struct Triangle {
293+
Point3 ptc[3];
294+
Point2f pti[3];
295+
};
296+
297+
const Camera& camera;
292298
DepthMap& depthMap;
293299

294-
Point3 ptc[3];
295-
Point2f pti[3];
296-
297300
TRasterMeshBase(const Camera& _camera, DepthMap& _depthMap)
298301
: camera(_camera), depthMap(_depthMap) {}
299302

@@ -304,55 +307,70 @@ struct TRasterMeshBase {
304307
return depthMap.size();
305308
}
306309

307-
inline bool ProjectVertex(const Point3f& pt, int v) {
308-
return (ptc[v] = camera.TransformPointW2C(Cast<REAL>(pt))).z > 0 &&
309-
depthMap.isInsideWithBorder<float,3>(pti[v] = camera.TransformPointC2I(ptc[v]));
310+
inline bool ProjectVertex(const Point3f& pt, int v, Triangle& t) {
311+
return (t.ptc[v] = camera.TransformPointW2C(Cast<REAL>(pt))).z > 0 &&
312+
depthMap.isInsideWithBorder<float,3>(t.pti[v] = camera.TransformPointC2I(t.ptc[v]));
310313
}
311314

312-
inline Point3f PerspectiveCorrectBarycentricCoordinates(const Point3f& bary) {
313-
return SEACAVE::PerspectiveCorrectBarycentricCoordinates(bary, (float)ptc[0].z, (float)ptc[1].z, (float)ptc[2].z);
315+
inline Point3f PerspectiveCorrectBarycentricCoordinates(const Triangle& t, const Point3f& bary) {
316+
return SEACAVE::PerspectiveCorrectBarycentricCoordinates(bary, (float)t.ptc[0].z, (float)t.ptc[1].z, (float)t.ptc[2].z);
314317
}
315-
inline float ComputeDepth(const Point3f& pbary) {
316-
return pbary[0]*(float)ptc[0].z + pbary[1]*(float)ptc[1].z + pbary[2]*(float)ptc[2].z;
318+
inline float ComputeDepth(const Triangle& t, const Point3f& pbary) {
319+
return pbary[0]*(float)t.ptc[0].z + pbary[1]*(float)t.ptc[1].z + pbary[2]*(float)t.ptc[2].z;
317320
}
318-
void Raster(const ImageRef& pt, const Point3f& bary) {
319-
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(bary));
320-
const Depth z(ComputeDepth(pbary));
321+
void Raster(const ImageRef& pt, const Triangle& t, const Point3f& bary) {
322+
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(t, bary));
323+
const Depth z(ComputeDepth(t, pbary));
321324
ASSERT(z > Depth(0));
322325
Depth& depth = depthMap(pt);
323326
if (depth == 0 || depth > z)
324327
depth = z;
325328
}
326-
inline void operator()(const ImageRef& pt, const Point3f& bary) {
327-
static_cast<DERIVED*>(this)->Raster(pt, bary);
329+
330+
struct TriangleRasterizer {
331+
Triangle& triangle;
332+
Rasterizer& rasterizer;
333+
TriangleRasterizer(Triangle& t, Rasterizer& r) : triangle(t), rasterizer(r) {}
334+
inline cv::Size Size() const {
335+
return rasterizer.Size();
336+
}
337+
inline void operator()(const ImageRef& pt, const Point3f& bary) const {
338+
rasterizer.Raster(pt, triangle, bary);
339+
}
340+
};
341+
inline TriangleRasterizer CreateTriangleRasterizer(Triangle& triangle) {
342+
return TriangleRasterizer(triangle, *static_cast<DERIVED*>(this));
328343
}
329344
};
330345

331346
// used to render a mesh
332347
template <typename DERIVED>
333348
struct TRasterMesh : TRasterMeshBase<DERIVED> {
334349
typedef TRasterMeshBase<DERIVED> Base;
350+
using typename Base::Triangle;
351+
using typename Base::TriangleRasterizer;
335352

336353
using Base::camera;
337354
using Base::depthMap;
338355

339-
using Base::ptc;
340-
using Base::pti;
341-
342356
const Mesh::VertexArr& vertices;
343357

344358
TRasterMesh(const Mesh::VertexArr& _vertices, const Camera& _camera, DepthMap& _depthMap)
345359
: Base(_camera, _depthMap), vertices(_vertices) {}
346360

347-
void Project(const Mesh::Face& facet) {
361+
void Project(const Mesh::Face& facet, TriangleRasterizer& tr) {
348362
// project face vertices to image plane
349363
for (int v=0; v<3; ++v) {
350364
// skip face if not completely inside
351-
if (!static_cast<DERIVED*>(this)->ProjectVertex(vertices[facet[v]], v))
365+
if (!static_cast<DERIVED*>(this)->ProjectVertex(vertices[facet[v]], v, tr.triangle))
352366
return;
353367
}
354368
// draw triangle
355-
Image8U3::RasterizeTriangleBary(pti[0], pti[1], pti[2], *this);
369+
Image8U3::RasterizeTriangleBary(tr.triangle.pti[0], tr.triangle.pti[1], tr.triangle.pti[2], tr);
370+
}
371+
void Project(const Mesh::Face& facet) {
372+
Triangle triangle;
373+
Project(facet, this->CreateTriangleRasterizer(triangle));
356374
}
357375
};
358376
/*----------------------------------------------------------------*/

libs/MVS/SceneRefine.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ class MeshRefine {
111111
faceMap.memset((uint8_t)NO_ID);
112112
baryMap.memset(0);
113113
}
114-
void Raster(const ImageRef& pt, const Point3f& bary) {
115-
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(bary));
116-
const Depth z(ComputeDepth(pbary));
114+
void Raster(const ImageRef& pt, const Triangle& t, const Point3f& bary) {
115+
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(t, bary));
116+
const Depth z(ComputeDepth(t, pbary));
117117
ASSERT(z > Depth(0));
118118
Depth& depth = depthMap(pt);
119119
if (depth == 0 || depth > z) {
@@ -734,11 +734,13 @@ void MeshRefine::ProjectMesh(
734734
baryMap.create(size);
735735
// project all triangles on this image and keep the closest ones
736736
RasterMesh rasterer(vertices, camera, depthMap, faceMap, baryMap);
737+
RasterMesh::Triangle triangle;
738+
RasterMesh::TriangleRasterizer triangleRasterizer(triangle, rasterer);
737739
rasterer.Clear();
738740
for (auto idxFace : cameraFaces) {
739741
const Face& facet = faces[idxFace];
740742
rasterer.idxFace = idxFace;
741-
rasterer.Project(facet);
743+
rasterer.Project(facet, triangleRasterizer);
742744
}
743745
}
744746

libs/MVS/SceneTexture.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ struct MeshTexture {
112112
Base::Clear();
113113
faceMap.memset((uint8_t)NO_ID);
114114
}
115-
void Raster(const ImageRef& pt, const Point3f& bary) {
116-
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(bary));
117-
const Depth z(ComputeDepth(pbary));
115+
void Raster(const ImageRef& pt, const Triangle& t, const Point3f& bary) {
116+
const Point3f pbary(PerspectiveCorrectBarycentricCoordinates(t, bary));
117+
const Depth z(ComputeDepth(t, pbary));
118118
ASSERT(z > Depth(0));
119119
Depth& depth = depthMap(pt);
120120
if (depth == 0 || depth > z) {
@@ -496,6 +496,8 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr
496496
faceMap.create(imageData.GetSize());
497497
depthMap.create(imageData.GetSize());
498498
RasterMesh rasterer(vertices, imageData.camera, depthMap, faceMap);
499+
RasterMesh::Triangle triangle;
500+
RasterMesh::TriangleRasterizer triangleRasterizer(triangle, rasterer);
499501
if (nIgnoreMaskLabel >= 0) {
500502
// import mask
501503
BitMatrix bmask;
@@ -513,9 +515,9 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr
513515
rasterer.validFace = true;
514516
const Face& facet = faces[idxFace];
515517
rasterer.idxFace = idxFace;
516-
rasterer.Project(facet);
518+
rasterer.Project(facet, triangleRasterizer);
517519
if (!rasterer.validFace)
518-
rasterer.Project(facet);
520+
rasterer.Project(facet, triangleRasterizer);
519521
}
520522
// compute the projection area of visible faces
521523
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA

0 commit comments

Comments
 (0)