Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
CityDoctor
CityDoctor2
Commits
b073d9bc
Commit
b073d9bc
authored
Apr 28, 2026
by
Numanoglu
Browse files
Remove old BVH test locations
parent
e6f4979d
Changes
4
Show whitespace changes
Inline
Side-by-side
CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/geometry/RingSelfIntCheckVariantComparisonTest.java
deleted
100644 → 0
View file @
e6f4979d
package
de.hft.stuttgart.citydoctor2.checks.geometry
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
org.junit.jupiter.api.Test
;
import
de.hft.stuttgart.citydoctor2.check.CheckResult
;
import
de.hft.stuttgart.citydoctor2.check.ResultStatus
;
import
de.hft.stuttgart.citydoctor2.check.ValidationConfiguration
;
import
de.hft.stuttgart.citydoctor2.datastructure.Building
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing
;
import
de.hft.stuttgart.citydoctor2.datastructure.Lod
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParseException
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParser
;
import
de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException
;
/**
* Compares RingSelfIntCheck variants on the same input model.
*
* Compared variants:
* - OLD
* - TREE_1_EDGE_BVH
* - TREE_2_EDGE_AND_VERTEX_BVH
*/
public
class
RingSelfIntCheckVariantComparisonTest
{
private
static
final
String
TEST_GML
=
"src/test/resources/SimpleSolid_SrefBS-GE-gml-LR-0004-T0004.gml"
;
private
static
final
double
EPSILON
=
0.001
;
@Test
public
void
oldVsTree1VsTree2_sameErrorCounts
()
throws
CityGmlParseException
,
InvalidGmlFileException
{
Geometry
geometryOld
=
parseGeometry
(
TEST_GML
);
Geometry
geometryTree1
=
parseGeometry
(
TEST_GML
);
Geometry
geometryTree2
=
parseGeometry
(
TEST_GML
);
long
start
=
System
.
nanoTime
();
int
oldCount
=
runCheckAndCountErrors
(
geometryOld
,
RingSelfIntCheck
.
Variant
.
OLD
);
long
oldTime
=
System
.
nanoTime
()
-
start
;
System
.
out
.
println
(
"RingSelfIntCheck OLD count="
+
oldCount
+
" time(ns)="
+
oldTime
);
start
=
System
.
nanoTime
();
int
tree1Count
=
runCheckAndCountErrors
(
geometryTree1
,
RingSelfIntCheck
.
Variant
.
TREE_1_EDGE_BVH
);
long
tree1Time
=
System
.
nanoTime
()
-
start
;
System
.
out
.
println
(
"RingSelfIntCheck TREE_1_EDGE_BVH count="
+
tree1Count
+
" time(ns)="
+
tree1Time
);
start
=
System
.
nanoTime
();
int
tree2Count
=
runCheckAndCountErrors
(
geometryTree2
,
RingSelfIntCheck
.
Variant
.
TREE_2_EDGE_AND_VERTEX_BVH
);
long
tree2Time
=
System
.
nanoTime
()
-
start
;
System
.
out
.
println
(
"RingSelfIntCheck TREE_2_EDGE_AND_VERTEX_BVH count="
+
tree2Count
+
" time(ns)="
+
tree2Time
);
assertEquals
(
"OLD vs TREE_1_EDGE_BVH differs"
,
oldCount
,
tree1Count
);
assertEquals
(
"OLD vs TREE_2_EDGE_AND_VERTEX_BVH differs"
,
oldCount
,
tree2Count
);
}
@Test
public
void
perRingResultsMatch_oldVsTree1VsTree2
()
throws
CityGmlParseException
,
InvalidGmlFileException
{
Geometry
geometryOld
=
parseGeometry
(
TEST_GML
);
Geometry
geometryTree1
=
parseGeometry
(
TEST_GML
);
Geometry
geometryTree2
=
parseGeometry
(
TEST_GML
);
List
<
LinearRing
>
oldRings
=
collectRings
(
geometryOld
);
List
<
LinearRing
>
tree1Rings
=
collectRings
(
geometryTree1
);
List
<
LinearRing
>
tree2Rings
=
collectRings
(
geometryTree2
);
assertEquals
(
"Different number of rings in old/tree1 geometry"
,
oldRings
.
size
(),
tree1Rings
.
size
());
assertEquals
(
"Different number of rings in old/tree2 geometry"
,
oldRings
.
size
(),
tree2Rings
.
size
());
for
(
int
i
=
0
;
i
<
oldRings
.
size
();
i
++)
{
LinearRing
oldRing
=
oldRings
.
get
(
i
);
LinearRing
tree1Ring
=
tree1Rings
.
get
(
i
);
LinearRing
tree2Ring
=
tree2Rings
.
get
(
i
);
RingSelfIntCheck
oldCheck
=
createCheck
(
RingSelfIntCheck
.
Variant
.
OLD
);
RingSelfIntCheck
tree1Check
=
createCheck
(
RingSelfIntCheck
.
Variant
.
TREE_1_EDGE_BVH
);
RingSelfIntCheck
tree2Check
=
createCheck
(
RingSelfIntCheck
.
Variant
.
TREE_2_EDGE_AND_VERTEX_BVH
);
oldCheck
.
check
(
oldRing
);
tree1Check
.
check
(
tree1Ring
);
tree2Check
.
check
(
tree2Ring
);
CheckResult
oldResult
=
oldRing
.
getCheckResult
(
oldCheck
);
CheckResult
tree1Result
=
tree1Ring
.
getCheckResult
(
tree1Check
);
CheckResult
tree2Result
=
tree2Ring
.
getCheckResult
(
tree2Check
);
assertNotNull
(
"OLD result is null for ring index "
+
i
,
oldResult
);
assertNotNull
(
"TREE_1 result is null for ring index "
+
i
,
tree1Result
);
assertNotNull
(
"TREE_2 result is null for ring index "
+
i
,
tree2Result
);
assertEquals
(
"OLD vs TREE_1 status differs for ring index "
+
i
,
oldResult
.
getResultStatus
(),
tree1Result
.
getResultStatus
());
assertEquals
(
"OLD vs TREE_2 status differs for ring index "
+
i
,
oldResult
.
getResultStatus
(),
tree2Result
.
getResultStatus
());
}
}
private
int
runCheckAndCountErrors
(
Geometry
geometry
,
RingSelfIntCheck
.
Variant
variant
)
{
int
count
=
0
;
for
(
LinearRing
ring
:
collectRings
(
geometry
))
{
RingSelfIntCheck
check
=
createCheck
(
variant
);
check
.
check
(
ring
);
CheckResult
result
=
ring
.
getCheckResult
(
check
);
assertNotNull
(
"CheckResult must not be null"
,
result
);
if
(
result
.
getResultStatus
()
==
ResultStatus
.
ERROR
)
{
count
++;
}
}
return
count
;
}
private
RingSelfIntCheck
createCheck
(
RingSelfIntCheck
.
Variant
variant
)
{
RingSelfIntCheck
check
=
new
RingSelfIntCheck
(
variant
);
check
.
init
(
Collections
.
singletonMap
(
"minVertexDistance"
,
String
.
valueOf
(
EPSILON
)),
null
);
return
check
;
}
private
List
<
LinearRing
>
collectRings
(
Geometry
geometry
)
{
assertNotNull
(
"geometry must not be null"
,
geometry
);
List
<
LinearRing
>
rings
=
new
ArrayList
<>();
for
(
Polygon
polygon
:
geometry
.
getPolygons
())
{
if
(
polygon
.
getExteriorRing
()
!=
null
)
{
rings
.
add
(
polygon
.
getExteriorRing
());
}
rings
.
addAll
(
polygon
.
getInnerRings
());
}
return
rings
;
}
private
Geometry
parseGeometry
(
String
gmlPath
)
throws
CityGmlParseException
,
InvalidGmlFileException
{
ValidationConfiguration
config
=
ValidationConfiguration
.
loadStandardValidationConfig
();
config
.
setSchematronFilePathInGlobalParameters
(
null
);
CityDoctorModel
model
=
CityGmlParser
.
parseCityGmlFile
(
gmlPath
,
config
.
getParserConfiguration
());
Building
building
=
model
.
getBuildings
().
findFirst
().
orElseThrow
();
Geometry
geometry
=
building
.
getGeometry
(
GeometryType
.
SOLID
,
Lod
.
LOD2
);
assertNotNull
(
"Expected SOLID LOD2 geometry in test model: "
+
gmlPath
,
geometry
);
return
geometry
;
}
}
\ No newline at end of file
CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/util/SolidSelfIntersectionBVHUtilTest.java
deleted
100644 → 0
View file @
e6f4979d
package
de.hft.stuttgart.citydoctor2.checks.util
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
java.io.File
;
import
java.util.List
;
import
org.citygml4j.core.model.CityGMLVersion
;
import
org.citygml4j.core.model.core.CityModel
;
import
org.junit.jupiter.api.Test
;
import
de.hft.stuttgart.citydoctor2.check.ValidationConfiguration
;
import
de.hft.stuttgart.citydoctor2.database.UnconnectedCache
;
import
de.hft.stuttgart.citydoctor2.datastructure.Building
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Lod
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.bht.AABB
;
import
de.hft.stuttgart.citydoctor2.datastructure.bht.BoundingVolumeHierarchyTree
;
import
de.hft.stuttgart.citydoctor2.exceptions.CityDoctorWriteException
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParseException
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParser
;
import
de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException
;
import
de.hft.stuttgart.citydoctor2.parser.ParserConfiguration
;
import
de.hft.stuttgart.citydoctor2.utils.PolygonIntersection
;
public
class
SolidSelfIntersectionBVHUtilTest
{
@Test
public
void
testWriteModel
()
throws
CityDoctorWriteException
{
Building
b
=
new
Building
();
b
.
addGeometry
(
GeometryTestUtils
.
createGoodGeometry
());
b
.
setGmlObject
(
new
org
.
citygml4j
.
core
.
model
.
building
.
Building
());
UnconnectedCache
unconnectedCache
=
new
UnconnectedCache
();
CityDoctorModel
model
=
new
CityDoctorModel
(
new
ParserConfiguration
(
8
,
false
),
new
File
(
"test.gml"
),
unconnectedCache
);
model
.
setParsedCityGMLVersion
(
CityGMLVersion
.
v2_0
);
model
.
setCityModel
(
new
CityModel
());
model
.
addBuilding
(
b
);
model
.
saveAs
(
"test.gml"
,
false
);
}
@Test
public
void
testBVHCalculateOnKnownGoodModel
()
throws
CityGmlParseException
,
InvalidGmlFileException
{
ValidationConfiguration
config
=
ValidationConfiguration
.
loadStandardValidationConfig
();
config
.
setSchematronFilePathInGlobalParameters
(
null
);
CityDoctorModel
m
=
CityGmlParser
.
parseCityGmlFile
(
"src/test/resources/SolidSelfIntTest1.gml"
,
config
.
getParserConfiguration
()
);
Building
building
=
m
.
getBuildings
().
findFirst
().
orElseThrow
();
Geometry
g
=
building
.
getGeometry
(
GeometryType
.
SOLID
,
Lod
.
LOD2
);
assertNotNull
(
"Expected SOLID LOD2 geometry in test model"
,
g
);
List
<
Polygon
>
polys
=
g
.
getPolygons
();
assertNotNull
(
polys
);
assertTrue
(
"Expected at least 2 polygons"
,
polys
.
size
()
>
1
);
BoundingVolumeHierarchyTree
<
Polygon
>
tree
=
BoundingVolumeHierarchyTree
.
newBinary
(
polys
,
p
->
AABB
.
of
(
p
.
getOriginal
()));
double
delta
=
0.001
;
// calls new method with trees
List
<
PolygonIntersection
>
intersections
=
SelfIntersectionUtil
.
calculateSolidSelfIntersection
(
g
,
delta
,
tree
);
// This file is a good example (no self intersection)
assertTrue
(
"No self-intersections expected for SolidSelfIntTest1.gml"
,
intersections
.
isEmpty
());
}
}
\ No newline at end of file
CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/util/SolidSelfIntersectionBuildingTest.java
deleted
100644 → 0
View file @
e6f4979d
package
de.hft.stuttgart.citydoctor2.checks.util
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
java.util.List
;
import
org.junit.jupiter.api.Test
;
import
de.hft.stuttgart.citydoctor2.datastructure.Building
;
import
de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry.Orientation
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing
;
import
de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Lod
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.datastructure.Vertex
;
import
de.hft.stuttgart.citydoctor2.datastructure.bht.AABB
;
import
de.hft.stuttgart.citydoctor2.datastructure.bht.BoundingVolumeHierarchyTree
;
import
de.hft.stuttgart.citydoctor2.utils.PolygonIntersection
;
public
class
SolidSelfIntersectionBuildingTest
{
private
static
final
double
DELTA
=
0.001
;
private
static
final
int
MIN_EXPECTED_POLYGONS
=
60
;
@Test
public
void
testBvhBuildAndQueryOnLod2AndLod3
()
{
Building
building
=
createDenseBuildingWithoutIntersections
();
assertBvhBuildAndQuery
(
building
.
getGeometry
(
GeometryType
.
SOLID
,
Lod
.
LOD2
),
"LOD2"
);
assertBvhBuildAndQuery
(
building
.
getGeometry
(
GeometryType
.
SOLID
,
Lod
.
LOD3
),
"LOD3"
);
}
@Test
public
void
testOldVsNewSameResultCountOnIntersectingLod2AndLod3
()
{
Building
building
=
createDenseBuildingWithIntersections
();
assertOldVsNewComparison
(
building
.
getGeometry
(
GeometryType
.
SOLID
,
Lod
.
LOD2
),
"LOD2"
);
assertOldVsNewComparison
(
building
.
getGeometry
(
GeometryType
.
SOLID
,
Lod
.
LOD3
),
"LOD3"
);
}
private
void
assertBvhBuildAndQuery
(
Geometry
geometry
,
String
lodLabel
)
{
List
<
Polygon
>
polygons
=
requireValidGeometry
(
geometry
,
lodLabel
);
BoundingVolumeHierarchyTree
<
Polygon
>
tree
=
new
BoundingVolumeHierarchyTree
<>(
polygons
,
p
->
AABB
.
of
(
p
.
getOriginal
()),
BoundingVolumeHierarchyTree
.
BuildConfig
.
binaryDefault
());
Polygon
probe
=
polygons
.
get
(
0
);
AABB
probeAabb
=
AABB
.
of
(
probe
.
getOriginal
());
assertNotNull
(
"Probe AABB must not be null for "
+
lodLabel
,
probeAabb
);
List
<
Polygon
>
candidates
=
tree
.
getAllIntersectingElements
(
probeAabb
);
int
nonEmptyQueries
=
0
;
int
totalCandidates
=
0
;
int
maxCandidates
=
0
;
for
(
Polygon
polygon
:
polygons
)
{
AABB
query
=
AABB
.
of
(
polygon
.
getOriginal
());
assertNotNull
(
"Query AABB must not be null for "
+
lodLabel
,
query
);
List
<
Polygon
>
perPolygonCandidates
=
tree
.
getAllIntersectingElements
(
query
);
if
(!
perPolygonCandidates
.
isEmpty
())
{
nonEmptyQueries
++;
}
int
currentSize
=
perPolygonCandidates
.
size
();
totalCandidates
+=
currentSize
;
if
(
currentSize
>
maxCandidates
)
{
maxCandidates
=
currentSize
;
}
}
printBvhStats
(
lodLabel
,
polygons
.
size
(),
candidates
.
size
(),
nonEmptyQueries
,
totalCandidates
,
maxCandidates
);
assertTrue
(
"Expected at least one non-empty BVH query on "
+
lodLabel
,
nonEmptyQueries
>
0
);
}
private
void
assertOldVsNewComparison
(
Geometry
geometry
,
String
lodLabel
)
{
List
<
Polygon
>
polygons
=
requireValidGeometry
(
geometry
,
lodLabel
);
List
<
PolygonIntersection
>
oldRes
=
SelfIntersectionUtil
.
calculateSolidSelfIntersection0
(
geometry
,
DELTA
);
assertNotNull
(
"Old result list must not be null for "
+
lodLabel
,
oldRes
);
BoundingVolumeHierarchyTree
<
Polygon
>
externalTree
=
new
BoundingVolumeHierarchyTree
<>(
polygons
,
p
->
AABB
.
of
(
p
.
getOriginal
()),
BoundingVolumeHierarchyTree
.
BuildConfig
.
binaryDefault
());
List
<
PolygonIntersection
>
oldTreeRes
=
SelfIntersectionUtil
.
calculateSolidSelfIntersection
(
geometry
,
DELTA
,
externalTree
);
assertNotNull
(
"Old+tree result list must not be null for "
+
lodLabel
,
oldTreeRes
);
List
<
PolygonIntersection
>
newRes
=
SelfIntersectionUtil
.
calculateSolidSelfIntersectionWithTree
(
geometry
,
DELTA
);
assertNotNull
(
"New result list must not be null for "
+
lodLabel
,
newRes
);
printComparisonStats
(
lodLabel
,
polygons
.
size
(),
oldRes
.
size
(),
oldTreeRes
.
size
(),
newRes
.
size
());
assertEquals
(
"Old vs external-tree differs for "
+
lodLabel
,
oldRes
.
size
(),
oldTreeRes
.
size
());
assertEquals
(
"Old vs new-tree differs for "
+
lodLabel
,
oldRes
.
size
(),
newRes
.
size
());
}
private
List
<
Polygon
>
requireValidGeometry
(
Geometry
geometry
,
String
lodLabel
)
{
assertNotNull
(
"Expected geometry for "
+
lodLabel
,
geometry
);
List
<
Polygon
>
polygons
=
geometry
.
getPolygons
();
assertNotNull
(
"Polygon list must not be null for "
+
lodLabel
,
polygons
);
assertFalse
(
"Polygon list must not be empty for "
+
lodLabel
,
polygons
.
isEmpty
());
assertTrue
(
"Expected many polygons for "
+
lodLabel
+
" (got "
+
polygons
.
size
()
+
")"
,
polygons
.
size
()
>=
MIN_EXPECTED_POLYGONS
);
return
polygons
;
}
private
void
printBvhStats
(
String
lodLabel
,
int
polygonCount
,
int
probeCandidateCount
,
int
nonEmptyQueries
,
int
totalCandidates
,
int
maxCandidates
)
{
System
.
out
.
printf
(
"[BVH][%s] polygons=%d, probeCandidates=%d, nonEmptyQueries=%d/%d, totalCandidates=%d, maxPerQuery=%d%n"
,
lodLabel
,
polygonCount
,
probeCandidateCount
,
nonEmptyQueries
,
polygonCount
,
totalCandidates
,
maxCandidates
);
}
private
void
printComparisonStats
(
String
lodLabel
,
int
polygonCount
,
int
oldCount
,
int
oldTreeCount
,
int
newCount
)
{
System
.
out
.
printf
(
"[SelfInt][%s] polygons=%d, old=%d, old+tree=%d, new=%d%n"
,
lodLabel
,
polygonCount
,
oldCount
,
oldTreeCount
,
newCount
);
}
private
Building
createDenseBuildingWithoutIntersections
()
{
Building
b
=
new
Building
();
b
.
addGeometry
(
createGridGeometry
(
Lod
.
LOD2
,
4
,
4
,
false
));
b
.
addGeometry
(
createGridGeometry
(
Lod
.
LOD3
,
6
,
6
,
false
));
return
b
;
}
private
Building
createDenseBuildingWithIntersections
()
{
Building
b
=
new
Building
();
b
.
addGeometry
(
createGridGeometry
(
Lod
.
LOD2
,
4
,
4
,
true
));
b
.
addGeometry
(
createGridGeometry
(
Lod
.
LOD3
,
6
,
6
,
true
));
return
b
;
}
private
Geometry
createGridGeometry
(
Lod
lod
,
int
xCount
,
int
yCount
,
boolean
addIntersections
)
{
Geometry
g
=
new
Geometry
(
GeometryType
.
SOLID
,
lod
,
Orientation
.
OUTWARD
);
double
spacing
=
6.0
;
double
width
=
4.0
;
double
depth
=
4.0
;
double
height
=
4.0
;
for
(
int
ix
=
0
;
ix
<
xCount
;
ix
++)
{
for
(
int
iy
=
0
;
iy
<
yCount
;
iy
++)
{
double
x
=
ix
*
spacing
;
double
y
=
iy
*
spacing
;
addBox
(
g
,
x
,
y
,
0.0
,
width
,
depth
,
height
);
}
}
// TODO Re-validate the Intersction-Idee
if
(
addIntersections
)
{
// Two additional boxes overlap each other and the grid neighborhood.
addBox
(
g
,
spacing
*
1.2
,
spacing
*
1.2
,
0.5
,
6.0
,
2.8
,
3.5
);
addBox
(
g
,
spacing
*
1.4
,
spacing
*
1.0
,
0.0
,
2.8
,
6.0
,
4.2
);
}
g
.
updateEdgesAndVertices
();
return
g
;
}
///----------------------------------- add geometric sub-entities ---------------------------///
private
void
addBox
(
Geometry
geometry
,
double
x
,
double
y
,
double
z
,
double
width
,
double
depth
,
double
height
)
{
Vertex
v000
=
new
Vertex
(
x
,
y
,
z
);
Vertex
v100
=
new
Vertex
(
x
+
width
,
y
,
z
);
Vertex
v110
=
new
Vertex
(
x
+
width
,
y
+
depth
,
z
);
Vertex
v010
=
new
Vertex
(
x
,
y
+
depth
,
z
);
Vertex
v001
=
new
Vertex
(
x
,
y
,
z
+
height
);
Vertex
v101
=
new
Vertex
(
x
+
width
,
y
,
z
+
height
);
Vertex
v111
=
new
Vertex
(
x
+
width
,
y
+
depth
,
z
+
height
);
Vertex
v011
=
new
Vertex
(
x
,
y
+
depth
,
z
+
height
);
addQuad
(
geometry
,
v000
,
v100
,
v110
,
v010
);
// bottom
addQuad
(
geometry
,
v001
,
v011
,
v111
,
v101
);
// top
addQuad
(
geometry
,
v000
,
v001
,
v101
,
v100
);
// front
addQuad
(
geometry
,
v100
,
v101
,
v111
,
v110
);
// right
addQuad
(
geometry
,
v110
,
v111
,
v011
,
v010
);
// back
addQuad
(
geometry
,
v010
,
v011
,
v001
,
v000
);
// left
}
private
void
addQuad
(
Geometry
geometry
,
Vertex
a
,
Vertex
b
,
Vertex
c
,
Vertex
d
)
{
ConcretePolygon
polygon
=
new
ConcretePolygon
();
LinearRing
ring
=
new
LinearRing
(
LinearRingType
.
EXTERIOR
);
polygon
.
setExteriorRing
(
ring
);
// ACHTUNG :Ensure polygon->geometry parent relation exists before adding vertices.
// LinearRing.addVertex() updates vertex adjacency via parent geometry.
geometry
.
addPolygon
(
polygon
);
ring
.
addVertex
(
a
);
ring
.
addVertex
(
b
);
ring
.
addVertex
(
c
);
ring
.
addVertex
(
d
);
ring
.
addVertex
(
a
);
}
}
CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/checks/util/SolidSelfIntersectionOldVsNewTest.java
deleted
100644 → 0
View file @
e6f4979d
package
de.hft.stuttgart.citydoctor2.checks.util
;
import
static
org
.
junit
.
Assert
.*;
import
java.util.List
;
import
org.junit.jupiter.api.Test
;
import
de.hft.stuttgart.citydoctor2.check.ValidationConfiguration
;
import
de.hft.stuttgart.citydoctor2.datastructure.Building
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.GeometryType
;
import
de.hft.stuttgart.citydoctor2.datastructure.Lod
;
import
de.hft.stuttgart.citydoctor2.datastructure.Polygon
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParseException
;
import
de.hft.stuttgart.citydoctor2.parser.CityGmlParser
;
import
de.hft.stuttgart.citydoctor2.parser.InvalidGmlFileException
;
import
de.hft.stuttgart.citydoctor2.utils.PolygonIntersection
;
import
de.hft.stuttgart.citydoctor2.datastructure.bht.AABB
;
import
de.hft.stuttgart.citydoctor2.datastructure.bht.BoundingVolumeHierarchyTree
;
/*
* First comparison SolidSelfIntersection version with Bounding Volume Tree vs old version
*
* @ Baris Numanoglu
* */
public
class
SolidSelfIntersectionOldVsNewTest
{
// @Test
// public void testOldVsNewSameResultCount() throws CityGmlParseException, InvalidGmlFileException {
// compareOnFile("src/test/resources/SolidSelfIntTest-known_false_positive_Big_Mesh2.gml", 0.001);
// }// dubious Test data: may be TP and not FP?
//
// @Test
// public void testOldVsNewSameResultCountFalsePositiveExample1() throws CityGmlParseException, InvalidGmlFileException {
// compareOnFile("src/test/resources/SolidSelfIntTest-known_false_positive1.gml", 0.001);
// }
@Test
public
void
testOldVsNewSameResultCountFalsePositiveExample2
()
throws
CityGmlParseException
,
InvalidGmlFileException
{
compareOnFile
(
"src/test/resources/SolidSelfIntTest-known_false_positive2.gml"
,
0.001
);
}
private
void
compareOnFile
(
String
gmlPath
,
double
delta
)
throws
CityGmlParseException
,
InvalidGmlFileException
{
ValidationConfiguration
config
=
ValidationConfiguration
.
loadStandardValidationConfig
();
config
.
setSchematronFilePathInGlobalParameters
(
null
);
CityDoctorModel
m
=
CityGmlParser
.
parseCityGmlFile
(
gmlPath
,
config
.
getParserConfiguration
());
Building
building
=
m
.
getBuildings
().
findFirst
().
orElseThrow
();
Geometry
g
=
building
.
getGeometry
(
GeometryType
.
SOLID
,
Lod
.
LOD2
);
assertNotNull
(
"Expected SOLID LOD2 geometry in test model: "
+
gmlPath
,
g
);
List
<
Polygon
>
polys
=
g
.
getPolygons
();
assertNotNull
(
polys
);
assertTrue
(
"Expected at least 2 polygons in: "
+
gmlPath
,
polys
.
size
()
>
1
);
/// Without Tree
long
start
=
System
.
nanoTime
();
List
<
PolygonIntersection
>
oldRes
=
SelfIntersectionUtil
.
calculateSolidSelfIntersection0
(
g
,
delta
);
long
dif
=
System
.
nanoTime
()
-
start
;
System
.
out
.
println
(
"Alt: "
+
dif
);
/// With IdentityHashMap
start
=
System
.
nanoTime
();
BoundingVolumeHierarchyTree
<
Polygon
>
polygonTree
=
new
BoundingVolumeHierarchyTree
<>(
g
.
getPolygons
(),
AABB:
:
of
,
BoundingVolumeHierarchyTree
.
BuildConfig
.
binaryDefault
()
);
List
<
PolygonIntersection
>
oldTreeRes
=
SelfIntersectionUtil
.
calculateSolidSelfIntersection
(
g
,
delta
,
polygonTree
);
dif
=
System
.
nanoTime
()
-
start
;
System
.
out
.
println
(
"Alt + external polygon tree: "
+
dif
);
/// With Polygon Indices
start
=
System
.
nanoTime
();
List
<
PolygonIntersection
>
newRes
=
SelfIntersectionUtil
.
calculateSolidSelfIntersectionWithTree
(
g
,
delta
);
dif
=
System
.
nanoTime
()
-
start
;
System
.
out
.
println
(
"Neu: "
+
dif
);
///
System
.
out
.
println
(
"oldRes.size() = "
+
oldRes
.
size
());
System
.
out
.
println
(
"oldTreeRes.size() = "
+
oldTreeRes
.
size
());
System
.
out
.
println
(
"newRes.size() = "
+
newRes
.
size
());
assertFalse
(
"oldRes is empty for: "
+
gmlPath
,
oldRes
.
isEmpty
());
assertFalse
(
"oldTreeRes is empty for: "
+
gmlPath
,
oldTreeRes
.
isEmpty
());
assertFalse
(
"newRes is empty for: "
+
gmlPath
,
newRes
.
isEmpty
());
assertEquals
(
"Old vs oldTree differs for: "
+
gmlPath
,
oldRes
.
size
(),
oldTreeRes
.
size
());
assertEquals
(
"Old vs new self-intersection result count differs for: "
+
gmlPath
,
oldRes
.
size
(),
newRes
.
size
());
}
}
\ No newline at end of file
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment