Skip to content

Commit

Permalink
Green tests! (#3297)
Browse files Browse the repository at this point in the history
* Green tests!

* Add `MR_BIND_TEMPLATE`. Fail the build if the tests fail.
  • Loading branch information
adalisk-emikhaylov authored Sep 4, 2024
1 parent 7b9ca5c commit ed0b58b
Show file tree
Hide file tree
Showing 11 changed files with 186 additions and 13 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build-test-ubuntu-x64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ jobs:
repository: MeshInspector/mrbind
path: _mrbind
token: ${{ secrets.BUILD_MACHINE_TOKEN }}
ref: 83a53a39c1f0dbb5564a47355026406ead99946b
ref: b8448867e913efe0561404597b575588a20b674b

- name: Compile MRBind
if: ${{ matrix.os == 'ubuntu24' }}
Expand Down Expand Up @@ -170,7 +170,7 @@ jobs:
LD_LIBRARY_PATH: .
USE_MESHLIB2_PY: 1
working-directory: build/${{ matrix.config }}/bin
run: python3 ./../../../scripts/run_python_test_script.py -d '../test_python' || true
run: python3 ./../../../scripts/run_python_test_script.py -d '../test_python'

- name: Collect Timings
run: ./scripts/devops/collect_timing_logs.sh ${{matrix.os}} ${{matrix.config}} "${{matrix.compiler}}"
Expand Down
2 changes: 1 addition & 1 deletion scripts/mrbind/compiler_only_flags.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
-I_mrbind/include -Wno-deprecated-declarations -Wno-implicitly-unsigned-literal -fPIC -DMR_COMPILING_PB11_BINDINGS -DMRBIND_HEADER='<mrbind/targets/pybind11.h>' -DMB_PB11_MODULE_NAME=mrmeshpy -DMB_PB11_ADJUST_NAMES='"s/\\bMR:://g;s/\\bvec_\\b/vec/"' -DMB_PB11_ENABLE_CXX_STYLE_CONTAINER_METHODS
-I_mrbind/include -Wno-deprecated-declarations -Wno-implicitly-unsigned-literal -fPIC -DMR_COMPILING_PB11_BINDINGS -DMRBIND_HEADER='<mrbind/targets/pybind11.h>' -DMB_PB11_MODULE_NAME=mrmeshpy -DMB_PB11_ADJUST_NAMES='"s/\\bMR::Extra:://g;s/\\bMR:://g;s/\\bvec_\\b/vec/"' -DMB_PB11_ENABLE_CXX_STYLE_CONTAINER_METHODS
15 changes: 10 additions & 5 deletions scripts/mrbind/generate.mk
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,40 @@ DEPS_BASE_DIR := .
# ]

MODULE_OUTPUT_DIR := $(MESHLIB_SHLIB_DIR)/meshlib2
MRBIND_FLAGS := $(file <$(makefile_dir)/mrbind_flags.txt)

# Those variables are for mrbind/scripts/apply_to_files.mk
INPUT_DIRS := $(addprefix $(makefile_dir)/../../source/,MRMesh MRSymbolMesh) $(makefile_dir)
INPUT_FILES_BLACKLIST := $(file <$(makefile_dir)/input_file_blacklist.txt)
OUTPUT_DIR := build/binds
INPUT_GLOBS := *.h
MRBIND := $(MRBIND_EXE) $(MRBIND_FLAGS)
MRBIND := $(MRBIND_EXE)
MRBIND_FLAGS := $(file <$(makefile_dir)/mrbind_flags.txt)
MRBIND_FLAGS_FOR_EXTRA_INPUTS := $(file <$(makefile_dir)/mrbind_flags_for_helpers.txt)
COMPILER_FLAGS := $(file <$(makefile_dir)/common_compiler_parser_flags.txt) $(shell pkg-config --cflags python3-embed) -I. -I$(DEPS_BASE_DIR)/include -I$(makefile_dir)/../../source
COMPILER_FLAGS_LIBCLANG := $(file <$(makefile_dir)/parser_only_flags.txt)
COMPILER := $(CXX) $(file <$(makefile_dir)/compiler_only_flags.txt) -I$(MRBIND_SOURCE)/include
LINKER_OUTPUT := $(MODULE_OUTPUT_DIR)/mrmeshpy$(shell python3-config --extension-suffix)
LINKER := $(CXX) -fuse-ld=lld
LINKER_FLAGS := -Wl,-rpath='$$ORIGIN/..:$$ORIGIN' $(shell pkg-config --libs python3-embed) -L$(DEPS_BASE_DIR)/lib -L$(MESHLIB_SHLIB_DIR) -lMRMesh -lMRSymbolMesh -shared $(file <$(makefile_dir)/linker_flags.txt)
NUM_FRAGMENTS := 4
EXTRA_INPUT_SOURCES := $(makefile_dir)/helpers.cpp

override mrbind_vars = $(subst $,$$$$, \
INPUT_DIRS=$(call quote,$(INPUT_DIRS)) \
INPUT_FILES_BLACKLIST=$(call quote,$(INPUT_FILES_BLACKLIST)) \
OUTPUT_DIR=$(call quote,$(OUTPUT_DIR)) \
INPUT_GLOBS=$(call quote,$(INPUT_GLOBS)) \
MRBIND=$(call quote,$(MRBIND)) \
MRBIND_FLAGS=$(call quote,$(MRBIND_FLAGS)) \
MRBIND_FLAGS_FOR_EXTRA_INPUTS=$(call quote,$(MRBIND_FLAGS_FOR_EXTRA_INPUTS)) \
COMPILER_FLAGS=$(call quote,$(COMPILER_FLAGS)) \
COMPILER_FLAGS_LIBCLANG=$(call quote,$(COMPILER_FLAGS_LIBCLANG)) \
COMPILER=$(call quote,$(COMPILER)) \
LINKER_OUTPUT=$(call quote,$(LINKER_OUTPUT)) \
LINKER=$(call quote,$(LINKER)) \
LINKER_FLAGS=$(call quote,$(LINKER_FLAGS)) \
NUM_FRAGMENTS=$(call quote,$(NUM_FRAGMENTS)) \
EXTRA_INPUT_SOURCES=$(call quote,$(EXTRA_INPUT_SOURCES)) \
)

# Generated mrmeshpy.
Expand All @@ -69,8 +74,8 @@ only-generate:
$(MAKE) -f $(MRBIND_SOURCE)/scripts/apply_to_files.mk generate $(mrbind_vars)

# Handwritten mrmeshnumpy.
MRMESHPY_MODULE := $(MODULE_OUTPUT_DIR)/mrmeshnumpy$(shell python3-config --extension-suffix)
$(MRMESHPY_MODULE): | $(MODULE_OUTPUT_DIR)
MRMESHNUMPY_MODULE := $(MODULE_OUTPUT_DIR)/mrmeshnumpy$(shell python3-config --extension-suffix)
$(MRMESHNUMPY_MODULE): | $(MODULE_OUTPUT_DIR)
$(CXX) \
-o $@ \
$(makefile_dir)/../../source/mrmeshnumpy/*.cpp \
Expand All @@ -82,7 +87,7 @@ $(MRMESHPY_MODULE): | $(MODULE_OUTPUT_DIR)
# All modules.
.DEFAULT_GOAL := all
.PHONY: all
all: $(LINKER_OUTPUT) $(MRMESHPY_MODULE)
all: $(LINKER_OUTPUT) $(MRMESHNUMPY_MODULE)

# The directory for the modules.
$(MODULE_OUTPUT_DIR):
Expand Down
117 changes: 117 additions & 0 deletions scripts/mrbind/helpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include "MRMesh/MRBitSetParallelFor.h"
#include "MRMesh/MRBoolean.h"
#include "MRMesh/MREdgeIterator.h"
#include "MRMesh/MRMesh.h"
#include "MRMesh/MRPointsToMeshProjector.h"

// Only the functions that should be exported should be in `MR::Extra`. Place everything else somewhere outside.
// Note that the comments are pasted to Python too.

namespace MR::Extra
{
// Fix self-intersections by converting to voxels and back.
void fixSelfIntersections( Mesh& mesh, float voxelSize )
{
MeshVoxelsConverter convert;
convert.voxelSize = voxelSize;
auto gridA = convert(mesh);
mesh = convert(gridA);
}

// Subtract mesh B from mesh A.
Mesh voxelBooleanSubtract( const Mesh& mesh1, const Mesh& mesh2, float voxelSize )
{
MeshVoxelsConverter convert;
convert.voxelSize = voxelSize;
auto gridA = convert(mesh1);
auto gridB = convert(mesh2);
gridA -= gridB;
return convert(gridA);
}

// Unite mesh A and mesh B.
Mesh voxelBooleanUnite( const Mesh& mesh1, const Mesh& mesh2, float voxelSize )
{
MeshVoxelsConverter convert;
convert.voxelSize = voxelSize;
auto gridA = convert(mesh1);
auto gridB = convert(mesh2);
gridA += gridB;
return convert( gridA );
}

// Intersect mesh A and mesh B.
Mesh voxelBooleanIntersect( const Mesh& mesh1, const Mesh& mesh2, float voxelSize )
{
MeshVoxelsConverter convert;
convert.voxelSize = voxelSize;
auto gridA = convert(mesh1);
auto gridB = convert(mesh2);
gridA *= gridB;
return convert( gridA );
}

// Computes signed distances from all mesh points to refMesh.
// `refMesh` - all points will me projected to this mesh
// `mesh` - this mesh points will be projected
// `refXf` - world transform for refMesh
// `upDistLimitSq` - upper limit on the distance in question, if the real distance is larger than the returning upDistLimit
// `loDistLimitSq` - low limit on the distance in question, if a point is found within this distance then it is immediately returned without searching for a closer one
VertScalars projectAllMeshVertices( const Mesh& refMesh, const Mesh& mesh, const AffineXf3f* refXf = nullptr, const AffineXf3f* xf = nullptr, float upDistLimitSq = FLT_MAX, float loDistLimitSq = 0.0f )
{
PointsToMeshProjector projector;
projector.updateMeshData( &refMesh );
std::vector<MeshProjectionResult> mpRes( mesh.points.vec_.size() );
projector.findProjections( mpRes, mesh.points.vec_, xf, refXf, upDistLimitSq, loDistLimitSq );
VertScalars res( mesh.topology.lastValidVert() + 1, std::sqrt( upDistLimitSq ) );

AffineXf3f fullXf;
if ( refXf )
fullXf = refXf->inverse();
if ( xf )
fullXf = fullXf * ( *xf );

BitSetParallelFor( mesh.topology.getValidVerts(), [&] ( VertId v )
{
const auto& mpResV = mpRes[v.get()];
auto& resV = res[v];

resV = mpResV.distSq;
if ( mpResV.mtp.e )
resV = refMesh.signedDistance( fullXf( mesh.points[v] ), mpResV );
else
resV = std::sqrt( resV );
} );
return res;
}

// Merge a list of meshes to one mesh.
Mesh mergeMeshes( const std::vector<std::shared_ptr<MR::Mesh>>& meshes )
{
Mesh res;
for ( const auto& m : meshes )
res.addPart( *m );
return res;
}

// Return faces with at least one edge longer than the specified length.
FaceBitSet getFacesByMinEdgeLength( const Mesh& mesh, float minLength )
{
using namespace MR;
FaceBitSet resultFaces( mesh.topology.getValidFaces().size() );
float minLengthSq = minLength * minLength;
for ( auto ue : undirectedEdges( mesh.topology ) )
{
if ( mesh.edgeLengthSq( ue ) > minLengthSq )
{
auto l = mesh.topology.left( ue );
auto r = mesh.topology.right( ue );
if ( l )
resultFaces.set( l );
if ( r )
resultFaces.set( r );
}
}
return resultFaces;
}
}
2 changes: 1 addition & 1 deletion scripts/mrbind/mrbind_flags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
--ignore MR::detail
--ignore MR::Signal
--ignore MR::UniquePtr
--ignore MR::OpenVdbFloatGrid
--ignore MR::RegisterRenderObjectConstructor
--ignore MR::Config
--allow std::integral_constant
--skip-base boost::dynamic_bitset
--skip-base /openvdb::v[0-9][0-9_a-zA-Z]*::Grid/
4 changes: 4 additions & 0 deletions scripts/mrbind/mrbind_flags_for_helpers.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
--format=macros
--ignore-pch-flags
--ignore ::
--allow MR::Extra
20 changes: 20 additions & 0 deletions source/MRMesh/MRBindingMacros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

// Those macros help control Python bindings generated using MRBind.

// MR_PARSING_FOR_PB11_BINDINGS - gets defined when parsing the source code
// MR_COMPILING_PB11_BINDINGS - gets defined when compiling the resulting bindings

// Use to specify valid template arguments for templates (usually function templates).
// For example:
// template <typename T> void foo(T) {...};
// MR_BIND_TEMPLATE( void foo(int) )
// MR_BIND_TEMPLATE( void foo(float) )
//
// As with `extern template`, you might need to use `foo<...>` instead of `foo` if the template parameters can't be deduced from the
// parameter types and the return type.
#ifdef MR_PARSING_FOR_PB11_BINDINGS
#define MR_BIND_TEMPLATE(...) extern template __VA_ARGS__;
#else
#define MR_BIND_TEMPLATE(...)
#endif
11 changes: 11 additions & 0 deletions source/MRMesh/MRContour.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "MRBindingMacros.h"
#include "MRMeshFwd.h"
#include "MRVector3.h"

Expand Down Expand Up @@ -77,4 +78,14 @@ To copyContours( const From & from )

/// \}

// Instantiate the templates when generating bindings.
MR_BIND_TEMPLATE( float calcOrientedArea( const Contour2<float> & contour ) )
MR_BIND_TEMPLATE( double calcOrientedArea( const Contour2<double> & contour ) )
MR_BIND_TEMPLATE( Vector3<float> calcOrientedArea( const Contour3<float> & contour ) )
MR_BIND_TEMPLATE( Vector3<double> calcOrientedArea( const Contour3<double> & contour ) )
MR_BIND_TEMPLATE( Contour2<float> copyContour( const Contour2<double> & from ) )
MR_BIND_TEMPLATE( Contour3<float> copyContour( const Contour3<double> & from ) )
MR_BIND_TEMPLATE( Contour2<double> copyContour( const Contour2<float> & from ) )
MR_BIND_TEMPLATE( Contour3<double> copyContour( const Contour3<float> & from ) )

} // namespace MR
1 change: 1 addition & 0 deletions source/MRMesh/MRMesh.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@
<ClInclude Include="MRMacros.h" />
<ClInclude Include="MRTeethMaskToDirectionVolume.h" />
<ClInclude Include="MRCanonicalTypedefs.h" />
<ClInclude Include="MRBindingMacros.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="MR2DContoursTriangulation.cpp" />
Expand Down
9 changes: 7 additions & 2 deletions source/MRMesh/MRMesh.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -1335,7 +1335,12 @@
<ClInclude Include="MRMeshAttributesToUpdate.h">
<Filter>Source Files\MeshAlgorithm</Filter>
</ClInclude>
<ClInclude Include="MRCanonicalTypedefs.h" />
<ClInclude Include="MRBindingMacros.h">
<Filter>Source Files\Basic</Filter>
</ClInclude>
<ClInclude Include="MRCanonicalTypedefs.h">
<Filter>Source Files\Basic</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="MRObject.cpp">
Expand Down Expand Up @@ -2226,4 +2231,4 @@
<Filter>Source Files\Python</Filter>
</CopyFileToFolders>
</ItemGroup>
</Project>
</Project>
14 changes: 12 additions & 2 deletions test_python/test_voxels_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,18 @@ def test_voxels_conversion():

# Test mesh build functions
radius = 8 * mul
mesh1 = mrmesh.gridToMesh(vdb_volume, isoValue = max_value - radius * radius)
mesh2 = mrmesh.gridToMesh(grid, voxelSize = volume0.voxelSize, isoValue = max_value - radius * radius)
if is_new_binding:
settings1 = mrmesh.GridToMeshSettings()
settings1.isoValue = max_value - radius * radius
settings1.voxelSize = vdb_volume.voxelSize
mesh1 = mrmesh.gridToMesh(vdb_volume.data, settings1)
settings2 = mrmesh.GridToMeshSettings()
settings2.isoValue = max_value - radius * radius
settings2.voxelSize = volume0.voxelSize
mesh2 = mrmesh.gridToMesh(grid, settings2)
else:
mesh1 = mrmesh.gridToMesh(vdb_volume, isoValue = max_value - radius * radius)
mesh2 = mrmesh.gridToMesh(grid, voxelSize = volume0.voxelSize, isoValue = max_value - radius * radius)
# Basic checks
for mesh in (mesh1, mesh2):
assert len(mrmesh.getAllComponents(mesh1)) == 1
Expand Down

0 comments on commit ed0b58b

Please sign in to comment.