Skip to content

Commit 208a441

Browse files
committed
common: implement assert with message
1 parent efce2f6 commit 208a441

File tree

10 files changed

+105
-141
lines changed

10 files changed

+105
-141
lines changed

apps/Tests/Tests.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ bool UnitTests()
7575
bool PipelineTest(bool verbose=false)
7676
{
7777
TD_TIMER_START();
78+
#if 0 && defined(_USE_CUDA)
79+
// force CPU for testing even if CUDA is available
80+
SEACAVE::CUDA::desiredDeviceID = -2;
81+
#endif
7882
Scene scene;
7983
if (!scene.Load(MAKE_PATH("scene.mvs"))) {
8084
VERBOSE("ERROR: TestDataset failed loading the scene!");
@@ -88,15 +92,15 @@ bool PipelineTest(bool verbose=false)
8892
}
8993
if (verbose)
9094
scene.pointcloud.Save(MAKE_PATH("scene_dense.ply"));
91-
if (!scene.ReconstructMesh() || scene.mesh.faces.size() < 40000u) {
95+
if (!scene.ReconstructMesh() || scene.mesh.faces.size() < 25000u) {
9296
VERBOSE("ERROR: TestDataset failed reconstructing the mesh!");
9397
return false;
9498
}
9599
if (verbose)
96100
scene.mesh.Save(MAKE_PATH("scene_dense_mesh.ply"));
97101
constexpr float decimate = 0.7f;
98102
scene.mesh.Clean(decimate);
99-
if (!ISINSIDE(scene.mesh.faces.size(), 25000u, 45000u)) {
103+
if (!ISINSIDE(scene.mesh.faces.size(), 20000u, 30000u)) {
100104
VERBOSE("ERROR: TestDataset failed cleaning the mesh!");
101105
return false;
102106
}

libs/Common/Common.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ namespace SEACAVE { extern int g_nVerbosityLevel; }
7878
#define LOG_ERR() GET_LOG() //or std::cerr
7979

8080

81+
#ifdef PRINT_ASSERT_MSG
82+
#undef PRINT_ASSERT_MSG
83+
#define PRINT_ASSERT_MSG(exp, ...) {std::cout << SEACAVE::PrintMessageToString("ASSERTION FAILED: (" #exp ") ", __VA_ARGS__) << std::endl;}
84+
#endif
85+
86+
8187
// macros simplifying the task of composing file paths;
8288
// WORKING_FOLDER and WORKING_FOLDER_FULL must be defined as strings
8389
// containing the relative/full path to the working folder
@@ -86,7 +92,7 @@ namespace SEACAVE {
8692
class String;
8793
extern String g_strWorkingFolder; // empty by default (current folder)
8894
extern String g_strWorkingFolderFull; // full path to current folder
89-
}
95+
} // namespace SEACAVE
9096
#define WORKING_FOLDER g_strWorkingFolder // empty by default (current folder)
9197
#define WORKING_FOLDER_FULL g_strWorkingFolderFull // full path to current folder
9298
#endif

libs/Common/Config.h

+13-5
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@
216216
#define SAFE_RELEASE(p) { if (p!=NULL) { (p)->Release(); (p)=NULL; } }
217217

218218

219+
#define PRINT_ASSERT_MSG(exp, ...)
220+
219221
#ifdef _DEBUG
220222

221223
#ifdef _MSC_VER
@@ -224,26 +226,32 @@
224226
#include <cstdlib>
225227
#include <crtdbg.h>
226228
#ifdef _INC_CRTDBG
227-
#define ASSERT(exp, ...) {if (!(exp) && 1 == _CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, NULL, #exp)) _CrtDbgBreak();}
229+
#define SIMPLE_ASSERT(exp) {if (!(exp) && 1 == _CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, NULL, #exp)) _CrtDbgBreak();}
230+
#define ASSERT(exp, ...) {static bool bIgnore(false); if (!bIgnore && !(exp)) {PRINT_ASSERT_MSG(exp, __VA_ARGS__); if (!(bIgnore = !(1 == _CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, NULL, #exp)))) _CrtDbgBreak();}}
228231
#else
229-
#define ASSERT(exp, ...) {if (!(exp)) __debugbreak();}
232+
#define SIMPLE_ASSERT(exp) {if (!(exp)) __debugbreak();}
233+
#define ASSERT(exp, ...) {if (!(exp)) {PRINT_ASSERT_MSG(exp, __VA_ARGS__); __debugbreak();}}
230234
#endif // _INC_CRTDBG
231235
#define TRACE(...) {TCHAR buffer[2048]; _sntprintf(buffer, 2048, __VA_ARGS__); OutputDebugString(buffer);}
232236
#else // _MSC_VER
233237
#include <assert.h>
234-
#define ASSERT(exp, ...) assert(exp)
238+
#define SIMPLE_ASSERT(exp) {if (!(exp)) assert(exp);}
239+
#define ASSERT(exp, ...) {if (!(exp)) {PRINT_ASSERT_MSG(exp, __VA_ARGS__); assert(exp);}}
235240
#define TRACE(...)
236241
#endif // _MSC_VER
237242

238243
#else
239244

240245
#ifdef _RELEASE
246+
#define SIMPLE_ASSERT(exp)
241247
#define ASSERT(exp, ...)
242248
#else
243249
#ifdef _MSC_VER
244-
#define ASSERT(exp, ...) {if (!(exp)) __debugbreak();}
250+
#define SIMPLE_ASSERT(exp) {if (!(exp)) __debugbreak();}
251+
#define ASSERT(exp, ...) {if (!(exp)) {PRINT_ASSERT_MSG(exp, __VA_ARGS__); __debugbreak();}}
245252
#else // _MSC_VER
246-
#define ASSERT(exp, ...) {if (!(exp)) __builtin_trap();}
253+
#define SIMPLE_ASSERT(exp) {if (!(exp)) __builtin_trap();}
254+
#define ASSERT(exp, ...) {if (!(exp)) {PRINT_ASSERT_MSG(exp, __VA_ARGS__); __builtin_trap();}}
247255
#endif // _MSC_VER
248256
#endif
249257
#define TRACE(...)

libs/Common/Rotation.inl

+6-6
Original file line numberDiff line numberDiff line change
@@ -1176,8 +1176,8 @@ void TRMatrixBase<TYPE>::SetFromHV(const Vec& xxx, const Vec& yyy)
11761176
template <typename TYPE>
11771177
TRMatrixBase<TYPE>& TRMatrixBase<TYPE>::SetFromDir2Dir(const Vec& dir0, const Vec& dir1)
11781178
{
1179-
ASSERT(ISEQUAL(norm(dir0), TYPE(1)));
1180-
ASSERT(ISEQUAL(norm(dir1), TYPE(1)));
1179+
ASSERT(ISEQUAL(norm(dir0), TYPE(1)), "Norm = ", norm(dir0));
1180+
ASSERT(ISEQUAL(norm(dir1), TYPE(1)), "Norm = ", norm(dir1));
11811181
const TYPE cos01(CLAMP(dir1.dot(dir0), TYPE(-1), TYPE(1)));
11821182
const TYPE sin01Sq(TYPE(1) - SQUARE(cos01));
11831183
if (sin01Sq > EPSILONTOLERANCE<TYPE>()) {
@@ -1203,8 +1203,8 @@ TRMatrixBase<TYPE>& TRMatrixBase<TYPE>::SetFromDir2Dir(const Vec& dir0, const Ve
12031203
template <typename TYPE>
12041204
void TRMatrixBase<TYPE>::SetFromDirUpGL(const Vec& viewDir, const Vec& viewUp)
12051205
{
1206-
ASSERT(ISEQUAL(norm(viewDir), TYPE(1)));
1207-
ASSERT(ISEQUAL(norm(viewUp), TYPE(1)));
1206+
ASSERT(ISEQUAL(norm(viewDir), TYPE(1)), "Norm = ", norm(viewDir));
1207+
ASSERT(ISEQUAL(norm(viewUp), TYPE(1)), "Norm = ", norm(viewUp));
12081208
const Vec right(normalized(cross(viewDir, viewUp)));
12091209
const Vec up(normalized(cross(right, viewDir)));
12101210
const Vec forward(viewDir * TYPE(-1)); // convert to right handed system
@@ -1214,8 +1214,8 @@ void TRMatrixBase<TYPE>::SetFromDirUpGL(const Vec& viewDir, const Vec& viewUp)
12141214
template <typename TYPE>
12151215
void TRMatrixBase<TYPE>::SetFromDirUp(const Vec& viewDir, const Vec& viewUp)
12161216
{
1217-
ASSERT(ISEQUAL(norm(viewDir), TYPE(1)));
1218-
ASSERT(ISEQUAL(norm(viewUp), TYPE(1)));
1217+
ASSERT(ISEQUAL(norm(viewDir), TYPE(1)), "Norm = ", norm(viewDir));
1218+
ASSERT(ISEQUAL(norm(viewUp), TYPE(1)), "Norm = ", norm(viewUp));
12191219
const Vec right(normalized(cross(viewDir, viewUp)));
12201220
const Vec up(normalized(cross(viewDir, right)));
12211221
const Vec& forward(viewDir);

libs/Common/Types.h

+21-2
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,25 @@ typedef TAliasCast<double,int32_t> CastD2I;
378378
#endif
379379

380380

381+
// functions simplifying the task of printing messages
382+
namespace SEACAVE {
383+
// print the given message composed of any number of arguments to the given stream
384+
template<typename... Args>
385+
std::ostringstream& PrintMessageToStream(std::ostringstream& oss, Args&&... args) {
386+
// fold expression to insert all arguments into the stream
387+
(oss << ... << args);
388+
return oss;
389+
}
390+
// print the given message composed of any number of arguments to a string
391+
template<typename... Args>
392+
std::string PrintMessageToString(Args&&... args) {
393+
std::ostringstream oss;
394+
(oss << ... << args);
395+
return oss.str();
396+
}
397+
} // namespace SEACAVE
398+
399+
381400
// I N C L U D E S /////////////////////////////////////////////////
382401

383402
#include "Strings.h"
@@ -681,13 +700,13 @@ constexpr T factorial(T n) {
681700
}
682701
template<typename T>
683702
constexpr T combinations(const T& n, const T& k) {
684-
ASSERT(n >= k);
703+
SIMPLE_ASSERT(n >= k);
685704
#if 1
686705
T num = n;
687706
const T den = factorial(k);
688707
for (T i=n-k+1; i<n; ++i)
689708
num *= i;
690-
ASSERT(num%den == 0);
709+
SIMPLE_ASSERT(num%den == 0);
691710
return num/den;
692711
#else
693712
return factorial(n) / (factorial(k)*factorial(n-k));

libs/Common/Util.inl

+2-2
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ inline TPoint3<TYPE> PerspectiveCorrectBarycentricCoordinates(const TPoint3<TYPE
752752
// Encodes/decodes a normalized 3D vector in two parameters for the direction
753753
template<typename T, typename TR>
754754
inline void Normal2Dir(const TPoint3<T>& d, TPoint2<TR>& p) {
755-
ASSERT(ISEQUAL(norm(d), T(1)));
755+
ASSERT(ISEQUAL(norm(d), T(1)), "Norm = ", norm(d));
756756
p.x = TR(atan2(d.y, d.x));
757757
p.y = TR(acos(d.z));
758758
}
@@ -762,7 +762,7 @@ inline void Dir2Normal(const TPoint2<T>& p, TPoint3<TR>& d) {
762762
d.x = TR(cos(p.x)*siny);
763763
d.y = TR(sin(p.x)*siny);
764764
d.z = TR(cos(p.y));
765-
ASSERT(ISEQUAL(norm(d), TR(1)));
765+
ASSERT(ISEQUAL(norm(d), TR(1)), "Norm = ", norm(d));
766766
}
767767
// Encodes/decodes a 3D vector in two parameters for the direction and one parameter for the scale
768768
template<typename T, typename TR>

libs/MVS/DepthMap.cpp

+42-115
Original file line numberDiff line numberDiff line change
@@ -663,130 +663,57 @@ void DepthEstimator::ProcessPixel(IDX idx)
663663
#if DENSE_SMOOTHNESS != DENSE_SMOOTHNESS_NA
664664
neighborsClose.Empty();
665665
#endif
666-
if (dir == LT2RB) {
667-
// direction from left-top to right-bottom corner
668-
if (x0.x > nSizeHalfWindow) {
669-
const ImageRef nx(x0.x-1, x0.y);
670-
const Depth ndepth(depthMap0(nx));
671-
if (ndepth > 0) {
672-
#if DENSE_SMOOTHNESS != DENSE_SMOOTHNESS_NA
673-
ASSERT(ISEQUAL(norm(normalMap0(nx)), 1.f));
674-
neighbors.emplace_back(nx);
675-
neighborsClose.emplace_back(NeighborEstimate{ndepth,normalMap0(nx)
676-
#if DENSE_SMOOTHNESS == DENSE_SMOOTHNESS_PLANE
677-
, Cast<float>(image0.camera.TransformPointI2C(Point3(nx, ndepth)))
678-
#endif
679-
});
680-
#else
681-
neighbors.emplace_back(NeighborData{nx,ndepth,normalMap0(nx)});
666+
const auto AddDirectionNeighbor = [this] (const ImageRef& nx) {
667+
const Depth ndepth(depthMap0(nx));
668+
if (ndepth > 0) {
669+
#if DENSE_SMOOTHNESS != DENSE_SMOOTHNESS_NA
670+
ASSERT(ISEQUAL(norm(normalMap0(nx)), 1.f), "Norm = ", norm(normalMap0(nx)));
671+
neighbors.emplace_back(nx);
672+
neighborsClose.emplace_back(NeighborEstimate{ndepth, normalMap0(nx)
673+
#if DENSE_SMOOTHNESS == DENSE_SMOOTHNESS_PLANE
674+
, Cast<float>(image0.camera.TransformPointI2C(Point3(nx, ndepth)))
682675
#endif
683-
}
676+
});
677+
#else
678+
neighbors.emplace_back(NeighborData{nx,ndepth,normalMap0(nx)});
679+
#endif
684680
}
685-
if (x0.y > nSizeHalfWindow) {
686-
const ImageRef nx(x0.x, x0.y-1);
687-
const Depth ndepth(depthMap0(nx));
688-
if (ndepth > 0) {
689-
#if DENSE_SMOOTHNESS != DENSE_SMOOTHNESS_NA
690-
ASSERT(ISEQUAL(norm(normalMap0(nx)), 1.f));
691-
neighbors.emplace_back(nx);
692-
neighborsClose.emplace_back(NeighborEstimate{ndepth,normalMap0(nx)
693-
#if DENSE_SMOOTHNESS == DENSE_SMOOTHNESS_PLANE
694-
, Cast<float>(image0.camera.TransformPointI2C(Point3(nx, ndepth)))
695-
#endif
696-
});
697-
#else
698-
neighbors.emplace_back(NeighborData{nx,ndepth,normalMap0(nx)});
681+
};
682+
const auto AddDirection = [this] (const ImageRef& nx) {
683+
const Depth ndepth(depthMap0(nx));
684+
if (ndepth > 0) {
685+
ASSERT(ISEQUAL(norm(normalMap0(nx)), 1.f), "Norm = ", norm(normalMap0(nx)));
686+
neighborsClose.emplace_back(NeighborEstimate{ndepth, normalMap0(nx)
687+
#if DENSE_SMOOTHNESS == DENSE_SMOOTHNESS_PLANE
688+
, Cast<float>(image0.camera.TransformPointI2C(Point3(nx, ndepth)))
699689
#endif
700-
}
701-
}
702-
#if DENSE_SMOOTHNESS != DENSE_SMOOTHNESS_NA
703-
if (x0.x < size.width-nSizeHalfWindow) {
704-
const ImageRef nx(x0.x+1, x0.y);
705-
const Depth ndepth(depthMap0(nx));
706-
if (ndepth > 0) {
707-
ASSERT(ISEQUAL(norm(normalMap0(nx)), 1.f));
708-
neighborsClose.emplace_back(NeighborEstimate{ndepth,normalMap0(nx)
709-
#if DENSE_SMOOTHNESS == DENSE_SMOOTHNESS_PLANE
710-
, Cast<float>(image0.camera.TransformPointI2C(Point3(nx, ndepth)))
711-
#endif
712-
});
713-
}
714-
}
715-
if (x0.y < size.height-nSizeHalfWindow) {
716-
const ImageRef nx(x0.x, x0.y+1);
717-
const Depth ndepth(depthMap0(nx));
718-
if (ndepth > 0) {
719-
ASSERT(ISEQUAL(norm(normalMap0(nx)), 1.f));
720-
neighborsClose.emplace_back(NeighborEstimate{ndepth,normalMap0(nx)
721-
#if DENSE_SMOOTHNESS == DENSE_SMOOTHNESS_PLANE
722-
, Cast<float>(image0.camera.TransformPointI2C(Point3(nx, ndepth)))
723-
#endif
724690
});
725-
}
726691
}
692+
};
693+
if (dir == LT2RB) {
694+
// direction from left-top to right-bottom corner
695+
if (x0.x > nSizeHalfWindow)
696+
AddDirectionNeighbor(ImageRef(x0.x-1, x0.y));
697+
if (x0.y > nSizeHalfWindow)
698+
AddDirectionNeighbor(ImageRef(x0.x, x0.y-1));
699+
#if DENSE_SMOOTHNESS != DENSE_SMOOTHNESS_NA
700+
if (x0.x < size.width-nSizeHalfWindow)
701+
AddDirection(ImageRef(x0.x+1, x0.y));
702+
if (x0.y < size.height-nSizeHalfWindow)
703+
AddDirection(ImageRef(x0.x, x0.y+1));
727704
#endif
728705
} else {
729706
ASSERT(dir == RB2LT);
730707
// direction from right-bottom to left-top corner
731-
if (x0.x < size.width-nSizeHalfWindow) {
732-
const ImageRef nx(x0.x+1, x0.y);
733-
const Depth ndepth(depthMap0(nx));
734-
if (ndepth > 0) {
735-
#if DENSE_SMOOTHNESS != DENSE_SMOOTHNESS_NA
736-
ASSERT(ISEQUAL(norm(normalMap0(nx)), 1.f));
737-
neighbors.emplace_back(nx);
738-
neighborsClose.emplace_back(NeighborEstimate{ndepth,normalMap0(nx)
739-
#if DENSE_SMOOTHNESS == DENSE_SMOOTHNESS_PLANE
740-
, Cast<float>(image0.camera.TransformPointI2C(Point3(nx, ndepth)))
741-
#endif
742-
});
743-
#else
744-
neighbors.emplace_back(NeighborData{nx,ndepth,normalMap0(nx)});
745-
#endif
746-
}
747-
}
748-
if (x0.y < size.height-nSizeHalfWindow) {
749-
const ImageRef nx(x0.x, x0.y+1);
750-
const Depth ndepth(depthMap0(nx));
751-
if (ndepth > 0) {
752-
#if DENSE_SMOOTHNESS != DENSE_SMOOTHNESS_NA
753-
ASSERT(ISEQUAL(norm(normalMap0(nx)), 1.f));
754-
neighbors.emplace_back(nx);
755-
neighborsClose.emplace_back(NeighborEstimate{ndepth,normalMap0(nx)
756-
#if DENSE_SMOOTHNESS == DENSE_SMOOTHNESS_PLANE
757-
, Cast<float>(image0.camera.TransformPointI2C(Point3(nx, ndepth)))
758-
#endif
759-
});
760-
#else
761-
neighbors.emplace_back(NeighborData{nx,ndepth,normalMap0(nx)});
762-
#endif
763-
}
764-
}
708+
if (x0.x < size.width-nSizeHalfWindow)
709+
AddDirectionNeighbor(ImageRef(x0.x+1, x0.y));
710+
if (x0.y < size.height-nSizeHalfWindow)
711+
AddDirectionNeighbor(ImageRef(x0.x, x0.y+1));
765712
#if DENSE_SMOOTHNESS != DENSE_SMOOTHNESS_NA
766-
if (x0.x > nSizeHalfWindow) {
767-
const ImageRef nx(x0.x-1, x0.y);
768-
const Depth ndepth(depthMap0(nx));
769-
if (ndepth > 0) {
770-
ASSERT(ISEQUAL(norm(normalMap0(nx)), 1.f));
771-
neighborsClose.emplace_back(NeighborEstimate{ndepth,normalMap0(nx)
772-
#if DENSE_SMOOTHNESS == DENSE_SMOOTHNESS_PLANE
773-
, Cast<float>(image0.camera.TransformPointI2C(Point3(nx, ndepth)))
774-
#endif
775-
});
776-
}
777-
}
778-
if (x0.y > nSizeHalfWindow) {
779-
const ImageRef nx(x0.x, x0.y-1);
780-
const Depth ndepth(depthMap0(nx));
781-
if (ndepth > 0) {
782-
ASSERT(ISEQUAL(norm(normalMap0(nx)), 1.f));
783-
neighborsClose.emplace_back(NeighborEstimate{ndepth,normalMap0(nx)
784-
#if DENSE_SMOOTHNESS == DENSE_SMOOTHNESS_PLANE
785-
, Cast<float>(image0.camera.TransformPointI2C(Point3(nx, ndepth)))
786-
#endif
787-
});
788-
}
789-
}
713+
if (x0.x > nSizeHalfWindow)
714+
AddDirection(ImageRef(x0.x-1, x0.y));
715+
if (x0.y > nSizeHalfWindow)
716+
AddDirection(ImageRef(x0.x, x0.y-1));
790717
#endif
791718
}
792719
float& conf = confMap0(x0);
@@ -1027,7 +954,7 @@ DepthEstimator::PixelEstimate DepthEstimator::PerturbEstimate(const PixelEstimat
1027954
}
1028955
perturbation *= 0.5f;
1029956
}
1030-
ASSERT(ISEQUAL(norm(ptbEst.normal), 1.f));
957+
ASSERT(ISEQUAL(norm(ptbEst.normal), 1.f), "Norm = ", norm(ptbEst.normal));
1031958

1032959
return ptbEst;
1033960
}

libs/MVS/DepthMap.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ struct MVS_API DepthEstimator {
453453
inline Normal RandomNormal(const Point3f& viewRay) {
454454
Normal normal;
455455
Dir2Normal(Point2f(rnd.randomRange(FD2R(0.f),FD2R(180.f)), rnd.randomRange(FD2R(90.f),FD2R(180.f))), normal);
456-
ASSERT(ISEQUAL(norm(normal), 1.f));
456+
ASSERT(ISEQUAL(norm(normal), 1.f), "Norm = ", norm(normal));
457457
return normal.dot(viewRay) > 0 ? -normal : normal;
458458
}
459459

@@ -463,7 +463,7 @@ struct MVS_API DepthEstimator {
463463
const float cosAngLen(normal.dot(viewDir));
464464
if (cosAngLen >= 0)
465465
normal = RMatrixBaseF(normal.cross(viewDir), MINF((ACOS(cosAngLen/norm(viewDir))-FD2R(90.f))*1.01f, -0.001f)) * normal;
466-
ASSERT(ISEQUAL(norm(normal), 1.f));
466+
ASSERT(ISEQUAL(norm(normal), 1.f), "Norm = ", norm(normal));
467467
}
468468

469469
static bool ImportIgnoreMask(const Image&, const Image8U::Size&, uint16_t nIgnoreMaskLabel, BitMatrix&, Image8U* =NULL);

libs/MVS/Scene.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1847,7 +1847,7 @@ size_t Scene::DrawCircle(PointCloud& pc, PointCloud::PointArr& outCircle, const
18471847
const float fAngle(fStartAngle + fAngleBetweenPoints * pIdx);
18481848
ASSERT(fAngle <= FTWO_PI);
18491849
const Normal n(cos(fAngle), sin(fAngle), 0);
1850-
ASSERT(ISEQUAL(norm(n), 1.f));
1850+
ASSERT(ISEQUAL(norm(n), 1.f), "Norm = ", norm(n));
18511851
const Point3f newPoint(circleCenter + circleRadius * n);
18521852
// select cameras seeing this point
18531853
PointCloud::ViewArr views;

0 commit comments

Comments
 (0)