Commit 97a65114 authored by Riegel's avatar Riegel
Browse files

Merge branch 'dev' into 'master'

Version 3.15.0

See merge request !8
parents 99c8f6a8 5950ea5f
Pipeline #10106 passed with stage
in 3 minutes and 15 seconds
set CLASSPATH=.\target\classes;..\CityDoctorModel\target\classes
set PATH="c:\Program Files (x86)\Java\jdk1.8.0_25\bin"
javah -jni de.hft.stuttgart.citydoctor2.CppInitializer
javah -jni de.hft.stuttgart.citydoctor2.connect.edge.CppPolygonHealing
javah -jni de.hft.stuttgart.citydoctor2.connect.edge.CppHealResult
javah -jni de.hft.stuttgart.citydoctor2.connect.edge.CppFeature
pause
<?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) &gt; 0 or count(descendant::*:lod2Solid) &gt; 0 or count(descendant::*:lod3Solid) &gt; 0 or count(descendant::*:lod4Solid) &gt; 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>
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 http://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.15.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>CityDoctorHealer</artifactId>
<dependencies>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorModel</artifactId>
</dependency>
<dependency>
<groupId>de.hft.stuttgart</groupId>
<artifactId>CityDoctorValidation</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>1.0-alpha-11</version>
<extensions>true</extensions>
<configuration>
<javahClassNames>
<javahClassName>de.hft.stuttgart.citydoctor2.connect.edge.CppFeature</javahClassName>
<javahClassName>de.hft.stuttgart.citydoctor2.CppInitializer</javahClassName>
<javahClassName>de.hft.stuttgart.citydoctor2.connect.edge.CppHealResult</javahClassName>
</javahClassNames>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<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
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<core:CityModel xmlns:xAL="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0" xmlns:gml="http://www.opengis.net/gml" xmlns:wtr="http://www.opengis.net/citygml/waterbody/2.0" xmlns:app="http://www.opengis.net/citygml/appearance/2.0" xmlns:tex="http://www.opengis.net/citygml/texturedsurface/2.0" xmlns:core="http://www.opengis.net/citygml/2.0" xmlns:veg="http://www.opengis.net/citygml/vegetation/2.0" xmlns:dem="http://www.opengis.net/citygml/relief/2.0" xmlns:tran="http://www.opengis.net/citygml/transportation/2.0" xmlns:bldg="http://www.opengis.net/citygml/building/2.0" xmlns:grp="http://www.opengis.net/citygml/cityobjectgroup/2.0" xmlns:tun="http://www.opengis.net/citygml/tunnel/2.0" xmlns:frn="http://www.opengis.net/citygml/cityfurniture/2.0" xmlns:brid="http://www.opengis.net/citygml/bridge/2.0" xmlns:gen="http://www.opengis.net/citygml/generics/2.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:luse="http://www.opengis.net/citygml/landuse/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/citygml/waterbody/2.0 http://schemas.opengis.net/citygml/waterbody/2.0/waterBody.xsd http://www.opengis.net/citygml/appearance/2.0 http://schemas.opengis.net/citygml/appearance/2.0/appearance.xsd http://www.opengis.net/citygml/texturedsurface/2.0 http://schemas.opengis.net/citygml/texturedsurface/2.0/texturedSurface.xsd http://www.opengis.net/citygml/vegetation/2.0 http://schemas.opengis.net/citygml/vegetation/2.0/vegetation.xsd http://www.opengis.net/citygml/relief/2.0 http://schemas.opengis.net/citygml/relief/2.0/relief.xsd http://www.opengis.net/citygml/transportation/2.0 http://schemas.opengis.net/citygml/transportation/2.0/transportation.xsd http://www.opengis.net/citygml/building/2.0 http://schemas.opengis.net/citygml/building/2.0/building.xsd http://www.opengis.net/citygml/cityobjectgroup/2.0 http://schemas.opengis.net/citygml/cityobjectgroup/2.0/cityObjectGroup.xsd http://www.opengis.net/citygml/tunnel/2.0 http://schemas.opengis.net/citygml/tunnel/2.0/tunnel.xsd http://www.opengis.net/citygml/cityfurniture/2.0 http://schemas.opengis.net/citygml/cityfurniture/2.0/cityFurniture.xsd http://www.opengis.net/citygml/bridge/2.0 http://schemas.opengis.net/citygml/bridge/2.0/bridge.xsd http://www.opengis.net/citygml/generics/2.0 http://schemas.opengis.net/citygml/generics/2.0/generics.xsd http://www.opengis.net/citygml/landuse/2.0 http://schemas.opengis.net/citygml/landuse/2.0/landUse.xsd">
<core:cityObjectMember>
<bldg:Building gml:id="CityDoctor_1554196053314_13">
<bldg:lod2Solid>
<gml:Solid>
<gml:exterior>
<gml:CompositeSurface>
<gml:surfaceMember>
<gml:Polygon gml:id="CityDoctor_1554196053313_1">
<gml:exterior>
<gml:LinearRing gml:id="CityDoctor_1554196053313_2">
<gml:posList srsDimension="3">4.160428746108475 7.172506867550141 10.540765429820073 4.160428746108475 7.172506867550141 10.540765429820073 9.714428746112201 8.075506867483085 10.540765429820073 9.714428746112201 8.075506867483085 10.540765429820073 8.88942874610056 13.090506867147809 10.540765429820073 8.88942874610056 13.090506867147809 10.540765429820073 3.3354287460968335 12.183506867490536 10.540765429820073 3.3354287460968335 12.183506867490536 10.540765429820073 4.160428746108475 7.172506867550141 10.540765429820073</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="CityDoctor_1554196053313_3">
<gml:exterior>
<gml:LinearRing gml:id="CityDoctor_1554196053313_4">
<gml:posList srsDimension="3">3.3354287460968335 12.183506867490536 7.815765429820079 8.88942874610056 13.090506867147809 7.815765429820079 9.714428746112201 8.075506867483085 7.815765429820079 4.160428746108475 7.172506867550141 7.815765429820079 3.3354287460968335 12.183506867490536 7.815765429820079</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="CityDoctor_1554196053313_5">
<gml:exterior>
<gml:LinearRing gml:id="CityDoctor_1554196053313_6">
<gml:posList srsDimension="3">4.160428746108475 7.172506867550141 10.540765429820073 4.160428746108475 7.172506867550141 10.540765429820073 4.160428746108475 7.172506867550141 7.815765429820079 9.714428746112201 8.075506867483085 7.815765429820079 9.714428746112201 8.075506867483085 10.540765429820073 9.714428746112201 8.075506867483085 10.540765429820073 4.160428746108475 7.172506867550141 10.540765429820073</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="CityDoctor_1554196053313_7">
<gml:exterior>
<gml:LinearRing gml:id="CityDoctor_1554196053313_8">
<gml:posList srsDimension="3">9.714428746112201 8.075506867483085 10.540765429820073 9.714428746112201 8.075506867483085 10.540765429820073 9.714428746112201 8.075506867483085 7.815765429820079 8.88942874610056 13.090506867147809 7.815765429820079 8.88942874610056 13.090506867147809 10.540765429820073 8.88942874610056 13.090506867147809 10.540765429820073 9.714428746112201 8.075506867483085 10.540765429820073</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="CityDoctor_1554196053313_9">
<gml:exterior>
<gml:LinearRing gml:id="CityDoctor_1554196053313_10">
<gml:posList srsDimension="3">8.88942874610056 13.090506867147809 10.540765429820073 8.88942874610056 13.090506867147809 10.540765429820073 8.88942874610056 13.090506867147809 7.815765429820079 3.3354287460968335 12.183506867490536 7.815765429820079 3.3354287460968335 12.183506867490536 10.540765429820073 3.3354287460968335 12.183506867490536 10.540765429820073 8.88942874610056 13.090506867147809 10.540765429820073</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
<gml:surfaceMember>
<gml:Polygon gml:id="CityDoctor_1554196053313_11">
<gml:exterior>
<gml:LinearRing gml:id="CityDoctor_1554196053313_12">
<gml:posList srsDimension="3">3.3354287460968335 12.183506867490536 10.540765429820073 3.3354287460968335 12.183506867490536 10.540765429820073 3.3354287460968335 12.183506867490536 7.815765429820079 4.160428746108475 7.172506867550141 7.815765429820079 4.160428746108475 7.172506867550141 10.540765429820073 4.160428746108475 7.172506867550141 10.540765429820073 3.3354287460968335 12.183506867490536 10.540765429820073</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:surfaceMember>
</gml:CompositeSurface>
</gml:exterior>
</gml:Solid>
</bldg:lod2Solid>
</bldg:Building>
</core:cityObjectMember>
</core:CityModel>
\ No newline at end of file
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>zip</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>libs</outputDirectory>
<excludes>
<exclude>${project.groupId}:${project.artifactId}:jar:*</exclude>
</excludes>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>./assets/</directory>
<useDefaultExcludes>true</useDefaultExcludes>
<outputDirectory>./assets</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>${project.artifactId}-${project.version}.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.basedir}/src/assembly</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>start.bat</include>
<include>streamingStandardConfig.yml</include>
<include>TestBuilding1.gml</include>
<include>checkForSolid.xml</include>
</includes>
<filtered>true</filtered>
</fileSet>
</fileSets>
</assembly>
\ No newline at end of file
<?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) &gt; 0 or count(descendant::*:lod2Solid) &gt; 0 or count(descendant::*:lod3Solid) &gt; 0 or count(descendant::*:lod4Solid) &gt; 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>
java -jar ${project.artifactId}-${project.version}.jar -in TestBuilding1.gml -out TestBuilding1Fixed.gml -config streamingStandardConfig.yml -xmlReport output.xml
pause
\ No newline at end of file
requirements:
R_GE_R_TOO_FEW_POINTS:
enabled: true
R_GE_R_NOT_CLOSED:
enabled: true
R_GE_R_CONSECUTIVE_POINTS_SAME:
enabled: true
R_GE_R_SELF_INTERSECTION:
enabled: true
R_GE_S_MULTIPLE_CONNECTED_COMPONENTS:
enabled: true
R_GE_P_INTERIOR_DISCONNECTED:
enabled: true
R_GE_P_INTERSECTING_RINGS:
enabled: true
R_GE_P_NON_PLANAR:
enabled: true
parameters:
# one of ("distance", "angle", "both")
type: distance
# in m
distanceTolerance: 0.01
# in degree
angleTolerance: 1
R_GE_P_HOLE_OUTSIDE:
enabled: true
R_GE_P_ORIENTATION_RINGS_SAME:
enabled: true
R_GE_P_INNER_RINGS_NESTED:
enabled: true
R_GE_S_TOO_FEW_POLYGONS:
enabled: true
R_GE_S_NOT_CLOSED:
enabled: true
R_GE_S_NON_MANIFOLD_EDGE:
enabled: true
R_GE_S_POLYGON_WRONG_ORIENTATION:
enabled: true
R_GE_S_ALL_POLYGONS_WRONG_ORIENTATION:
enabled: true
R_GE_S_NON_MANIFOLD_VERTEX:
enabled: true
R_GE_S_SELF_INTERSECTION:
enabled: true
R_SE_BS_IS_WALL:
enabled: false
parameters:
lowerAngle: '45'
upperAngle: '135'
R_SE_BS_IS_FLOOR:
enabled: false
R_SE_BS_GROUND_UNFRAGMENTED:
enabled: false
R_SE_BS_IS_GROUND:
enabled: false
R_SE_BS_IS_CEILING:
enabled: false
globalParameters:
numberOfRoundingPlaces: 8
# in m
minVertexDistance: 0.0001
schematronPath: 'checkForSolid.xml'
useStreaming: true
xmlValidation: false
/** --------------------------------------------------
* Hochschule f�r Technik Stuttgart
* Fachbereich Vermessung , Informatik und Mathematik
* Schellingstr . 24
* D - 70174 Stuttgart
*
* Projekt CityDoktor
*
* Copyright (c) 2011 HFT Stuttgart. All rights reserved.
* HFT Stuttgart and its licensors retain all intellectual property and
* proprietary rights in and to this software and related documentation.
* Any use, reproduction, disclosure, or distribution of this software
* and related documentation without an express license agreement from
* HFT Stuttgart is strictly prohibited.
*
* Please refer to the applicable HFT Stuttgart end user license agreement (EULA)
* associated with this source code for terms and conditions that govern
* your use of this HFT Stuttgart software.
*
* 11.09.2012
* bogdahn
* @author
* @version
*
*/
package de.hft.stuttgart.citydoctor2;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import de.hft.stuttgart.citydoctor2.connect.edge.NativeException;
/**
* @author bogdahn
*
*/
public class CppInitializer {
private static final String SUN_ARCH_DATA_MODEL = "sun.arch.data.model";
private static Logger logger = LogManager.getLogger(CppInitializer.class);
private static native boolean initCppLibrary() throws NativeException;
private static native boolean checkVersions(String jdkVersion) throws NativeException;
public static synchronized void initCpp() {
// init CPP JNI Checks
String dataModel = System.getProperty(SUN_ARCH_DATA_MODEL);
if (dataModel.equals("64")) {
// System.loadLibrary( "CityDoctor2CPP-windows-x64-sgd" ); // debug dll
System.loadLibrary("../CityDoctorHealer/lib/CityDoctor2CPP-windows-x64-s");
// System.loadLibrary("CityDoctor2CPP-windows-x64-s");
// System.loadLibrary("lib/libTestHeal");
} else if (dataModel.equals("32")) {
// System.loadLibrary( "CityDoctor2CPP-windows-x86-sgd" ); // debug dll
// System.loadLibrary("../CityDoctorHealer/lib/CityDoctor2CPP-windows-x86-s");
// System.loadLibrary("CityDoctor2CPP-windows-x86-s");
System.err.println("Load native library failed.");
System.err.println("Unknown architecture: " + dataModel);
System.err.println("Valid values are: \"64\"");
System.err.println("No library will be loaded");
} else {
System.err.println("Load native library failed.");
System.err.println("Unknown architecture: " + dataModel);
System.err.println("Valid values are: \"64\"");
System.err.println("No library will be loaded");
}
try {
if (initCppLibrary()) {
// checkVersions(System.getProperty("java.version")); // TODO : checkVersions
// funktioniert noch nicht!!
}
} catch (NativeException ne) {
System.err.println("Native Exception");
System.err.println(ne.getType());
System.err.println(ne.getMessage());
ne.printStackTrace();
System.exit(1);
} catch (IllegalArgumentException e) {
e.printStackTrace();
System.exit(1);
}
}
private CppInitializer() {
// only static utility
}
}
package de.hft.stuttgart.citydoctor2.connect.edge;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.hft.stuttgart.citydoctor2.datastructure.BoundarySurface;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
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.datastructure.Vertex;
/**
* @author wewetzer
* @version 1.0
*/
public class CppFeature extends CppReferenceHandlingBase {
private native long createCppFeature(String type) throws OutOfMemoryError;
private native void disposeCppFeature(long ptrToCppFeature) throws NativePointerCastException;
// setting geometry and attributes
private native boolean setGeometry(long ptrToFeature, int geomType, double[] pointArray, int[] pointIdMap,
int[] polygonArray, int[] polygonIdMap) throws NativeException;
private native boolean setLoD(long ptrToFeature, int LoD) throws NativeException;
// gets the id of a corresponding C++ entity to a given Java entity id
private native int getCppPointId(long ptrToFeature, int javaPointId) throws NativeException;
private native int getCppPolygonId(long ptrToFeature, int javaPolygonId) throws NativeException;
private native double[] getPoints(long ptrToFeature) throws NativeException;
// debug native methods
private native void printMesh(long ptrToFeature) throws NativeException;
private native void writeMeshToInventor(long ptrToFeature, String fileName) throws NativeException;
private String type;
public CppFeature(String type) {
this.type = type;
createCppObject();
}
/**
* Creates an C++ feature object
*
* @throws IllegalStateException Thrown if the encapsulated "long-Pointer"
* isn't 0
* @throws NativeOutOfMemoryException If there is no more memory on the native
* side
*
* @see {@link disposeCppObject}
* @see de.hft.stuttgart.citydoctor2.connect.edge.CppReferenceHandlingBase#createCppObject()
*/
private void createCppObject() {
if (0L != ptrToCppObject) {
throw new IllegalStateException("Can't create new C++ object, there is already one!");
}
// Maybe an exception is thrown
ptrToCppObject = createCppFeature(type);
}
@Override
public void disposeCppObject() throws NativePointerCastException {
if (0L != ptrToCppObject) {
disposeCppFeature(ptrToCppObject);
ptrToCppObject = 0L;
}
}
public void setGeometry(Geometry geometry) throws NativeException {
checkNullPointer();
CppGeometryData geometryData = createCppFeatureInput(geometry);
setGeometry(ptrToCppObject, 0, geometryData.pointArr, geometryData.pointIdMap, geometryData.polygonArr, geometryData.polygonIdMap);
}
public void setLoD(Lod lod) throws NativeException {
checkNullPointer();
int LoD = -1;
if(lod == Lod.LOD0) {
LoD = 0;
}
else if(lod == Lod.LOD1) {
LoD = 1;
}
else if(lod == Lod.LOD2) {
LoD = 2;
}
else if(lod == Lod.LOD3) {
LoD = 3;
}
else if(lod == Lod.LOD4) {
LoD = 4;
}
setLoD(ptrToCppObject, LoD);
}
/**
* Returns the id of the corresponding C++ point to a given Java point id
*
* @param javaPointId The given Java point id
* @return The corresponding C++ point id
* @throws IllegalArgumentException If the feature pointer is 0
* @throws NativeException If an error occurred during the execution of
* the native code
*/
public int getCppPointId(int javaPointId) throws NativeException {
checkNullPointer();
return this.getCppPointId(ptrToCppObject, javaPointId);
}
/**
* Returns the id of the corresponding C++ polygon to a given java polygon
* id
*
* @param javaPolygonId The given Java polygon id
* @return The corresponding C++ polygon id
* @throws IllegalArgumentException If the feature pointer is 0
* @throws NativeException If an error occurred during the execution of
* the native code
*/
public int getCppPolygonId(int javaPolygonId) throws NativeException {
checkNullPointer();
return this.getCppPolygonId(ptrToCppObject, javaPolygonId);
}
public double[] getPoints() throws NativeException {
checkNullPointer();
return this.getPoints(ptrToCppObject);
}
/**
* Debug method, that prints the mesh
*
* @throws IllegalArgumentException If the feature pointer is 0
* @throws NativeException If an error occurred during the execution of
* the native code
*/
public void printMesh() throws NativeException {
checkNullPointer();
this.printMesh(ptrToCppObject);
}
/**
* Writes the current stored level of detail 1 mesh in the file "filename.iv" as
* Open Inventor file.
*
* @param fileName The name of the output file
* @throws IllegalArgumentException If the feature pointer is 0
* @throws NativeException If an error occurred during the execution of
* the native code n
*/
public void writeMeshToInventor(String fileName) throws NativeException {
checkNullPointer();
this.writeMeshToInventor(ptrToCppObject, fileName);
}
/**
* Writes the current stored level of detail 2 mesh in the file "filename.iv" as
* Open Inventor file.
*
* @param fileName The name of the output file
* @throws IllegalArgumentException If the feature pointer is 0
* @throws NativeException If an error occurred during the execution of
* the native code n
*/
private void printGeomDataAsCppCode(CppGeometryData cppGeoData) {
System.out.println("\n \n \n");
double[] pnts = cppGeoData.pointArr;
System.out.println("const size_t numCoords = " + pnts.length / 3 + ";");
System.out.println("Coordinate3d * coords[" + pnts.length / 3 + "];");
for (int i = 0; i < pnts.length; i += 3) {
System.out.print("coords[ " + i / 3 + " ] = new Coordinate3d( ");
System.out.println(pnts[i] + ", " + pnts[i + 1] + ", " + pnts[i + 2] + " );");
}
System.out.println("");
int[] polys = cppGeoData.polygonArr;
System.out.println("const size_t numPolys = " + cppGeoData.polygonIdMap.length + ";");
System.out.println("const size_t sizePolys = " + polys.length + ";");
System.out.print("int polyArr[] = {");
for (int i = 0; i < polys.length - 1; ++i) {
if (-1 == polys[i]) {
System.out.println();
System.out.print(" " + polys[i] + ", ");
} else if (-2 == polys[i]) {
System.out.print(" " + polys[i] + ", ");
} else {
System.out.print(" " + polys[i] + ", ");
}
}
System.out.println(" " + polys[polys.length - 1] + " \n};\n");
if (cppGeoData.boundarySurfaceTypeArr.length > 0) {
System.out.println("BoundarySurfaceType types[numPolys] = {");
for (int i = 0; i < cppGeoData.boundarySurfaceTypeArr.length; i++) {
switch (cppGeoData.boundarySurfaceTypeArr[i]) {
case (1): {
System.out.println(" roofsurface,");
break;
}
case (2): {
System.out.println(" wallsurface,");
break;
}
case (3): {
System.out.println(" groundsurface,");
break;
}
default: {
System.out.println(" undefined,");
}
}
;
}
System.out.println("};");
System.out.println("return createHouse( coords, numCoords, polyArr, numPolys, sizePolys, types, true);");
}
}
/**
* generates all the necessary geometric input for the CppFeature
*
* @param geom
*/
private CppGeometryData createCppFeatureInput(Geometry geometry) {
// ====================================================================
// Vertices
List<Vertex> vertices = geometry.getVertices();
double[] pointArr = new double[vertices.size() * 3];
int[] pointIdMap = new int[vertices.size()];
Map<Vertex, Integer> vertexToIndexMap = new HashMap<>(vertices.size());
for (int i = 0; i < vertices.size(); i++) {
Vertex v = vertices.get(i);
vertexToIndexMap.put(v, i);
pointArr[i * 3 + 0] = v.getX();
pointArr[i * 3 + 1] = v.getY();
pointArr[i * 3 + 2] = v.getZ();
pointIdMap[i] = i;
}
// ====================================================================
// Polygons & BoundarySurfaceType
List<Polygon> polygons = geometry.getPolygons();
int numReferencedVertices = 0;
int[] polygonIdMap = new int[polygons.size()];
for (int i = 0; i < polygons.size(); i++) {
Polygon p = polygons.get(i);
polygonIdMap[i] = i;
numReferencedVertices += p.getExteriorRing().getVertices().size();
for (LinearRing lr : p.getInnerRings()) {
numReferencedVertices += lr.getVertices().size();
}
}
int[] polygonArr = new int[numReferencedVertices];
int[] boundarySurfaceTypeArr = new int[polygons.size()];
int polyCounter = 0;
for (int polyIndex = 0; polyIndex < polygons.size(); polyIndex++) {
Polygon p = polygons.get(polyIndex);
// exterior ring = -1
polygonArr[polyCounter++] = -1;
for (int i = 0; i < p.getExteriorRing().getVertices().size() - 1; i++) {
Vertex v = p.getExteriorRing().getVertices().get(i);
int id = vertexToIndexMap.get(v);
polygonArr[polyCounter++] = id;
}
for (LinearRing lr : p.getInnerRings()) {
// interior ring = -2
polygonArr[polyCounter++] = -2;
for (int i = 0; i < lr.getVertices().size() - 1; i++) {
Vertex v = lr.getVertices().get(i);
int id = vertexToIndexMap.get(v);
polygonArr[polyCounter++] = id;
}
}
if (geometry.getLod() == Lod.LOD2) {
BoundarySurface bs = p.getPartOfSurface();
if (bs != null) {
boundarySurfaceTypeArr[polyIndex] = bs.getType().ordinal();
} else {
boundarySurfaceTypeArr[polyIndex] = 999999;
}
}
}
return new CppGeometryData(pointArr, pointIdMap, polygonArr, polygonIdMap, boundarySurfaceTypeArr);
}
private class CppGeometryData {
private double[] pointArr;
private int[] pointIdMap;
private int[] polygonArr;
private int[] polygonIdMap;
private int[] boundarySurfaceTypeArr;
private CppGeometryData(double[] pointArr, int[] pointIdMap, int[] polygonArr, int[] polygonIdMap,
int[] bfTypeArr) {
this.pointArr = pointArr;
this.pointIdMap = pointIdMap;
this.polygonArr = polygonArr;
this.polygonIdMap = polygonIdMap;
this.boundarySurfaceTypeArr = bfTypeArr;
}
}
public String getType() {
return type;
}
}
package de.hft.stuttgart.citydoctor2.connect.edge;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import de.hft.stuttgart.citydoctor2.datastructure.ConcretePolygon;
import de.hft.stuttgart.citydoctor2.datastructure.Geometry;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing;
import de.hft.stuttgart.citydoctor2.datastructure.LinearRing.LinearRingType;
import de.hft.stuttgart.citydoctor2.datastructure.Polygon;
import de.hft.stuttgart.citydoctor2.datastructure.Vertex;
public class CppHealResult extends CppReferenceHandlingBase {
private native void delete(long ptr);
private native int[] getChangedOrAddedVertexIds(long ptr);
private native double[] getChangedOrAddedVertexValues(long ptr);
private native int[] getChangedOrAddedPolygonIds(long ptr);
private native int[] getChangedOrAddedPolygon(long ptr, int id);
public CppHealResult(long ptr) {
ptrToCppObject = ptr;
}
@Override
public void disposeCppObject() {
if (ptrToCppObject != 0) {
delete(ptrToCppObject);
ptrToCppObject = 0;
}
}
public void mergeIntoGeometry(Geometry geom) {
Map<Integer, Vertex> vertexMap = updateVertices(geom);
int[] changedPolygons = getChangedOrAddedPolygonIds(ptrToCppObject);
List<Polygon> deletedPolygons = new ArrayList<>();
for (int i = 0; i < changedPolygons.length; i++) {
int polyId = changedPolygons[i];
int[] vertices = getChangedOrAddedPolygon(ptrToCppObject, polyId);
if (vertices == null || vertices.length == 0) {
if (polyId >= geom.getPolygons().size()) {
throw new IllegalStateException("Cannot delete a polygon which does not exist");
}
Polygon p = geom.getPolygons().get(polyId);
deletedPolygons.add(p);
} else {
Polygon p;
if (polyId < geom.getPolygons().size()) {
p = geom.getPolygons().get(polyId);
// empty the polygon
p.removeRings();
} else {
p = new ConcretePolygon();
geom.addPolygon(p);
}
createPolygon(geom, vertexMap, vertices, p);
}
}
for (Polygon p : deletedPolygons) {
geom.getPolygons().remove(p);
}
}
private void createPolygon(Geometry geom, Map<Integer, Vertex> vertexMap, int[] vertices, Polygon p) {
LinearRing lr = null;
for (int j = 0; j < vertices.length; j++) {
if (vertices[j] == -1) {
if (p.getExteriorRing() != null) {
throw new IllegalStateException("Cannot create a polygon with more than 1 exterior rings");
}
lr = new LinearRing(LinearRingType.EXTERIOR);
p.setExteriorRing(lr);
} else if (vertices[j] == -2) {
lr = new LinearRing(LinearRingType.INTERIOR);
p.addInteriorRing(lr);
} else {
Objects.requireNonNull(lr, "No ring type specified, before supplying vertices");
int index = vertices[j];
Vertex v;
if (index < geom.getVertices().size()) {
v = geom.getVertices().get(index);
} else {
v = vertexMap.get(index);
}
Objects.requireNonNull(v, "Polygon references vertex, which does not exist");
lr.addVertex(v);
}
}
// close the rings
p.getExteriorRing().addVertex(p.getExteriorRing().getVertices().get(0));
for (LinearRing inner : p.getInnerRings()) {
inner.addVertex(inner.getVertices().get(0));
}
}
private Map<Integer, Vertex> updateVertices(Geometry geom) {
int[] changedVertices = getChangedOrAddedVertexIds(ptrToCppObject);
double[] changedVertexValues = getChangedOrAddedVertexValues(ptrToCppObject);
Map<Integer, Vertex> vertexMap = new HashMap<>();
for (int i = 0; i < changedVertices.length; i++) {
int id = changedVertices[i];
double x = changedVertexValues[i * 3 + 0];
double y = changedVertexValues[i * 3 + 1];
double z = changedVertexValues[i * 3 + 2];
if (id >= geom.getVertices().size()) {
// new vertex
Vertex newV = new Vertex(x, y, z);
vertexMap.put(id, newV);
System.out.println("New Vertex: " + newV);
} else {
// change vertex
Vertex changedV = geom.getVertices().get(id);
System.out.print("Changed Vertex from " + changedV + " to ");
changedV.setX(x);
changedV.setY(y);
changedV.setZ(z);
System.out.println(changedV);
}
}
return vertexMap;
}
public void print() {
int[] changedVertices = getChangedOrAddedVertexIds(ptrToCppObject);
System.out.println("Changed or added vertex ids: " + Arrays.toString(changedVertices));
double[] changedVertexValues = getChangedOrAddedVertexValues(ptrToCppObject);
if (changedVertices.length * 3 != changedVertexValues.length) {
throw new IllegalStateException("Number of indices and number of values do not match");
}
for (int i = 0; i < changedVertices.length; i++) {
System.out.println(String.format("Vertex %d = [%f, %f, %f]", changedVertices[i],
changedVertexValues[i * 3 + 0], changedVertexValues[i * 3 + 1], changedVertexValues[i * 3 + 2]));
}
System.out.println();
int[] changedPolygons = getChangedOrAddedPolygonIds(ptrToCppObject);
System.out.println("Changed or added polygon ids: " + Arrays.toString(changedPolygons));
for (int i = 0; i < changedPolygons.length; i++) {
int polyId = changedPolygons[i];
System.out.println("Polygon " + polyId + ":");
int[] vertices = getChangedOrAddedPolygon(ptrToCppObject, polyId);
if (vertices == null || vertices.length == 0) {
System.out.println("deleted");
} else {
for (int j = 0; j < vertices.length; j++) {
if (vertices[j] == -1) {
System.out.println("Exterior ring:");
} else if (vertices[j] == -2) {
System.out.println("Interior ring:");
} else {
System.out.println(vertices[j]);
}
}
}
}
}
public boolean isEmpty() {
int[] changedVertices = getChangedOrAddedVertexIds(ptrToCppObject);
int[] changedPolygons = getChangedOrAddedPolygonIds(ptrToCppObject);
if(changedVertices.length == 0 && changedPolygons.length == 0)
return true;
return false;
}
}
package de.hft.stuttgart.citydoctor2.connect.edge;
public abstract class CppHealing extends CppReferenceHandlingBase {
// Checks will operate on this VPDFeature
CppFeature feature;
public CppHealing(CppFeature feature) {
this.feature = feature;
}
public CppFeature getNestedFeature() {
return feature;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
//*************************************************************************************
// vorerst auskommentiert, da CppChecks nicht mehr verwendet wird
// @Override
// public boolean equals(Object obj)
// {
// if (obj instanceof CppChecks)
// {
// return (super.equals(obj) && (feature == ((CppChecks)obj).feature));
// }
// else
// {
// return super.equals(obj);
// }
// }
//**************************************************************************************
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
int hash = super.hashCode();
hash = hash * 19 + feature.hashCode() * 3;
return hash;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
StringBuffer sf = new StringBuffer();
sf.append(super.toString());
sf.append("Feature:\n\t");
sf.append(feature);
return sf.toString();
}
}
\ No newline at end of file
package de.hft.stuttgart.citydoctor2.connect.edge;
public enum CppHealingResultChangeType {
ADD, DELETE, CHANGE, REPLACE
}
package de.hft.stuttgart.citydoctor2.connect.edge;
public enum CppHealingResultType {
VERTEX, POLYGON, EDGE
}
package de.hft.stuttgart.citydoctor2.connect.edge;
// im alten CD:
//
public class CppPolygonHealing extends CppHealing {
// ----- native methods
// create and release stored C++ polygon check object
private native long createCppPolygonHealing(long ptrToCppFeature) throws OutOfMemoryError;
private native void disposeCppPolygonHealing(long ptrToCppFeature) throws NativePointerCastException;
// healing
private native long healPlanarity(long ptrToCppFeature, int[] polyIds)
throws NativeException, IllegalArgumentException;
private native long healSolidNotClosed(long ptrToCppFeature)
throws NativeException, IllegalArgumentException;
public CppPolygonHealing(CppFeature feature) {
super(feature);
}
/**
* Creates an C++ object to use the native solid check methods.
*
* @throws IllegalStateException Thrown if the encapsulated "long-Pointer" isn't
* 0
* @throws OutOfMemoryError If there is no more memory on the native side
*
* @see {@link disposeCppObject}
* @see de.hft.stuttgart.citydoctor.connect.edGe.CppReferenceHandlingBase#createCppObject()
*/
public void createCppObject() throws IllegalStateException, OutOfMemoryError {
if (0L != ptrToCppObject) {
throw new IllegalStateException("Can't create new C++ object, there is allready one!");
}
// Maybe an exception is thrown and there should be no crap in ptrToCppObject
long tmpPointer = createCppPolygonHealing(feature.ptrToCppObject);
ptrToCppObject = tmpPointer;
}
@Override
public void disposeCppObject() throws NativePointerCastException {
if (0L != ptrToCppObject) {
disposeCppPolygonHealing(this.ptrToCppObject);
ptrToCppObject = 0L;
}
}
public CppHealResult healPlanarity(int[] polyIds) throws NativeException, IllegalArgumentException {
checkNullPointer();
return new CppHealResult( healPlanarity( this.feature.ptrToCppObject, polyIds ));
}
public CppHealResult healSolidNotClosed() throws NativeException, IllegalArgumentException{
checkNullPointer();
return new CppHealResult( healSolidNotClosed( this.feature.ptrToCppObject ));
}
}
package de.hft.stuttgart.citydoctor2.connect.edge;
/**
* This class is part of the JNI interface which controls the access to the
* check- and heal kernel in native C++ code.<br>
* It's represent a base class for classes which encapsulates a C++ object.
* Therefor two abstract methods {@link createCppObject} and
* {@link disposeCppObject} are defined, to create and dispose a C++ object. All
* non-abstract subclasses are requested to implement at least the two native
* methods<br>
* <br>
* <code>
* native long create[MeaningfulName](long ptrToCppFeature);<br>
* native void dispose[MeaningfulName](long ptrToCppPolygonCheck);
* </code><br>
* <br>
*
* @author wewetzer
* @version 1.0
*
*/
public abstract class CppReferenceHandlingBase {
// This long holds the address of an C++ object
long ptrToCppObject = 0L;
/**
* This method frees the occupied memory of the created C++ object. The method
* should be called after the instance of an child class is nor longer needed,
* to avoid memory leaks.
*
* @see {@link createCppObject}
*/
public abstract void disposeCppObject();
/**
* Checks if the pointer to the corresponding C++ object is 0. In this case an
* exception is thrown. This method should be called at first in every method,
* that uses native methods!
*
* @throws IllegalArgumentException if the pointer to the corresponding C++
* object i 0
*/
public void checkNullPointer() {
if (0L == ptrToCppObject) {
throw new IllegalArgumentException("C++ object pointer is null");
}
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
CppReferenceHandlingBase other = (CppReferenceHandlingBase) obj;
return ptrToCppObject == other.ptrToCppObject;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#finalize()
*/
@Override
protected void finalize() throws Throwable {
if (0L != ptrToCppObject) {
disposeCppObject();
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (ptrToCppObject ^ (ptrToCppObject >>> 32));
return result;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return ("ptrToCppObject\n\t" + ptrToCppObject + "\n");
}
}
package de.hft.stuttgart.citydoctor2.connect.edge;
public class CppTestHeal {
private CppTestHeal() {
// only static usage
}
private static native long healGeometry(long ptrToCppFeature);
public static CppHealResult healGeometry(CppFeature feature) {
return new CppHealResult(healGeometry(feature.ptrToCppObject));
}
}
package de.hft.stuttgart.citydoctor2.connect.edge;
/**
* This class represents the parent class of all exceptions thrown by the native
* c++ library for the check- and healkernel for the project CityDoctor. An
* additionally sting field has been added to identify the thrown Exception, if
* not a specialized exception has been caught. This keeps the code clearly
* arranged, because most of the exception that will be thrown represents an
* severe error in C++, so there it doesn't makes sense to carry on with the
* java program
*
* @author wewetzer
* @version 1.0
*/
public abstract class NativeException extends RuntimeException {
private static final long serialVersionUID = 443321035265866910L;
String exceptionType = "not specified";
/**
* Standard constructor.
*/
public NativeException() {
super("Message not specified");
}
/**
* Constructs a NativeException with the given message an the given type
*
* @param message The message of the exception
*/
public NativeException(String message) {
super(message);
}
/**
* Returns the type of the exception
*
* @return The type of the exception
*/
public String getType() {
return exceptionType;
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment