use of org.bimserver.ObjectProviderProxy in project BIMserver by opensourceBIM.
the class GeometryRunner method run.
@Override
public void run() {
long start = System.nanoTime();
job.setStartNanos(start);
try {
HashMapVirtualObject next = objectProvider.next();
Query query = new Query("Double buffer query " + eClass.getName(), this.streamingGeometryGenerator.packageMetaData);
QueryPart queryPart = query.createQueryPart();
while (next != null) {
queryPart.addOid(next.getOid());
if (this.streamingGeometryGenerator.packageMetaData.getEClass("IfcProduct").isSuperTypeOf(next.eClass())) {
job.addObject(next.getOid(), next.eClass().getName());
}
next = objectProvider.next();
}
objectProvider = new QueryObjectProvider(databaseSession, this.streamingGeometryGenerator.bimServer, query, Collections.singleton(queryContext.getRoid()), this.streamingGeometryGenerator.packageMetaData);
StreamingSerializer ifcSerializer = ifcSerializerPlugin.createSerializer(new PluginConfiguration());
RenderEngine renderEngine = null;
byte[] bytes = null;
try {
final Set<HashMapVirtualObject> objects = new HashSet<>();
ObjectProviderProxy proxy = new ObjectProviderProxy(objectProvider, new ObjectListener() {
@Override
public void newObject(HashMapVirtualObject next) {
if (eClass.isSuperTypeOf(next.eClass())) {
if (next.eGet(GeometryRunner.this.streamingGeometryGenerator.representationFeature) != null) {
objects.add(next);
}
}
}
});
ifcSerializer.init(proxy, null, null, this.streamingGeometryGenerator.bimServer.getPluginManager(), this.streamingGeometryGenerator.packageMetaData);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
IOUtils.copy(ifcSerializer.getInputStream(), baos);
bytes = baos.toByteArray();
InputStream in = new ByteArrayInputStream(bytes);
Map<Integer, String> notFoundObjects = new HashMap<>();
Set<Range> reusableGeometryData = new HashSet<>();
Map<Long, Q> productToData = new HashMap<>();
try {
if (!objects.isEmpty()) {
renderEngine = renderEnginePool.borrowObject();
try (RenderEngineModel renderEngineModel = renderEngine.openModel(in, bytes.length)) {
renderEngineModel.setSettings(renderEngineSettings);
renderEngineModel.setFilter(renderEngineFilter);
try {
renderEngineModel.generateGeneralGeometry();
} catch (RenderEngineException e) {
if (e.getCause() instanceof java.io.EOFException) {
if (objects.isEmpty() || eClass.getName().equals("IfcAnnotation")) {
// SKIP
} else {
StreamingGeometryGenerator.LOGGER.error("Error in " + eClass.getName(), e);
}
}
}
OidConvertingSerializer oidConvertingSerializer = (OidConvertingSerializer) ifcSerializer;
Map<Long, Integer> oidToEid = oidConvertingSerializer.getOidToEid();
Map<Long, double[]> matrices = new HashMap<>();
for (HashMapVirtualObject ifcProduct : objects) {
if (!this.streamingGeometryGenerator.running) {
return;
}
if (ifcProduct.get("GlobalId").equals("1sZn$z_i91bPOCQJOkOibU")) {
System.out.println();
}
Integer expressId = oidToEid.get(ifcProduct.getOid());
try {
RenderEngineInstance renderEngineInstance = renderEngineModel.getInstanceFromExpressId(expressId);
RenderEngineGeometry geometry = renderEngineInstance.generateGeometry();
boolean translate = true;
if (geometry != null && geometry.getNrIndices() > 0) {
VirtualObject geometryInfo = new HashMapVirtualObject(queryContext, GeometryPackage.eINSTANCE.getGeometryInfo());
WrappedVirtualObject minBounds = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
WrappedVirtualObject maxBounds = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
minBounds.set("x", Double.POSITIVE_INFINITY);
minBounds.set("y", Double.POSITIVE_INFINITY);
minBounds.set("z", Double.POSITIVE_INFINITY);
maxBounds.set("x", -Double.POSITIVE_INFINITY);
maxBounds.set("y", -Double.POSITIVE_INFINITY);
maxBounds.set("z", -Double.POSITIVE_INFINITY);
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_MinBounds(), minBounds);
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_MaxBounds(), maxBounds);
WrappedVirtualObject minBoundsUntranslated = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
WrappedVirtualObject maxBoundsUntranslated = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
minBoundsUntranslated.set("x", Double.POSITIVE_INFINITY);
minBoundsUntranslated.set("y", Double.POSITIVE_INFINITY);
minBoundsUntranslated.set("z", Double.POSITIVE_INFINITY);
maxBoundsUntranslated.set("x", -Double.POSITIVE_INFINITY);
maxBoundsUntranslated.set("y", -Double.POSITIVE_INFINITY);
maxBoundsUntranslated.set("z", -Double.POSITIVE_INFINITY);
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_MinBoundsUntranslated(), minBoundsUntranslated);
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_MaxBoundsUntranslated(), maxBoundsUntranslated);
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_Area(), renderEngineInstance.getArea());
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_Volume(), renderEngineInstance.getVolume());
VirtualObject geometryData = new HashMapVirtualObject(queryContext, GeometryPackage.eINSTANCE.getGeometryData());
int[] indices = geometry.getIndices();
geometryData.setAttribute(GeometryPackage.eINSTANCE.getGeometryData_Indices(), GeometryUtils.intArrayToByteArray(indices));
float[] vertices = geometry.getVertices();
geometryData.setAttribute(GeometryPackage.eINSTANCE.getGeometryData_Vertices(), GeometryUtils.floatArrayToByteArray(vertices));
geometryData.setAttribute(GeometryPackage.eINSTANCE.getGeometryData_Normals(), GeometryUtils.floatArrayToByteArray(geometry.getNormals()));
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_PrimitiveCount(), indices.length / 3);
job.setTrianglesGenerated(indices.length / 3);
job.getReport().incrementTriangles(indices.length / 3);
Set<Color4f> usedColors = new HashSet<>();
if (geometry.getMaterialIndices() != null && geometry.getMaterialIndices().length > 0) {
boolean hasMaterial = false;
float[] vertex_colors = new float[vertices.length / 3 * 4];
for (int i = 0; i < geometry.getMaterialIndices().length; ++i) {
int c = geometry.getMaterialIndices()[i];
for (int j = 0; j < 3; ++j) {
int k = indices[i * 3 + j];
if (c > -1) {
hasMaterial = true;
Color4f color = new Color4f();
for (int l = 0; l < 4; ++l) {
float val = geometry.getMaterials()[4 * c + l];
vertex_colors[4 * k + l] = val;
color.set(l, val);
}
usedColors.add(color);
}
}
}
if (usedColors.size() == 1) {
WrappedVirtualObject color = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector4f());
Color4f firstColor = usedColors.iterator().next();
color.set("x", firstColor.getR());
color.set("y", firstColor.getG());
color.set("z", firstColor.getB());
color.set("w", firstColor.getA());
geometryData.setAttribute(GeometryPackage.eINSTANCE.getGeometryData_Color(), color);
hasMaterial = false;
}
if (hasMaterial) {
geometryData.setAttribute(GeometryPackage.eINSTANCE.getGeometryData_Materials(), GeometryUtils.floatArrayToByteArray(vertex_colors));
}
}
double[] productTranformationMatrix = new double[16];
if (translate && renderEngineInstance.getTransformationMatrix() != null) {
productTranformationMatrix = renderEngineInstance.getTransformationMatrix();
} else {
Matrix.setIdentityM(productTranformationMatrix, 0);
}
geometryInfo.setReference(GeometryPackage.eINSTANCE.getGeometryInfo_Data(), geometryData.getOid(), 0);
long size = this.streamingGeometryGenerator.getSize(geometryData);
for (int i = 0; i < indices.length; i++) {
this.streamingGeometryGenerator.processExtends(geometryInfo, productTranformationMatrix, vertices, indices[i] * 3, generateGeometryResult);
this.streamingGeometryGenerator.processExtendsUntranslated(geometryInfo, vertices, indices[i] * 3, generateGeometryResult);
}
double[] mibu = new double[] { (double) minBoundsUntranslated.eGet(GeometryPackage.eINSTANCE.getVector3f_X()), (double) minBoundsUntranslated.eGet(GeometryPackage.eINSTANCE.getVector3f_Y()), (double) minBoundsUntranslated.eGet(GeometryPackage.eINSTANCE.getVector3f_Z()), 1d };
double[] mabu = new double[] { (double) maxBoundsUntranslated.eGet(GeometryPackage.eINSTANCE.getVector3f_X()), (double) maxBoundsUntranslated.eGet(GeometryPackage.eINSTANCE.getVector3f_Y()), (double) maxBoundsUntranslated.eGet(GeometryPackage.eINSTANCE.getVector3f_Z()), 1d };
if (reuseGeometry) {
int hash = this.streamingGeometryGenerator.hash(geometryData);
float[] firstVertex = new float[] { vertices[indices[0]], vertices[indices[0] + 1], vertices[indices[0] + 2] };
float[] lastVertex = new float[] { vertices[indices[indices.length - 1] * 3], vertices[indices[indices.length - 1] * 3 + 1], vertices[indices[indices.length - 1] * 3 + 2] };
Range range = new Range(firstVertex, lastVertex);
if (this.streamingGeometryGenerator.hashes.containsKey(hash)) {
geometryInfo.setReference(GeometryPackage.eINSTANCE.getGeometryInfo_Data(), this.streamingGeometryGenerator.hashes.get(hash), 0);
this.streamingGeometryGenerator.bytesSavedByHash.addAndGet(size);
} else if (geometryReused) {
boolean found = false;
// }
if (!found) {
range.setGeometryDataOid(geometryData.getOid());
reusableGeometryData.add(range);
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_Area(), renderEngineInstance.getArea());
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_Volume(), renderEngineInstance.getVolume());
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_PrimitiveCount(), indices.length / 3);
productToData.put(ifcProduct.getOid(), new Q(geometryData.getOid(), renderEngineInstance.getArea(), renderEngineInstance.getVolume(), indices.length / 3, size, mibu, mabu));
geometryData.save();
}
} else {
// }
if (geometryReused) {
range.setGeometryDataOid(geometryData.getOid());
reusableGeometryData.add(range);
productToData.put(ifcProduct.getOid(), new Q(geometryData.getOid(), renderEngineInstance.getArea(), renderEngineInstance.getVolume(), indices.length / 3, size, mibu, mabu));
}
this.streamingGeometryGenerator.hashes.put(hash, geometryData.getOid());
geometryData.save();
// sizes.put(size, ifcProduct);
}
} else {
geometryData.save();
}
calculateObb(geometryInfo, productTranformationMatrix, indices, vertices, generateGeometryResult);
this.streamingGeometryGenerator.setTransformationMatrix(geometryInfo, productTranformationMatrix);
matrices.put(ifcProduct.getOid(), productTranformationMatrix);
geometryInfo.save();
this.streamingGeometryGenerator.totalBytes.addAndGet(size);
ifcProduct.setReference(this.streamingGeometryGenerator.geometryFeature, geometryInfo.getOid(), 0);
ifcProduct.saveOverwrite();
// Doing a sync here because probably
// writing large amounts of data, and db
// only syncs every 100.000 writes by
// default
// databaseSession.getKeyValueStore().sync();
} else {
// TODO
}
} catch (EntityNotFoundException e) {
// e.printStackTrace();
// As soon as we find a representation that
// is not Curve2D, then we should show a
// "INFO" message in the log to indicate
// there could be something wrong
boolean ignoreNotFound = eClass.getName().equals("IfcAnnotation");
// }
if (!ignoreNotFound) {
// LOGGER.warn("Entity not found " +
// ifcProduct.eClass().getName() + " " +
// (expressId) + "/" +
// ifcProduct.getOid());
notFoundObjects.put(expressId, ifcProduct.eClass().getName());
}
} catch (BimserverDatabaseException | RenderEngineException e) {
StreamingGeometryGenerator.LOGGER.error("", e);
}
}
if (geometryReused && map != null) {
long firstKey = map.keySet().iterator().next();
ProductDef masterProductDef = map.get(firstKey);
for (long key : map.keySet()) {
if (key != firstKey) {
ProductDef productDef = map.get(key);
HashMapVirtualObject ifcProduct = productDef.getObject();
Q q = productToData.get(productDef.getMasterOid());
if (q != null) {
VirtualObject geometryInfo = new HashMapVirtualObject(queryContext, GeometryPackage.eINSTANCE.getGeometryInfo());
WrappedVirtualObject minBounds = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
WrappedVirtualObject maxBounds = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
double[] mibu = q.getMibu();
double[] mabu = q.getMibu();
double[] mibt = new double[4];
double[] mabt = new double[4];
// TODO
Matrix.multiplyMV(mibt, 0, productDef.getProductMatrix(), 0, mibu, 0);
Matrix.multiplyMV(mabt, 0, productDef.getProductMatrix(), 0, mabu, 0);
minBounds.set("x", mibt[0]);
minBounds.set("y", mibt[1]);
minBounds.set("z", mibt[2]);
maxBounds.set("x", mabt[0]);
maxBounds.set("y", mabt[1]);
maxBounds.set("z", mabt[2]);
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_MinBounds(), minBounds);
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_MaxBounds(), maxBounds);
WrappedVirtualObject minBoundsUntranslated = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
WrappedVirtualObject maxBoundsUntranslated = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
minBoundsUntranslated.set("x", mibu[0]);
minBoundsUntranslated.set("y", mibu[1]);
minBoundsUntranslated.set("z", mibu[2]);
maxBoundsUntranslated.set("x", mabu[0]);
maxBoundsUntranslated.set("y", mabu[1]);
maxBoundsUntranslated.set("z", mabu[2]);
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_MinBoundsUntranslated(), minBoundsUntranslated);
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_MaxBoundsUntranslated(), maxBoundsUntranslated);
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_Area(), q.getArea());
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_Volume(), q.getVolume());
geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_PrimitiveCount(), q.getNrPrimitives());
this.streamingGeometryGenerator.bytesSavedByMapping.addAndGet(q.getSize());
this.streamingGeometryGenerator.totalBytes.addAndGet(q.getSize());
double[] inverted = Matrix.identity();
if (!Matrix.invertM(inverted, 0, masterProductDef.getMappingMatrix(), 0)) {
System.out.println("No inverse");
}
double[] finalMatrix = Matrix.identity();
double[] totalTranformationMatrix = Matrix.identity();
Matrix.multiplyMM(finalMatrix, 0, productDef.getMappingMatrix(), 0, inverted, 0);
Matrix.multiplyMM(totalTranformationMatrix, 0, productDef.getProductMatrix(), 0, finalMatrix, 0);
if (matrices.containsKey(ifcProduct.getOid())) {
if (!Arrays.equals(matrices.get(ifcProduct.getOid()), totalTranformationMatrix)) {
System.out.println("Not the same " + ifcProduct.get("GlobalId"));
Matrix.dump(matrices.get(ifcProduct.getOid()));
System.out.println();
Matrix.dump(totalTranformationMatrix);
}
}
geometryInfo.setReference(GeometryPackage.eINSTANCE.getGeometryInfo_Data(), q.getOid(), 0);
// for (int i = 0; i <
// indices.length; i++) {
// processExtends(geometryInfo,
// productTranformationMatrix,
// vertices, indices[i] * 3,
// generateGeometryResult);
// processExtendsUntranslated(geometryInfo,
// vertices, indices[i] * 3,
// generateGeometryResult);
// }
// calculateObb(geometryInfo,
// productTranformationMatrix,
// indices, vertices,
// generateGeometryResult);
this.streamingGeometryGenerator.setTransformationMatrix(geometryInfo, totalTranformationMatrix);
geometryInfo.save();
// totalBytes.addAndGet(size);
ifcProduct.setReference(this.streamingGeometryGenerator.geometryFeature, geometryInfo.getOid(), 0);
ifcProduct.saveOverwrite();
}
}
}
}
}
}
} finally {
if (renderEngine != null) {
renderEnginePool.returnObject(renderEngine);
}
try {
if (!notFoundObjects.isEmpty()) {
int debugId = writeDebugFile(bytes, false, notFoundObjects);
job.setException(new Exception("Missing objects in model (" + Joiner.on(", ").join(notFoundObjects.keySet()) + ")"), debugId);
} else if (writeOutputFiles) {
int debugId = writeDebugFile(bytes, false, null);
job.setDebugFile(debugId);
}
in.close();
} catch (Throwable e) {
} finally {
}
this.streamingGeometryGenerator.jobsDone.incrementAndGet();
this.streamingGeometryGenerator.updateProgress();
}
} catch (Exception e) {
StreamingGeometryGenerator.LOGGER.error("", e);
int debugId = writeDebugFile(bytes, true, null);
job.setException(e, debugId);
// LOGGER.error("Original query: " + originalQuery, e);
}
} catch (Exception e) {
StreamingGeometryGenerator.LOGGER.error("", e);
// LOGGER.error("Original query: " + originalQuery, e);
}
long end = System.nanoTime();
job.setEndNanos(end);
}
Aggregations