Skip to content

Commit 5f058c8

Browse files
committed
arnaud comments and python tests
1 parent a9fa7ab commit 5f058c8

16 files changed

Lines changed: 376 additions & 19 deletions

bindings/python/src/validity/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_geode_python_binding(
2222
NAME "py_validity"
2323
SOURCES
2424
"edgedcurve_validity.hpp"
25+
"object_validity.hpp"
2526
"pointset_validity.hpp"
2627
"solid_validity.hpp"
2728
"surface_validity.hpp"
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2019 - 2026 Geode-solutions
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
* SOFTWARE.
21+
*
22+
*/
23+
24+
#pragma once
25+
26+
#include <string>
27+
28+
#include <geode/inspector/validity/object_validity.hpp>
29+
30+
namespace geode
31+
{
32+
inline void define_object_validity( pybind11::module& module )
33+
{
34+
pybind11::class_< ObjectValidity >( module, "ObjectValidity" )
35+
.def( "nb_issues", &ObjectValidity::nb_issues )
36+
.def( "string", &ObjectValidity::string )
37+
.def_readwrite( "invalidities", &ObjectValidity::invalidities );
38+
}
39+
} // namespace geode

bindings/python/src/validity/validity.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "pybind11/stl.h"
2727

2828
#include "edgedcurve_validity.hpp"
29+
#include "object_validity.hpp"
2930
#include "pointset_validity.hpp"
3031
#include "solid_validity.hpp"
3132
#include "surface_validity.hpp"
@@ -37,6 +38,7 @@ PYBIND11_MODULE( opengeode_inspector_py_validity, module )
3738
module, "OpenGeodeInspectorValidityLibrary" )
3839
.def( "initialize",
3940
&geode::OpenGeodeInspectorValidityLibrary::initialize );
41+
geode::define_object_validity( module );
4042
geode::define_edged_curve_validity( module );
4143
geode::define_point_set_validity( module );
4244
geode::define_solid_mesh_validity( module );

bindings/python/tests/validity/CMakeLists.txt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,25 @@
1919
# SOFTWARE.
2020

2121
add_geode_python_test(
22-
SOURCE "test-py-model-validity.py"
22+
SOURCE "test-py-edgedcurve-validity.py"
23+
DEPENDENCIES
24+
${PROJECT_NAME}::py_validity
25+
)
26+
27+
add_geode_python_test(
28+
SOURCE "test-py-pointset-validity.py"
29+
DEPENDENCIES
30+
${PROJECT_NAME}::py_validity
31+
)
32+
33+
add_geode_python_test(
34+
SOURCE "test-py-solid-validity.py"
35+
DEPENDENCIES
36+
${PROJECT_NAME}::py_validity
37+
)
38+
39+
add_geode_python_test(
40+
SOURCE "test-py-surface-validity.py"
2341
DEPENDENCIES
2442
${PROJECT_NAME}::py_validity
2543
)

bindings/python/tests/validity/test-py-model-validity.py renamed to bindings/python/tests/validity/test-py-edgedcurve-validity.py

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,38 @@
2727
for path in [x.strip() for x in os.environ["PATH"].split("") if x]:
2828
os.add_dll_directory(path)
2929

30-
import opengeode
30+
import opengeode as geode
3131
import opengeode_inspector_py_validity as validity
3232

33+
def check_validity():
34+
curve = geode.EdgedCurve3D.create()
35+
builder = geode.EdgedCurveBuilder3D.create( curve )
36+
builder.create_vertices( 7 )
37+
builder.set_point( 0, geode.Point3D([ 0., 2., 1. ]) )
38+
builder.set_point( 1, geode.Point3D([ 0., 2., 1. ]) )
39+
builder.set_point( 2, geode.Point3D([ 0., 0., 0. ]) )
40+
builder.set_point( 3, geode.Point3D([ 2., 0., 0. ]) )
41+
builder.set_point( 4, geode.Point3D([ 1., 4., 3. ]) )
42+
builder.set_point( 5, geode.Point3D([ 2., geode.GLOBAL_EPSILON / 2, geode.GLOBAL_EPSILON / 2 ]) )
43+
builder.set_point( 6, geode.Point3D([ geode.GLOBAL_EPSILON / 1.1, 2., 1. ]) )
3344

34-
def test_validity():
35-
return True
45+
first_object_validity = validity.is_edged_curve_valid3D( curve )
46+
print( "ObjectValidity: \n" + first_object_validity.string() )
47+
if not first_object_validity.nb_issues() == 1:
48+
raise ValueError( "EdgedCurve should have 1 invalidity due to colocation, not "+ str(first_object_validity.nb_issues()) )
3649

50+
builder.create_edge_with_vertices( 0, 1 )
51+
builder.create_edge_with_vertices( 1, 2 )
52+
builder.create_edge_with_vertices( 2, 3 )
53+
builder.create_edge_with_vertices( 3, 4 )
54+
builder.create_edge_with_vertices( 4, 5 )
55+
builder.create_edge_with_vertices( 5, 6 )
56+
57+
object_validity = validity.is_edged_curve_valid3D( curve )
58+
print( "ObjectValidity: \n" + object_validity.string() );
59+
if not object_validity.nb_issues() == 2:
60+
raise ValueError( "EdgedCurve should have 2 invalidity reasons, not "+ str(object_validity.nb_issues()) )
3761

38-
def check_validity():
39-
if not test_validity():
40-
raise ValueError(
41-
"[Test] Should be true"
42-
)
4362

4463
if __name__ == "__main__":
4564
validity.OpenGeodeInspectorValidityLibrary.initialize()
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright (c) 2019 - 2026 Geode-solutions
3+
#
4+
# Permission is hereby granted, free of charge, to any person obtaining a copy
5+
# of this software and associated documentation files (the "Software"), to deal
6+
# in the Software without restriction, including without limitation the rights
7+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
# copies of the Software, and to permit persons to whom the Software is
9+
# furnished to do so, subject to the following conditions:
10+
#
11+
# The above copyright notice and this permission notice shall be included in
12+
# all copies or substantial portions of the Software.
13+
#
14+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
# SOFTWARE.
21+
22+
import os
23+
import sys
24+
import platform
25+
26+
if sys.version_info >= (3, 8, 0) and platform.system() == "Windows":
27+
for path in [x.strip() for x in os.environ["PATH"].split("") if x]:
28+
os.add_dll_directory(path)
29+
30+
import opengeode as geode
31+
import opengeode_inspector_py_validity as validity
32+
33+
def check_non_validity2D():
34+
pointset = geode.PointSet2D.create()
35+
builder = geode.PointSetBuilder2D.create( pointset )
36+
builder.create_vertices( 4 )
37+
builder.set_point( 0, geode.Point2D( [0., 2.]) )
38+
builder.set_point( 1, geode.Point2D( [2., 0.]) )
39+
builder.set_point( 2, geode.Point2D( [1., 4.]) )
40+
builder.set_point( 3, geode.Point2D( [3., 3.]) )
41+
42+
object_validity = validity.is_pointset_valid2D( pointset )
43+
if not object_validity.nb_issues() == 0:
44+
raise ValueError("PointSet has "+ str(object_validity.nb_issues())+ " object_validity when it should have none." )
45+
46+
def check_validity2D():
47+
pointset = geode.PointSet2D.create()
48+
builder = geode.PointSetBuilder2D.create( pointset )
49+
builder.create_vertices( 7 )
50+
builder.set_point( 0, geode.Point2D([ 0., 2.]))
51+
builder.set_point( 1, geode.Point2D([ 0., 2.]))
52+
builder.set_point( 2, geode.Point2D([ 0., 0.]))
53+
builder.set_point( 3, geode.Point2D([ 2., 0.]))
54+
builder.set_point( 4, geode.Point2D([ 1., 4.]))
55+
builder.set_point( 5, geode.Point2D([ 2., geode.GLOBAL_EPSILON / 2 ]) )
56+
builder.set_point( 6, geode.Point2D([ geode.GLOBAL_EPSILON / 1.1, 2. ]) )
57+
58+
object_validity = validity.is_pointset_valid2D( pointset )
59+
print( "2D object_validity: \n"+ object_validity.string() )
60+
if not object_validity.nb_issues() == 1:
61+
raise ValueError("PointSet should have 1 invalidity reason, not "+str(object_validity.nb_issues()) )
62+
63+
def check_non_validity3D():
64+
pointset = geode.PointSet3D.create()
65+
builder = geode.PointSetBuilder3D.create( pointset )
66+
builder.create_vertices( 4 )
67+
builder.set_point( 0, geode.Point3D([ 0., 2., 0. ]) )
68+
builder.set_point( 1, geode.Point3D([2., 0., 0.5 ]) )
69+
builder.set_point( 2, geode.Point3D([ 1., 4., 1. ]) )
70+
builder.set_point( 3, geode.Point3D([ 3., 3., 2. ]) )
71+
72+
object_validity = validity.is_pointset_valid3D( pointset )
73+
if not object_validity.nb_issues() == 0:
74+
raise ValueError( "PointSet has "+ str(object_validity.nb_issues())+" object_validity when it should have none." )
75+
76+
def check_validity3D():
77+
pointset = geode.PointSet3D.create()
78+
builder = geode.PointSetBuilder3D.create( pointset )
79+
builder.create_vertices( 7 )
80+
builder.set_point( 0, geode.Point3D([ 0., 2., 1. ]) )
81+
builder.set_point( 1, geode.Point3D([ 0., 2., 1. ]) )
82+
builder.set_point( 2, geode.Point3D([ 0., 0., 0. ]) )
83+
builder.set_point( 3, geode.Point3D([ 2., 0., 0. ]) )
84+
builder.set_point( 4, geode.Point3D([ 1., 4., 3. ]) )
85+
builder.set_point( 5, geode.Point3D([ 2., geode.GLOBAL_EPSILON / 2, geode.GLOBAL_EPSILON / 2 ]) )
86+
builder.set_point( 6, geode.Point3D([ geode.GLOBAL_EPSILON / 1.1, 2., 1. ]) )
87+
88+
object_validity = validity.is_pointset_valid3D( pointset )
89+
print( "3D object_validity: \n"+ object_validity.string() )
90+
if not object_validity.nb_issues() == 1:
91+
raise ValueError( "PointSet should have 1 invalidity reason, not "+ str(object_validity.nb_issues()) )
92+
93+
94+
if __name__ == "__main__":
95+
validity.OpenGeodeInspectorValidityLibrary.initialize()
96+
check_non_validity2D()
97+
check_validity2D()
98+
check_non_validity3D()
99+
check_validity3D()
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright (c) 2019 - 2026 Geode-solutions
3+
#
4+
# Permission is hereby granted, free of charge, to any person obtaining a copy
5+
# of this software and associated documentation files (the "Software"), to deal
6+
# in the Software without restriction, including without limitation the rights
7+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
# copies of the Software, and to permit persons to whom the Software is
9+
# furnished to do so, subject to the following conditions:
10+
#
11+
# The above copyright notice and this permission notice shall be included in
12+
# all copies or substantial portions of the Software.
13+
#
14+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
# SOFTWARE.
21+
22+
import os
23+
import sys
24+
import platform
25+
26+
if sys.version_info >= (3, 8, 0) and platform.system() == "Windows":
27+
for path in [x.strip() for x in os.environ["PATH"].split("") if x]:
28+
os.add_dll_directory(path)
29+
30+
import opengeode as geode
31+
import opengeode_inspector_py_validity as validity
32+
33+
def check_validity():
34+
solid = geode.TetrahedralSolid3D.create()
35+
builder = geode.TetrahedralSolidBuilder3D.create( solid )
36+
builder.create_vertices( 7 )
37+
builder.set_point( 0, geode.Point3D([ 0., 0., 2. ]) )
38+
builder.set_point( 1, geode.Point3D([ 3., .5, 0. ]) )
39+
builder.set_point( 2, geode.Point3D([ .5, 3., .5 ]) )
40+
builder.set_point( 3, geode.Point3D([ 2., 1.5, 3. ]) )
41+
builder.set_point( 4, geode.Point3D([ 3.5, 2.5, -.5 ]) )
42+
builder.set_point( 5, geode.Point3D([ 3., .5, 0. ]) )
43+
builder.set_point( 6, geode.Point3D([ .5, 3., .5 ]) )
44+
45+
object_validity = validity.is_solid_valid3D( solid )
46+
print( "ObjectValidity: \n" + object_validity.string() )
47+
if not object_validity.nb_issues() == 1:
48+
raise ValueError( "SolidMesh should have 1 invalidity due to colocation, not " +str(object_validity.nb_issues()) )
49+
50+
builder.create_tetrahedron( [ 0, 1, 2, 3 ] )
51+
builder.create_tetrahedron( [ 5, 4, 6, 3 ] )
52+
53+
object_validity = validity.is_solid_valid3D( solid )
54+
print( "ObjectValidity: \n" + object_validity.string() )
55+
if not object_validity.nb_issues() == 2:
56+
raise ValueError( "SolidMesh should have 2 object_validity due to colocation and non manifold vertices, not " + str(object_validity.nb_issues()) )
57+
58+
builder.create_tetrahedron( [ 2, 1, 6, 3 ] )
59+
builder.create_tetrahedron( [ 1, 5, 3, 6 ] )
60+
61+
object_validity = validity.is_solid_valid3D( solid )
62+
print( "ObjectValidity: \n" + object_validity.string() )
63+
if not object_validity.nb_issues() == 5:
64+
raise ValueError( "SolidMesh should have 5 object_validity due to colocation, degenerated edges and polyhedra, and non manifold vertices and edges, not "+str(object_validity.nb_issues()) )
65+
66+
builder.create_tetrahedron( [ 1, 4, 3, 6 ] )
67+
68+
object_validity = validity.is_solid_valid3D( solid )
69+
print( "ObjectValidity: \n" + object_validity.string() )
70+
if not object_validity.nb_issues() == 7:
71+
raise ValueError( "SolidMesh should have 7 object_validity due to colocation, degenerated edges and polyhedra, non manifold vertices, edges, and facets, and negative polyhedra, not "+str(object_validity.nb_issues()))
72+
73+
builder.set_polyhedron_adjacent( geode.PolyhedronFacet( 0, 0 ), 1 )
74+
75+
object_validity = validity.is_solid_valid3D( solid )
76+
print( "ObjectValidity: \n" + object_validity.string() )
77+
if not object_validity.nb_issues() == 8:
78+
raise ValueError( "SolidMesh should have 8 object_validity due to adjacencies, colocation, degenerated edges and polyhedra, non manifold vertices, edges, and facets, and negative polyhedra, not "+str(object_validity.nb_issues()) )
79+
80+
81+
if __name__ == "__main__":
82+
validity.OpenGeodeInspectorValidityLibrary.initialize()
83+
check_validity()

0 commit comments

Comments
 (0)