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
ffdae21a
Commit
ffdae21a
authored
Jul 31, 2024
by
Riegel
Browse files
Open Source release of CityDoctor GUI
parent
a5a82382
Pipeline
#10029
failed with stage
in 8 seconds
Changes
249
Pipelines
1
Show whitespace changes
Inline
Side-by-side
CityDoctorParent/CityDoctorHealerGenetic/checkForSolid.xml
0 → 100644
View file @
ffdae21a
<?xml version="1.0" encoding="UTF-8"?>
<schema
xmlns=
"http://purl.oclc.org/dsdl/schematron"
queryBinding=
"xslt2"
>
<ns
prefix=
"gml"
uri=
"http://www.opengis.net/gml"
/>
<ns
prefix=
"bldg"
uri=
"http://www.opengis.net/citygml/building/2.0"
/>
<pattern>
<rule
context=
"//*:Building"
>
<assert
test=
"count(descendant::*:lod1Solid) > 0 or count(descendant::*:lod2Solid) > 0 or count(descendant::*:lod3Solid) > 0 or count(descendant::*:lod4Solid) > 0"
><value-of
select=
"@gml:id | @id"
/>
||||SE_ATTRIBUTE_MISSING||any solid
</assert>
</rule>
<rule
context=
"//*:BuildingPart"
>
<assert
test=
"count(*:lod1Solid) = 1 or count(*:lod2Solid) = 1 or count(*:lod3Solid) = 1 or count(*:lod4Solid) = 1"
><value-of
select=
"ancestor::*:Building/@*:id"
/>
||
<value-of
select=
"@gml:id | @id"
/>
||SE_ATTRIBUTE_MISSING||any solid
</assert>
</rule>
</pattern>
</schema>
CityDoctorParent/CityDoctorHealerGenetic/pom.xml
0 → 100644
View file @
ffdae21a
<?xml version="1.0" encoding="utf-8"?>
<project
xmlns=
"https://maven.apache.org/POM/4.0.0"
xmlns:xsi=
"https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<parent>
<groupId>
de.hft.stuttgart
</groupId>
<artifactId>
CityDoctorParent
</artifactId>
<version>
3.14.1
</version>
</parent>
<artifactId>
CityDoctorHealerGenetic
</artifactId>
<dependencies>
<dependency>
<groupId>
de.hft.stuttgart
</groupId>
<artifactId>
CityDoctorHealerGUI
</artifactId>
<version>
${revision}
</version>
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<scope>
test
</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-surefire-plugin
</artifactId>
<configuration>
<skipTests>
true
</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/Crossover.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
public
interface
Crossover
<
T
>
{
public
T
cross
(
T
parent1
,
T
parent2
);
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/FitnessEvaluation.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
public
interface
FitnessEvaluation
<
T
>
{
public
double
evaluate
(
T
t
);
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/GeneticAlgorithm.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Objects
;
public
class
GeneticAlgorithm
<
T
>
implements
Runnable
{
private
int
populationSize
=
5
;
private
int
maxGenerations
=
2
;
private
Crossover
<
T
>
cross
;
private
Mutation
<
T
>
mutate
;
private
Heuristic
<
T
>
heuristic
;
private
FitnessEvaluation
<
T
>
evaluation
;
private
Individual
<
T
>
result
;
private
GeneticAlgorithm
(
Crossover
<
T
>
cross
,
Mutation
<
T
>
mutate
,
Heuristic
<
T
>
heuristic
,
FitnessEvaluation
<
T
>
evaluation
)
{
this
.
cross
=
Objects
.
requireNonNull
(
cross
);
this
.
mutate
=
Objects
.
requireNonNull
(
mutate
);
this
.
heuristic
=
Objects
.
requireNonNull
(
heuristic
);
this
.
evaluation
=
Objects
.
requireNonNull
(
evaluation
);
}
public
static
<
T
>
GeneticAlgorithm
<
T
>
of
(
Crossover
<
T
>
cross
,
Mutation
<
T
>
mutate
,
Heuristic
<
T
>
heuristic
,
FitnessEvaluation
<
T
>
evaluation
)
{
return
new
GeneticAlgorithm
<>(
cross
,
mutate
,
heuristic
,
evaluation
);
}
@Override
public
void
run
()
{
// initial population
List
<
Individual
<
T
>>
population
=
new
ArrayList
<>();
for
(
int
i
=
0
;
i
<
populationSize
;
i
++)
{
population
.
add
(
new
Individual
<>(
heuristic
.
generate
()));
}
for
(
Individual
<
T
>
genome
:
population
)
{
genome
.
evaluateFitness
(
evaluation
);
}
Collections
.
sort
(
population
);
System
.
out
.
println
(
"Best Fitness: "
+
population
.
get
(
0
).
getFitness
());
// do the generations thing
for
(
int
i
=
0
;
i
<
maxGenerations
;
i
++)
{
// generate children
for
(
int
j
=
0
;
j
<
populationSize
-
1
;
j
++)
{
// maybe random children generation
Individual
<
T
>
parent1
=
population
.
get
(
j
);
Individual
<
T
>
parent2
=
population
.
get
(
j
+
1
);
Individual
<
T
>
child1
=
new
Individual
<>(
cross
.
cross
(
parent1
.
getObject
(),
parent2
.
getObject
()));
Individual
<
T
>
child2
=
new
Individual
<>(
cross
.
cross
(
parent2
.
getObject
(),
parent1
.
getObject
()));
// mutate
child1
=
new
Individual
<>(
mutate
.
mutate
(
child1
.
getObject
()));
child2
=
new
Individual
<>(
mutate
.
mutate
(
child2
.
getObject
()));
child1
.
evaluateFitness
(
evaluation
);
child2
.
evaluateFitness
(
evaluation
);
population
.
add
(
child1
);
population
.
add
(
child2
);
}
// sort
Collections
.
sort
(
population
);
// eliminate
List
<
Individual
<
T
>>
newGeneration
=
new
ArrayList
<>(
populationSize
);
for
(
int
j
=
0
;
j
<
populationSize
;
j
++)
{
newGeneration
.
add
(
population
.
get
(
j
));
}
population
=
newGeneration
;
System
.
out
.
println
(
"Best Fitness: "
+
population
.
get
(
0
).
getFitness
());
}
result
=
population
.
get
(
0
);
System
.
out
.
println
(
"End. Best fitness: "
+
population
.
get
(
0
).
getFitness
()
+
" with plan: "
+
population
.
get
(
0
).
getObject
());
}
public
Individual
<
T
>
getResult
()
{
return
result
;
}
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/Heuristic.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
public
interface
Heuristic
<
T
>
{
public
T
generate
();
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/Individual.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
public
class
Individual
<
T
>
implements
Comparable
<
Individual
<
T
>>
{
private
T
object
;
private
double
fitness
;
public
Individual
(
T
object
)
{
this
.
object
=
object
;
}
public
void
evaluateFitness
(
FitnessEvaluation
<
T
>
evaluation
)
{
fitness
=
evaluation
.
evaluate
(
object
);
}
public
double
getFitness
()
{
return
fitness
;
}
@Override
public
int
compareTo
(
Individual
<
T
>
o
)
{
return
Double
.
compare
(
o
.
getFitness
(),
fitness
);
}
@Override
public
int
hashCode
()
{
final
int
prime
=
31
;
int
result
=
1
;
long
temp
;
temp
=
Double
.
doubleToLongBits
(
fitness
);
result
=
prime
*
result
+
(
int
)
(
temp
^
(
temp
>>>
32
));
result
=
prime
*
result
+
((
object
==
null
)
?
0
:
object
.
hashCode
());
return
result
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
Individual
<?>
other
=
(
Individual
<?>)
obj
;
if
(
Double
.
doubleToLongBits
(
fitness
)
!=
Double
.
doubleToLongBits
(
other
.
fitness
))
{
return
false
;
}
if
(
object
==
null
)
{
if
(
other
.
object
!=
null
)
{
return
false
;
}
}
else
if
(!
object
.
equals
(
other
.
object
))
{
return
false
;
}
return
true
;
}
public
T
getObject
()
{
return
object
;
}
@Override
public
String
toString
()
{
return
"Genotype [object="
+
object
+
", fitness="
+
fitness
+
"]"
;
}
public
void
setFitness
(
double
fitness
)
{
this
.
fitness
=
fitness
;
}
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/Mutation.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
public
interface
Mutation
<
T
>
{
public
T
mutate
(
T
genotype
);
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/NoMutation.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
public
class
NoMutation
implements
Mutation
<
HealingPlan
>
{
@Override
public
HealingPlan
mutate
(
HealingPlan
plan
)
{
return
plan
;
}
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/OrderCrossover.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Random
;
import
de.hft.stuttgart.citydoctor2.check.HealingMethod
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
public
class
OrderCrossover
implements
Crossover
<
HealingPlan
>
{
private
Random
r
;
public
OrderCrossover
()
{
r
=
new
Random
();
}
@Override
public
HealingPlan
cross
(
HealingPlan
parent1
,
HealingPlan
parent2
)
{
int
size1
=
parent1
.
getHealingMethods
().
size
();
int
firstPoint
=
Math
.
max
(
0
,
r
.
nextInt
(
size1
-
2
));
int
secondPoint
=
Math
.
min
(
size1
,
firstPoint
+
r
.
nextInt
(
size1
-
firstPoint
)
+
1
);
List
<
HealingMethod
>
childMethods
=
new
ArrayList
<>(
size1
);
// fill with empty values, so set(i, x) works
for
(
int
i
=
0
;
i
<
size1
;
i
++)
{
childMethods
.
add
(
null
);
}
for
(
int
i
=
firstPoint
;
i
<
secondPoint
;
i
++)
{
childMethods
.
set
(
i
,
parent1
.
getHealingMethods
().
get
(
i
));
}
int
writeIndex
=
0
;
for
(
HealingMethod
m
:
parent2
.
getHealingMethods
())
{
if
(!
contains
(
childMethods
,
m
))
{
while
(
childMethods
.
get
(
writeIndex
)
!=
null
)
{
writeIndex
++;
}
childMethods
.
set
(
writeIndex
,
m
);
}
}
for
(
HealingMethod
m
:
parent1
.
getHealingMethods
())
{
if
(!
contains
(
childMethods
,
m
))
{
while
(
childMethods
.
get
(
writeIndex
)
!=
null
)
{
writeIndex
++;
}
childMethods
.
set
(
writeIndex
,
m
);
}
}
HealingPlan
child
=
new
HealingPlan
();
child
.
getHealingMethods
().
addAll
(
childMethods
);
return
child
;
}
private
boolean
contains
(
List
<
HealingMethod
>
childMethods
,
HealingMethod
m
)
{
for
(
HealingMethod
method
:
childMethods
)
{
if
(
method
!=
null
&&
method
.
getClass
()
==
m
.
getClass
())
{
return
true
;
}
}
return
false
;
}
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/RandomFitness.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
public
class
RandomFitness
implements
FitnessEvaluation
<
HealingPlan
>
{
@Override
public
double
evaluate
(
HealingPlan
plan
)
{
return
Math
.
random
()
*
50000
;
}
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/RandomHeuristic.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.check.HealingMethod
;
import
de.hft.stuttgart.citydoctor2.healer.HealingMethodPrototype
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
public
class
RandomHeuristic
implements
Heuristic
<
HealingPlan
>
{
private
List
<
HealingMethodPrototype
>
availableHealingMethods
;
public
RandomHeuristic
(
List
<
HealingMethodPrototype
>
availableHealingMethods
)
{
this
.
availableHealingMethods
=
availableHealingMethods
;
}
@Override
public
HealingPlan
generate
()
{
List
<
HealingMethod
>
methods
=
new
ArrayList
<>();
for
(
HealingMethodPrototype
proto
:
availableHealingMethods
)
{
methods
.
add
(
proto
.
createMethod
());
}
Collections
.
shuffle
(
methods
);
HealingPlan
plan
=
new
HealingPlan
();
plan
.
getHealingMethods
().
addAll
(
methods
);
System
.
out
.
println
(
"Generated: "
+
plan
);
return
plan
;
}
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/RandomSwitchMutation.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
import
java.util.List
;
import
java.util.Random
;
import
de.hft.stuttgart.citydoctor2.check.HealingMethod
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
public
class
RandomSwitchMutation
implements
Mutation
<
HealingPlan
>
{
private
Random
r
=
new
Random
();
@Override
public
HealingPlan
mutate
(
HealingPlan
individual
)
{
double
percentage
=
r
.
nextDouble
();
if
(
percentage
>
0.7
)
{
// mutate 30% of the time
List
<
HealingMethod
>
healingMethods
=
individual
.
getHealingMethods
();
int
index
=
r
.
nextInt
(
healingMethods
.
size
()
-
1
);
HealingMethod
temp
=
healingMethods
.
get
(
index
+
1
);
healingMethods
.
set
(
index
+
1
,
healingMethods
.
get
(
index
));
healingMethods
.
set
(
index
,
temp
);
}
return
individual
;
}
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/gui/GeneticsGUI.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic.gui
;
import
java.io.IOException
;
import
java.io.UncheckedIOException
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Optional
;
import
java.util.Set
;
import
de.hft.stuttgart.citydoctor2.check.Check
;
import
de.hft.stuttgart.citydoctor2.check.CheckId
;
import
de.hft.stuttgart.citydoctor2.check.Checker
;
import
de.hft.stuttgart.citydoctor2.check.Requirement
;
import
de.hft.stuttgart.citydoctor2.check.RequirementType
;
import
de.hft.stuttgart.citydoctor2.datastructure.BoundingBox
;
import
de.hft.stuttgart.citydoctor2.datastructure.Building
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityDoctorModel
;
import
de.hft.stuttgart.citydoctor2.datastructure.CityObject
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.datastructure.GmlId
;
import
de.hft.stuttgart.citydoctor2.gui.MainWindow
;
import
de.hft.stuttgart.citydoctor2.gui.TriangulatedGeometry
;
import
de.hft.stuttgart.citydoctor2.gui.View
;
import
de.hft.stuttgart.citydoctor2.gui.ViewRegistration
;
import
de.hft.stuttgart.citydoctor2.healer.HealingMethods
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
import
de.hft.stuttgart.citydoctor2.healer.genetic.GeneticAlgorithm
;
import
de.hft.stuttgart.citydoctor2.healer.genetic.NoMutation
;
import
de.hft.stuttgart.citydoctor2.healer.genetic.OrderCrossover
;
import
de.hft.stuttgart.citydoctor2.healer.genetic.RandomHeuristic
;
import
de.hft.stuttgart.citydoctor2.healer.gui.HealerGUI
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
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.Copy
;
import
javafx.beans.property.DoubleProperty
;
import
javafx.beans.property.SimpleDoubleProperty
;
import
javafx.fxml.FXML
;
import
javafx.fxml.FXMLLoader
;
import
javafx.scene.AmbientLight
;
import
javafx.scene.Group
;
import
javafx.scene.Node
;
import
javafx.scene.Parent
;
import
javafx.scene.PerspectiveCamera
;
import
javafx.scene.SceneAntialiasing
;
import
javafx.scene.SnapshotParameters
;
import
javafx.scene.SubScene
;
import
javafx.scene.control.Button
;
import
javafx.scene.image.Image
;
import
javafx.scene.input.MouseButton
;
import
javafx.scene.layout.HBox
;
import
javafx.scene.layout.Pane
;
import
javafx.scene.paint.Color
;
import
javafx.scene.shape.CullFace
;
import
javafx.scene.shape.DrawMode
;
import
javafx.scene.transform.Rotate
;
public
class
GeneticsGUI
extends
View
{
private
static
final
double
CAMERA_INITIAL_X_ANGLE
=
20.0
;
private
static
final
double
CAMERA_INITIAL_Y_ANGLE
=
120.0
;
private
Parent
pane
;
private
Image
image
;
private
DoubleProperty
translateZ
;
private
DoubleProperty
cameraXRot
;
private
DoubleProperty
cameraYRot
;
private
boolean
enableGuiControls
=
true
;
private
Group
currentWorld
;
private
Group
nextWorld
;
private
Group
currentMeshGroup
;
private
Group
nextMeshGroup
;
@FXML
private
Pane
view1
;
@FXML
private
Pane
view2
;
@FXML
private
Button
test
;
private
Geometry
currentGeometry
;
private
CityObject
currentFeature
;
private
Checker
currentChecker
;
private
TriangulatedGeometry
currentTriangulatedGeometry
;
private
TriangulatedGeometry
nextTriangulatedGeometry
;
private
Geometry
nextGeometry
;
private
double
dragX
;
private
double
dragY
;
public
GeneticsGUI
()
{
image
=
new
Image
(
getClass
().
getResourceAsStream
(
"genetic.png"
));
}
public
void
initialize
()
{
view2
.
prefWidthProperty
().
bind
(
view1
.
widthProperty
());
view2
.
prefHeightProperty
().
bind
(
view1
.
heightProperty
());
translateZ
=
new
SimpleDoubleProperty
(
0
);
cameraXRot
=
new
SimpleDoubleProperty
(
CAMERA_INITIAL_X_ANGLE
);
cameraYRot
=
new
SimpleDoubleProperty
(
CAMERA_INITIAL_Y_ANGLE
);
test
.
setOnAction
(
ae
->
{
test
.
setDisable
(
true
);
enableGuiControls
=
false
;
GmlId
gmlId
=
currentGeometry
.
getGmlId
();
OrderCrossover
cross
=
new
OrderCrossover
();
NoMutation
mutation
=
new
NoMutation
();
RandomHeuristic
heuristic
=
new
RandomHeuristic
(
HealingMethods
.
getAvailableHealingMethods
());
VisualFitness
fitness
=
new
VisualFitness
(
this
,
currentGeometry
,
currentChecker
);
GeneticAlgorithm
<
HealingPlan
>
ga
=
GeneticAlgorithm
.
of
(
cross
,
mutation
,
heuristic
,
fitness
);
ga
.
run
();
CityObject
nextFeature
=
Copy
.
copy
(
currentFeature
);
nextGeometry
=
findNextGeometry
(
gmlId
,
nextFeature
);
System
.
out
.
println
(
gmlId
);
System
.
out
.
println
(
nextGeometry
);
System
.
out
.
println
(
nextFeature
.
getGeometries
().
get
(
0
));
showCurrentGeometry
();
showNextGeometry
();
test
.
setDisable
(
false
);
enableGuiControls
=
true
;
});
buildCurrent3dView
();
buildNext3dView
();
}
private
Geometry
findNextGeometry
(
GmlId
gmlId
,
CityObject
nextFeature
)
{
Geometry
[]
foundGeom
=
new
Geometry
[
1
];
Check
geomFinder
=
new
Check
()
{
@Override
public
void
check
(
Geometry
geom
)
{
if
(
geom
.
getGmlId
().
equals
(
gmlId
))
{
foundGeom
[
0
]
=
geom
;
}
}
@Override
public
RequirementType
getType
()
{
return
null
;
}
@Override
public
Check
createNewInstance
()
{
return
null
;
}
@Override
public
CheckId
getCheckId
()
{
return
null
;
}
@Override
public
Set
<
Requirement
>
appliesToRequirements
()
{
return
null
;
}
};
nextFeature
.
accept
(
geomFinder
);
return
foundGeom
[
0
];
}
private
void
showCurrentGeometry
()
{
currentTriangulatedGeometry
=
TriangulatedGeometry
.
of
(
currentGeometry
);
currentTriangulatedGeometry
.
setCullFace
(
CullFace
.
BACK
);
currentTriangulatedGeometry
.
setDrawMode
(
DrawMode
.
FILL
);
zoomOutForBoundingBox
(
currentGeometry
.
calculateBoundingBox
());
getCurrentMeshGroup
().
getChildren
().
clear
();
getCurrentMeshGroup
().
getChildren
().
addAll
(
currentTriangulatedGeometry
.
getMeshes
());
}
private
void
showNextGeometry
()
{
nextTriangulatedGeometry
=
TriangulatedGeometry
.
of
(
nextGeometry
);
nextTriangulatedGeometry
.
setCullFace
(
CullFace
.
BACK
);
nextTriangulatedGeometry
.
setDrawMode
(
DrawMode
.
FILL
);
zoomOutForBoundingBox
(
nextGeometry
.
calculateBoundingBox
());
getNextMeshGroup
().
getChildren
().
clear
();
getNextMeshGroup
().
getChildren
().
addAll
(
nextTriangulatedGeometry
.
getMeshes
());
}
private
Group
getNextMeshGroup
()
{
return
nextMeshGroup
;
}
private
List
<
Image
>
makeScreenshots
(
int
xRotSteps
,
int
yRotSteps
)
{
List
<
Image
>
images
=
new
ArrayList
<>();
SnapshotParameters
params
=
new
SnapshotParameters
();
for
(
int
j
=
0
;
j
<
xRotSteps
;
j
++)
{
cameraXRot
.
set
(
j
*
(
180
d
/
xRotSteps
));
for
(
int
i
=
0
;
i
<
yRotSteps
;
i
++)
{
cameraYRot
.
set
(
i
*
(
360
d
/
yRotSteps
));
Image
screen
=
view1
.
snapshot
(
params
,
null
);
images
.
add
(
screen
);
}
}
cameraXRot
.
set
(
0
);
cameraYRot
.
set
(
0
);
return
images
;
}
private
void
buildCurrent3dView
()
{
Group
currentRoot
=
new
Group
();
SubScene
currentScene
=
new
SubScene
(
currentRoot
,
500
,
300
,
true
,
SceneAntialiasing
.
BALANCED
);
currentScene
.
heightProperty
().
bind
(
view1
.
heightProperty
());
currentScene
.
widthProperty
().
bind
(
view1
.
widthProperty
());
currentScene
.
setFill
(
Color
.
AZURE
);
view1
.
getChildren
().
add
(
currentScene
);
currentWorld
=
new
Group
();
currentRoot
.
getChildren
().
add
(
currentWorld
);
currentMeshGroup
=
new
Group
();
currentWorld
.
getChildren
().
add
(
currentMeshGroup
);
AmbientLight
al
=
new
AmbientLight
(
Color
.
WHITE
);
currentRoot
.
getChildren
().
add
(
al
);
PerspectiveCamera
currentCamera
=
new
PerspectiveCamera
(
true
);
currentCamera
.
setNearClip
(
0.1
);
currentCamera
.
setFarClip
(
10000
d
);
currentCamera
.
translateZProperty
().
bind
(
translateZ
);
Rotate
cameraZRotation
=
new
Rotate
();
Rotate
cameraXRotation
=
new
Rotate
();
cameraXRotation
.
setAxis
(
Rotate
.
X_AXIS
);
cameraZRotation
.
setAxis
(
Rotate
.
Z_AXIS
);
cameraZRotation
.
angleProperty
().
bind
(
cameraXRot
);
cameraXRotation
.
angleProperty
().
bind
(
cameraYRot
);
currentWorld
.
getTransforms
().
add
(
cameraXRotation
);
currentWorld
.
getTransforms
().
add
(
cameraZRotation
);
currentRoot
.
getChildren
().
add
(
currentCamera
);
currentScene
.
setCamera
(
currentCamera
);
setupMeshViewControls
(
view1
);
}
private
void
setupMeshViewControls
(
Pane
canvas
)
{
canvas
.
setOnMousePressed
(
me
->
{
if
(
enableGuiControls
&&
me
.
getButton
()
==
MouseButton
.
PRIMARY
)
{
dragX
=
me
.
getScreenX
();
dragY
=
me
.
getScreenY
();
}
});
canvas
.
setOnScroll
(
se
->
translateZ
.
set
(
translateZ
.
get
()
+
se
.
getDeltaY
()
/
10
d
));
canvas
.
setOnMouseDragged
(
me
->
{
if
(
enableGuiControls
&&
me
.
getButton
()
==
MouseButton
.
PRIMARY
)
{
double
deltaX
=
me
.
getScreenX
()
-
dragX
;
double
deltaY
=
me
.
getScreenY
()
-
dragY
;
dragX
=
me
.
getScreenX
();
dragY
=
me
.
getScreenY
();
cameraXRot
.
set
(
cameraXRot
.
get
()
+
((
deltaX
/
3
d
)
%
360
));
cameraYRot
.
set
(
cameraYRot
.
get
()
+
((
deltaY
/
3
d
)
%
360
));
}
});
}
private
void
buildNext3dView
()
{
Group
nextRoot
=
new
Group
();
SubScene
nextScene
=
new
SubScene
(
nextRoot
,
500
,
300
,
true
,
SceneAntialiasing
.
BALANCED
);
nextScene
.
heightProperty
().
bind
(
view2
.
heightProperty
());
nextScene
.
widthProperty
().
bind
(
view2
.
widthProperty
());
nextScene
.
setFill
(
Color
.
AZURE
);
view2
.
getChildren
().
add
(
nextScene
);
nextWorld
=
new
Group
();
nextRoot
.
getChildren
().
add
(
nextWorld
);
nextMeshGroup
=
new
Group
();
nextWorld
.
getChildren
().
add
(
nextMeshGroup
);
AmbientLight
al
=
new
AmbientLight
(
Color
.
WHITE
);
nextRoot
.
getChildren
().
add
(
al
);
PerspectiveCamera
nextCamera
=
new
PerspectiveCamera
(
true
);
nextCamera
.
setNearClip
(
0.1
);
nextCamera
.
setFarClip
(
10000
d
);
nextCamera
.
translateZProperty
().
bind
(
translateZ
);
Rotate
cameraZRotation
=
new
Rotate
();
Rotate
cameraXRotation
=
new
Rotate
();
cameraXRotation
.
setAxis
(
Rotate
.
X_AXIS
);
cameraZRotation
.
setAxis
(
Rotate
.
Z_AXIS
);
cameraZRotation
.
angleProperty
().
bind
(
cameraXRot
);
cameraXRotation
.
angleProperty
().
bind
(
cameraYRot
);
nextWorld
.
getTransforms
().
add
(
cameraXRotation
);
nextWorld
.
getTransforms
().
add
(
cameraZRotation
);
nextRoot
.
getChildren
().
add
(
nextCamera
);
nextScene
.
setCamera
(
nextCamera
);
}
@Override
public
Optional
<
HBox
>
getToolbar
()
{
return
Optional
.
empty
();
}
@Override
public
Node
getMainScreen
()
{
return
pane
;
}
@Override
public
Image
getViewLogo
()
{
return
image
;
}
@Override
public
void
initializeView
(
MainWindow
mainWindow
)
{
FXMLLoader
loader
=
new
FXMLLoader
(
getClass
().
getResource
(
"geneticGUI.fxml"
));
loader
.
setController
(
this
);
try
{
pane
=
loader
.
load
();
}
catch
(
IOException
e
)
{
throw
new
UncheckedIOException
(
e
);
}
try
{
setupViews
();
}
catch
(
CityGmlParseException
|
InvalidGmlFileException
e
)
{
e
.
printStackTrace
();
}
}
private
void
setupViews
()
throws
CityGmlParseException
,
InvalidGmlFileException
{
ParserConfiguration
parserConfig
=
new
ParserConfiguration
(
8
,
false
);
// CityDoctorModel model1 = CityGmlParser.parseCityGmlFile("src/test/resources/SimpleSolid_SrefBS.gml",
// parserConfig);
CityDoctorModel
model1
=
CityGmlParser
.
parseCityGmlFile
(
"src/test/resources/TestBuilding3.gml"
,
parserConfig
);
currentChecker
=
new
Checker
(
model1
);
currentChecker
.
runChecks
();
Building
building
=
model1
.
getBuildings
().
get
(
0
);
currentGeometry
=
building
.
getGeometries
().
get
(
0
);
currentFeature
=
building
;
showCurrentGeometry
();
}
public
void
zoomOutForBoundingBox
(
BoundingBox
b
)
{
double
cameraDistance
=
2.0d
;
Vector3d
objectSizes
=
b
.
getDiagonal
();
double
objectSize
=
max
(
objectSizes
.
getX
(),
objectSizes
.
getY
(),
objectSizes
.
getZ
());
double
cameraView
=
2.0d
*
Math
.
tan
(
0.5d
*
Math
.
toRadians
(
30
));
// Visible height 1 meter in front
double
distance
=
cameraDistance
*
objectSize
/
cameraView
;
// Combined wanted distance from the object
distance
+=
0.5d
*
objectSize
;
// Estimated offset from the center to the outside of the object
translateZ
.
set
(-
distance
);
}
private
double
max
(
double
a
,
double
b
,
double
c
)
{
double
temp
=
Math
.
max
(
a
,
b
);
return
Math
.
max
(
temp
,
c
);
}
public
Group
getCurrentMeshGroup
()
{
return
currentMeshGroup
;
}
@Override
public
void
onHide
()
{
// TODO Auto-generated method stub
}
@Override
public
void
onShow
(
CityDoctorModel
model
,
Checker
checker
)
{
// TODO Auto-generated method stub
}
public
static
void
main
(
String
[]
args
)
{
ViewRegistration
.
registerView
(
new
GeneticsGUI
());
HealerGUI
.
main
(
args
);
}
public
List
<
Image
>
createScreenshots
(
Geometry
geom
,
double
zoomLevel
,
int
xRotSteps
,
int
yRotSteps
)
{
currentGeometry
=
geom
;
currentTriangulatedGeometry
=
TriangulatedGeometry
.
of
(
currentGeometry
);
currentTriangulatedGeometry
.
setCullFace
(
CullFace
.
BACK
);
currentTriangulatedGeometry
.
setDrawMode
(
DrawMode
.
FILL
);
setZoomLevel
(
zoomLevel
);
getCurrentMeshGroup
().
getChildren
().
clear
();
getCurrentMeshGroup
().
getChildren
().
addAll
(
currentTriangulatedGeometry
.
getMeshes
());
return
makeScreenshots
(
xRotSteps
,
yRotSteps
);
}
private
void
setZoomLevel
(
double
zoomLevel
)
{
translateZ
.
set
(
zoomLevel
);
}
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/gui/ImageComparison.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic.gui
;
import
java.util.Objects
;
import
javafx.scene.image.Image
;
import
javafx.scene.image.PixelReader
;
import
javafx.scene.paint.Color
;
public
class
ImageComparison
{
private
ImageComparison
()
{
// only static access
}
public
static
double
compare
(
Image
image1
,
Image
image2
)
{
assertPredefinitions
(
image1
,
image2
);
PixelReader
pr1
=
image1
.
getPixelReader
();
Objects
.
requireNonNull
(
pr1
);
PixelReader
pr2
=
image2
.
getPixelReader
();
Objects
.
requireNonNull
(
pr2
);
double
pictureDif
=
0
;
for
(
int
i
=
0
;
i
<
image1
.
getWidth
();
i
++)
{
for
(
int
j
=
0
;
j
<
image2
.
getHeight
();
j
++)
{
double
pixelComp
=
1.0
;
Color
c1
=
pr1
.
getColor
(
i
,
j
);
Color
c2
=
pr2
.
getColor
(
i
,
j
);
double
redDif
=
Math
.
abs
(
c1
.
getRed
()
-
c2
.
getRed
());
double
blueDif
=
Math
.
abs
(
c1
.
getBlue
()
-
c2
.
getBlue
());
double
greenDif
=
Math
.
abs
(
c1
.
getGreen
()
-
c2
.
getGreen
());
if
(
redDif
>
0.05
)
{
pixelComp
-=
1
/
3
d
;
}
if
(
blueDif
>
0.05
)
{
pixelComp
-=
1
/
3
d
;
}
if
(
greenDif
>
0.05
)
{
pixelComp
-=
1
/
3
d
;
}
pictureDif
+=
pixelComp
;
}
}
double
dimension
=
image1
.
getWidth
()
*
image1
.
getHeight
();
pictureDif
=
Math
.
max
(
0
,
dimension
-
50
*
(
dimension
-
pictureDif
));
return
pictureDif
/
dimension
;
}
private
static
void
assertPredefinitions
(
Image
image1
,
Image
image2
)
{
if
(
image1
.
getProgress
()
!=
1.0
||
image2
.
getProgress
()
!=
1.0
)
{
throw
new
IllegalArgumentException
(
"Pictures are not fully loaded"
);
}
if
(
image1
.
getWidth
()
!=
image2
.
getWidth
()
||
image1
.
getHeight
()
!=
image2
.
getHeight
())
{
throw
new
IllegalArgumentException
(
"Pictures have to be the same size"
);
}
}
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/java/de/hft/stuttgart/citydoctor2/healer/genetic/gui/VisualFitness.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic.gui
;
import
java.util.List
;
import
de.hft.stuttgart.citydoctor2.check.Checker
;
import
de.hft.stuttgart.citydoctor2.datastructure.BoundingBox
;
import
de.hft.stuttgart.citydoctor2.datastructure.Geometry
;
import
de.hft.stuttgart.citydoctor2.healer.Healer
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
import
de.hft.stuttgart.citydoctor2.healer.genetic.FitnessEvaluation
;
import
de.hft.stuttgart.citydoctor2.math.Vector3d
;
import
de.hft.stuttgart.citydoctor2.utils.Copy
;
import
javafx.scene.image.Image
;
public
class
VisualFitness
implements
FitnessEvaluation
<
HealingPlan
>
{
private
int
xRotSteps
=
6
;
private
int
yRotSteps
=
12
;
private
GeneticsGUI
gui
;
private
Geometry
geom
;
private
List
<
Image
>
originalImages
;
private
Checker
c
;
private
double
distance
;
public
VisualFitness
(
GeneticsGUI
gui
,
Geometry
geom
,
Checker
c
)
{
this
.
gui
=
gui
;
this
.
geom
=
geom
;
this
.
c
=
c
;
BoundingBox
b
=
geom
.
calculateBoundingBox
();
double
cameraDistance
=
2.0d
;
Vector3d
objectSizes
=
b
.
getDiagonal
();
double
objectSize
=
max
(
objectSizes
.
getX
(),
objectSizes
.
getY
(),
objectSizes
.
getZ
());
double
cameraView
=
2.0d
*
Math
.
tan
(
0.5d
*
Math
.
toRadians
(
30
));
// Visible height 1 meter in front
distance
=
cameraDistance
*
objectSize
/
cameraView
;
distance
+=
0.5d
*
objectSize
;
// Estimated offset from the center to the outside of the object
distance
=
-
distance
;
originalImages
=
gui
.
createScreenshots
(
geom
,
distance
,
xRotSteps
,
yRotSteps
);
}
private
double
max
(
double
a
,
double
b
,
double
c
)
{
double
temp
=
Math
.
max
(
a
,
b
);
return
Math
.
max
(
temp
,
c
);
}
@Override
public
double
evaluate
(
HealingPlan
plan
)
{
Healer
healer
=
new
Healer
(
c
,
plan
);
Geometry
copy
=
Copy
.
copy
(
geom
);
healer
.
heal
(
copy
,
copy
.
getParent
());
if
(
copy
.
containsAnyError
())
{
System
.
out
.
println
(
plan
);
System
.
out
.
println
(
"Fitness: 0"
);
return
0
;
}
List
<
Image
>
compareImages
=
gui
.
createScreenshots
(
copy
,
distance
,
xRotSteps
,
yRotSteps
);
if
(
originalImages
.
size
()
!=
compareImages
.
size
())
{
throw
new
IllegalStateException
(
"Number of images differs"
);
}
double
value
=
0
;
for
(
int
i
=
0
;
i
<
originalImages
.
size
();
i
++)
{
Image
orig
=
originalImages
.
get
(
i
);
Image
compare
=
compareImages
.
get
(
i
);
value
+=
ImageComparison
.
compare
(
orig
,
compare
);
}
double
fitness
=
value
/
(
xRotSteps
*
yRotSteps
);
System
.
out
.
println
(
"Fitness: "
+
fitness
);
return
fitness
;
}
}
CityDoctorParent/CityDoctorHealerGenetic/src/main/resources/de/hft/stuttgart/citydoctor2/healer/genetic/gui/genetic.png
0 → 100644
View file @
ffdae21a
1.13 KB
CityDoctorParent/CityDoctorHealerGenetic/src/main/resources/de/hft/stuttgart/citydoctor2/healer/genetic/gui/geneticGUI.fxml
0 → 100644
View file @
ffdae21a
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<VBox
maxHeight=
"1.7976931348623157E308"
maxWidth=
"1.7976931348623157E308"
minHeight=
"-Infinity"
minWidth=
"-Infinity"
xmlns=
"http://javafx.com/javafx/8.0.221"
xmlns:fx=
"http://javafx.com/fxml/1"
>
<children>
<SplitPane
dividerPositions=
"0.7"
maxHeight=
"1.7976931348623157E308"
maxWidth=
"1.7976931348623157E308"
orientation=
"VERTICAL"
VBox.vgrow=
"ALWAYS"
>
<items>
<HBox
maxHeight=
"1.7976931348623157E308"
maxWidth=
"1.7976931348623157E308"
>
<children>
<Pane
fx:id=
"view1"
maxHeight=
"1.7976931348623157E308"
maxWidth=
"1.7976931348623157E308"
HBox.hgrow=
"ALWAYS"
/>
<Pane
fx:id=
"view2"
maxHeight=
"1.7976931348623157E308"
maxWidth=
"1.7976931348623157E308"
HBox.hgrow=
"ALWAYS"
/>
</children>
</HBox>
<HBox>
<children>
<Button
fx:id=
"test"
mnemonicParsing=
"false"
text=
"Button"
/>
</children>
</HBox>
</items>
</SplitPane>
</children>
</VBox>
CityDoctorParent/CityDoctorHealerGenetic/src/test/java/de/hft/stuttgart/citydoctor2/healer/genetic/GeneticAlgorithmTest.java
0 → 100644
View file @
ffdae21a
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
import
static
org
.
junit
.
Assert
.*;
import
org.junit.Test
;
import
de.hft.stuttgart.citydoctor2.healer.HealingMethods
;
import
de.hft.stuttgart.citydoctor2.healer.HealingPlan
;
public
class
GeneticAlgorithmTest
{
@Test
public
void
test
()
{
Crossover
<
HealingPlan
>
cross
=
new
OrderCrossover
();
Mutation
<
HealingPlan
>
mutation
=
new
NoMutation
();
FitnessEvaluation
<
HealingPlan
>
fitness
=
new
RandomFitness
();
Heuristic
<
HealingPlan
>
heuristic
=
new
RandomHeuristic
(
HealingMethods
.
getAvailableHealingMethods
());
GeneticAlgorithm
<
HealingPlan
>
ga
=
GeneticAlgorithm
.
of
(
cross
,
mutation
,
heuristic
,
fitness
);
ga
.
run
();
assertNotNull
(
ga
.
getResult
());
}
}
CityDoctorParent/CityDoctorHealerGenetic/src/test/java/de/hft/stuttgart/citydoctor2/healer/genetic/MetaFitnessValues.java
0 → 100644
View file @
ffdae21a
/*-
* Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart
*
* This file is part of CityDoctor2.
*
* CityDoctor2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CityDoctor2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CityDoctor2. If not, see <https://www.gnu.org/licenses/>.
*/
package
de.hft.stuttgart.citydoctor2.healer.genetic
;
public
class
MetaFitnessValues
{
int
numberOfPolygonsWithPlanarityIssues
=
0
;
int
numberOfPolygonsWithoutPlanarityIssues
=
0
;
int
numberOfPolygonsWithOtherErrors
=
0
;
int
numberOfPolygonsWithNoErrors
=
0
;
public
void
reset
()
{
numberOfPolygonsWithPlanarityIssues
=
0
;
numberOfPolygonsWithoutPlanarityIssues
=
0
;
numberOfPolygonsWithOtherErrors
=
0
;
numberOfPolygonsWithNoErrors
=
0
;
}
public
MetaFitnessValues
copy
()
{
MetaFitnessValues
copy
=
new
MetaFitnessValues
();
copy
.
numberOfPolygonsWithNoErrors
=
numberOfPolygonsWithNoErrors
;
copy
.
numberOfPolygonsWithOtherErrors
=
numberOfPolygonsWithOtherErrors
;
copy
.
numberOfPolygonsWithoutPlanarityIssues
=
numberOfPolygonsWithoutPlanarityIssues
;
copy
.
numberOfPolygonsWithPlanarityIssues
=
numberOfPolygonsWithPlanarityIssues
;
return
copy
;
}
}
Prev
1
…
4
5
6
7
8
9
10
11
12
13
Next
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