Search in sources :

Example 26 with QueryPart

use of org.bimserver.database.queries.om.QueryPart in project BIMserver by opensourceBIM.

the class GeometryRunner method run.

@Override
public void run() {
    Thread.currentThread().setName("GeometryRunner");
    long start = System.nanoTime();
    job.setStartNanos(start);
    // For all objects "hitchhiking" on this GeometryRunner, we also want to couple them to the job
    if (map != null) {
        for (long oid : map.keySet()) {
            if (map.get(oid).getMasterOid() != oid) {
                try {
                    job.addObject(oid, databaseSession.getEClassForOid(oid).getName());
                } catch (BimserverDatabaseException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    try {
        HashMapVirtualObject next = objectProvider.next();
        Query query = new Query("Double buffer query " + eClass.getName(), this.streamingGeometryGenerator.packageMetaData);
        QueryPart queryPart = query.createQueryPart();
        while (next != null) {
            long oid = next.getOid();
            queryPart.addOid(oid);
            if (eClass.isSuperTypeOf(next.eClass())) {
                for (QueryPart qp : originalQuery.getQueryParts()) {
                    if (qp.getOids().contains(oid)) {
                        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 serializer = ifcSerializerPlugin.createSerializer(new PluginConfiguration());
        RenderEngine renderEngine = null;
        byte[] bytes = null;
        try {
            final Set<HashMapVirtualObject> objects = new LinkedHashSet<>();
            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) {
                            for (QueryPart qp : originalQuery.getQueryParts()) {
                                if (qp.getOids().contains(next.getOid())) {
                                    objects.add(next);
                                }
                            }
                        }
                    }
                }
            });
            serializer.init(proxy, null, null, this.streamingGeometryGenerator.bimServer.getPluginManager(), this.streamingGeometryGenerator.packageMetaData);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            IOUtils.copy(serializer.getInputStream(), baos);
            bytes = baos.toByteArray();
            InputStream in = new ByteArrayInputStream(bytes);
            Map<Long, HashMapVirtualObject> notFoundObjects = new HashMap<>();
            Set<Range> reusableGeometryData = new HashSet<>();
            Map<Long, TemporaryGeometryData> 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) serializer;
                        Map<Long, Long> oidToEid = oidConvertingSerializer.getOidToEid();
                        Map<Long, DebuggingInfo> debuggingInfo = new HashMap<>();
                        for (HashMapVirtualObject ifcProduct : objects) {
                            if (!this.streamingGeometryGenerator.running) {
                                return;
                            }
                            Long expressId = oidToEid.get(ifcProduct.getOid());
                            try {
                                RenderEngineInstance renderEngineInstance = renderEngineModel.getInstanceFromExpressId(expressId);
                                RenderEngineGeometry geometry = renderEngineInstance.generateGeometry();
                                boolean translate = true;
                                if (geometry != null && geometry.getNrIndices() > 0) {
                                    HashMapVirtualObject geometryInfo = new HashMapVirtualObject(queryContext, GeometryPackage.eINSTANCE.getGeometryInfo());
                                    HashMapWrappedVirtualObject bounds = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getBounds());
                                    HashMapWrappedVirtualObject minBounds = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
                                    HashMapWrappedVirtualObject 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_IfcProductOid(), ifcProduct.getOid());
                                    geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_IfcProductUuid(), UuidUtils.toByteArray(ifcProduct.getUuid()));
                                    geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_IfcProductRid(), ifcProduct.getRid());
                                    geometryInfo.setReference(GeometryPackage.eINSTANCE.getGeometryInfo_Bounds(), bounds);
                                    bounds.setReference(GeometryPackage.eINSTANCE.getBounds_Min(), minBounds);
                                    bounds.setReference(GeometryPackage.eINSTANCE.getBounds_Max(), maxBounds);
                                    HashMapWrappedVirtualObject boundsUntransformed = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getBounds());
                                    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);
                                    boundsUntransformed.setReference(GeometryPackage.eINSTANCE.getBounds_Min(), minBoundsUntranslated);
                                    boundsUntransformed.setReference(GeometryPackage.eINSTANCE.getBounds_Max(), maxBoundsUntranslated);
                                    geometryInfo.setReference(GeometryPackage.eINSTANCE.getGeometryInfo_BoundsUntransformed(), boundsUntransformed);
                                    double volume = 0;
                                    volume = setCalculatedQuantities(renderEngineInstance, geometryInfo, volume);
                                    HashMapVirtualObject geometryData = new HashMapVirtualObject(queryContext, GeometryPackage.eINSTANCE.getGeometryData());
                                    geometryData.set("type", databaseSession.getCid(eClass));
                                    ByteBuffer indices = geometry.getIndices();
                                    ByteBuffer vertices = geometry.getVertices();
                                    ByteBuffer normals = geometry.getNormals();
                                    ByteBuffer colorByteBuffer = geometry.getMaterialIndices();
                                    IntBuffer indicesAsInt = indices.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
                                    DoubleBuffer verticesAsDouble = vertices.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer();
                                    FloatBuffer normalsAsFloat = normals.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
                                    IntBuffer materialIndices = colorByteBuffer.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
                                    if (detectTwoFaceTriangles(ifcProduct, indicesAsInt, verticesAsDouble, 0.001f)) {
                                        BufferSet bufferSet = appendInvertedGeometry(indicesAsInt, verticesAsDouble, normalsAsFloat, materialIndices);
                                        indices = bufferSet.getIndicesByteBuffer();
                                        vertices = bufferSet.getVerticesByteBuffer();
                                        normals = bufferSet.getNormalsByteBuffer();
                                        colorByteBuffer = bufferSet.getColorsByteBuffer();
                                        indicesAsInt = indices.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
                                        verticesAsDouble = vertices.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer();
                                        normalsAsFloat = normals.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
                                        materialIndices = colorByteBuffer.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
                                    }
                                    geometryData.setAttribute(GeometryPackage.eINSTANCE.getGeometryData_Reused(), 1);
                                    geometryData.setReference(GeometryPackage.eINSTANCE.getGeometryData_Indices(), createBuffer(queryContext, indices));
                                    geometryData.setReference(GeometryPackage.eINSTANCE.getGeometryData_Vertices(), createBuffer(queryContext, vertices));
                                    geometryData.setReference(GeometryPackage.eINSTANCE.getGeometryData_Normals(), createBuffer(queryContext, normals));
                                    geometryData.set("nrIndices", indicesAsInt.capacity());
                                    geometryData.set("nrVertices", verticesAsDouble.capacity());
                                    geometryData.set("nrNormals", normalsAsFloat.capacity());
                                    ByteBuffer lineIndices = generateLineRendering(ifcProduct, indicesAsInt, verticesAsDouble, normalsAsFloat, 0.001f);
                                    geometryData.set("nrLineIndices", lineIndices.capacity() / 4);
                                    geometryData.setReference(GeometryPackage.eINSTANCE.getGeometryData_LineIndices(), createBuffer(queryContext, lineIndices));
                                    geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_PrimitiveCount(), indicesAsInt.capacity() / 3);
                                    job.setTrianglesGenerated(indicesAsInt.capacity() / 3);
                                    job.getReport().incrementTriangles(indicesAsInt.capacity() / 3);
                                    streamingGeometryGenerator.cacheGeometryData(geometryData, vertices);
                                    ColorMap colorMap = new ColorMap();
                                    ByteBuffer colors = ByteBuffer.wrap(new byte[0]);
                                    if (materialIndices != null && materialIndices.capacity() > 0) {
                                        FloatBuffer materialsAsFloat = geometry.getMaterials().order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
                                        boolean hasMaterial = false;
                                        colors = ByteBuffer.allocate((verticesAsDouble.capacity() / 3) * 4);
                                        double[] triangle = new double[9];
                                        for (int i = 0; i < materialIndices.capacity(); ++i) {
                                            int c = materialIndices.get(i);
                                            if (c > -1) {
                                                Color4f color = new Color4f();
                                                for (int l = 0; l < 4; ++l) {
                                                    float val = fixColor(materialsAsFloat.get(4 * c + l));
                                                    color.set(l, val);
                                                }
                                                if (color.isBlack()) {
                                                    continue;
                                                }
                                                for (int j = 0; j < 3; ++j) {
                                                    int k = indicesAsInt.get(i * 3 + j);
                                                    triangle[j * 3 + 0] = verticesAsDouble.get(3 * k);
                                                    triangle[j * 3 + 1] = verticesAsDouble.get(3 * k + 1);
                                                    triangle[j * 3 + 2] = verticesAsDouble.get(3 * k + 2);
                                                    hasMaterial = true;
                                                    for (int l = 0; l < 4; ++l) {
                                                        float val = fixColor(materialsAsFloat.get(4 * c + l));
                                                        colors.put(4 * k + l, UnsignedBytes.checkedCast((int) (val * 255)));
                                                    }
                                                }
                                                colorMap.addTriangle(triangle, color);
                                            }
                                        }
                                        if (hasMaterial) {
                                            ColorMap2 colorMap2 = new ColorMap2();
                                            byte[] colorB = new byte[4];
                                            for (int i = 0; i < colors.capacity(); i += 4) {
                                                colors.get(colorB);
                                                colorMap2.addColor(colorB);
                                            }
                                            HashMapVirtualObject colorPack = new HashMapVirtualObject(queryContext, GeometryPackage.eINSTANCE.getColorPack());
                                            colorPack.setAttribute(GeometryPackage.eINSTANCE.getColorPack_Data(), colorMap2.toByteArray());
                                            colorPack.save();
                                            geometryData.setReference(GeometryPackage.eINSTANCE.getGeometryData_ColorPack(), colorPack.getOid(), 0);
                                        }
                                        if (colorMap.usedColors() == 0) {
                                            if (eClass.getName().contentEquals("IfcWindow") || eClass.getName().contentEquals("IfcOpeningElement") || eClass.getName().contentEquals("IfcSpace")) {
                                                // To make sure the viewer will but this object in the right buffer (transparent), we override the transparency here
                                                // This only happens for objects with no color, maybe there are more types that are usually transparent?
                                                colorMap.setHasTransparency(true);
                                            // } else {
                                            // LOGGER.info(ifcProduct.eClass().getName());
                                            }
                                        } else if (colorMap.usedColors() == 1) {
                                            WrappedVirtualObject color = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector4f());
                                            Color4f firstColor = colorMap.getFirstColor();
                                            color.set("x", firstColor.getR());
                                            color.set("y", firstColor.getG());
                                            color.set("z", firstColor.getB());
                                            color.set("w", firstColor.getA());
                                            geometryData.setReference(GeometryPackage.eINSTANCE.getGeometryData_Color(), color);
                                            // This tells the code further on to not store this geometry, as it can be easily generated
                                            hasMaterial = false;
                                        } else {
                                            Color4f mostUsed = colorMap.getMostUsedColor();
                                            WrappedVirtualObject color = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector4f());
                                            color.set("x", mostUsed.getR());
                                            color.set("y", mostUsed.getG());
                                            color.set("z", mostUsed.getB());
                                            color.set("w", mostUsed.getA());
                                            geometryData.setReference(GeometryPackage.eINSTANCE.getGeometryData_MostUsedColor(), color);
                                        }
                                        if (hasMaterial) {
                                            geometryData.set("nrColors", colors.capacity());
                                            geometryData.setReference(GeometryPackage.eINSTANCE.getGeometryData_ColorsQuantized(), createBuffer(queryContext, colors), -1);
                                        } else {
                                            geometryData.set("nrColors", 0);
                                        }
                                    } else {
                                        geometryData.set("nrColors", 0);
                                    }
                                    boolean hasTransparency = colorMap.hasTransparency();
                                    double[] productTranformationMatrix = new double[16];
                                    if (translate && renderEngineInstance.getTransformationMatrix() != null) {
                                        productTranformationMatrix = renderEngineInstance.getTransformationMatrix();
                                    } else {
                                        Matrix.setIdentityM(productTranformationMatrix, 0);
                                    }
                                    geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_NrColors(), colors.capacity());
                                    geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_NrVertices(), verticesAsDouble.capacity());
                                    geometryInfo.setReference(GeometryPackage.eINSTANCE.getGeometryInfo_Data(), geometryData.getOid(), 0);
                                    geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_HasTransparency(), hasTransparency);
                                    geometryData.setAttribute(GeometryPackage.eINSTANCE.getGeometryData_HasTransparency(), hasTransparency);
                                    long size = this.streamingGeometryGenerator.getSize(geometryData);
                                    for (int i = 0; i < indicesAsInt.capacity(); i++) {
                                        this.streamingGeometryGenerator.processExtends(minBounds, maxBounds, productTranformationMatrix, verticesAsDouble, indicesAsInt.get(i) * 3, generateGeometryResult);
                                        this.streamingGeometryGenerator.processExtendsUntranslated(geometryInfo, verticesAsDouble, indicesAsInt.get(i) * 3, generateGeometryResult);
                                    }
                                    HashMapWrappedVirtualObject boundsUntransformedMm = createMmBounds(geometryInfo, boundsUntransformed, generateGeometryResult.getMultiplierToMm());
                                    geometryInfo.set("boundsUntransformedMm", boundsUntransformedMm);
                                    HashMapWrappedVirtualObject boundsMm = createMmBounds(geometryInfo, bounds, generateGeometryResult.getMultiplierToMm());
                                    geometryInfo.set("boundsMm", boundsMm);
                                    ByteBuffer normalsQuantized = quantizeNormals(normalsAsFloat);
                                    geometryData.setReference(GeometryPackage.eINSTANCE.getGeometryData_NormalsQuantized(), createBuffer(queryContext, normalsQuantized));
                                    HashMapWrappedVirtualObject geometryDataBounds = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getBounds());
                                    WrappedVirtualObject geometryDataBoundsMin = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
                                    WrappedVirtualObject geometryDataBoundsMax = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
                                    geometryDataBoundsMin.set("x", ((HashMapWrappedVirtualObject) boundsMm.get("min")).get("x"));
                                    geometryDataBoundsMin.set("y", ((HashMapWrappedVirtualObject) boundsMm.get("min")).get("y"));
                                    geometryDataBoundsMin.set("z", ((HashMapWrappedVirtualObject) boundsMm.get("min")).get("z"));
                                    geometryDataBoundsMax.set("x", ((HashMapWrappedVirtualObject) boundsMm.get("max")).get("x"));
                                    geometryDataBoundsMax.set("y", ((HashMapWrappedVirtualObject) boundsMm.get("max")).get("y"));
                                    geometryDataBoundsMax.set("z", ((HashMapWrappedVirtualObject) boundsMm.get("max")).get("z"));
                                    geometryDataBounds.setReference(GeometryPackage.eINSTANCE.getBounds_Min(), geometryDataBoundsMin);
                                    geometryDataBounds.setReference(GeometryPackage.eINSTANCE.getBounds_Max(), geometryDataBoundsMax);
                                    geometryData.setReference(GeometryPackage.eINSTANCE.getGeometryData_BoundsMm(), geometryDataBounds);
                                    if (volume == 0) {
                                        volume = getVolumeFromBounds(boundsUntransformed);
                                    }
                                    float nrTriangles = indicesAsInt.capacity() / 3;
                                    Density density = new Density(eClass.getName(), (float) volume, getBiggestFaceFromBounds(boundsUntransformedMm), (long) nrTriangles, geometryInfo.getOid());
                                    geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_Density(), density.getDensityValue());
                                    generateGeometryResult.addDensity(density);
                                    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) {
                                        /* TODO It still happens that geometry that should be reused is not reused, one of the reasons is still concurrency:
											 * 	- When the same geometry is processed concurrently they could both do the hash check at a time when there is no cached version, then they both think it's non-reused geometry
											*/
                                        int hash = this.streamingGeometryGenerator.hash(indices, vertices, normals, colors);
                                        int firstIndex = indicesAsInt.get(0);
                                        int lastIndex = indicesAsInt.get(indicesAsInt.capacity() - 1);
                                        double[] firstVertex = new double[] { verticesAsDouble.get(firstIndex), verticesAsDouble.get(firstIndex + 1), verticesAsDouble.get(firstIndex + 2) };
                                        double[] lastVertex = new double[] { verticesAsDouble.get(lastIndex * 3), verticesAsDouble.get(lastIndex * 3 + 1), verticesAsDouble.get(lastIndex * 3 + 2) };
                                        Range range = new Range(firstVertex, lastVertex);
                                        Long referenceOid = this.streamingGeometryGenerator.hashes.get(hash);
                                        if (referenceOid != null) {
                                            HashMapVirtualObject referencedData = databaseSession.getFromCache(referenceOid);
                                            if (referencedData == null) {
                                                LOGGER.error("Object not found in cache: " + referenceOid + " (hash: " + hash + ")");
                                            }
                                            synchronized (referencedData) {
                                                Integer currentValue = (Integer) referencedData.get("reused");
                                                referencedData.set("reused", currentValue + 1);
                                            }
                                            HashMapWrappedVirtualObject dataBounds = (HashMapWrappedVirtualObject) referencedData.get("boundsMm");
                                            extendBounds(boundsMm, dataBounds);
                                            referencedData.saveOverwrite();
                                            geometryInfo.setReference(GeometryPackage.eINSTANCE.getGeometryInfo_Data(), referenceOid, 0);
                                            this.streamingGeometryGenerator.bytesSavedByHash.addAndGet(size);
                                        } else if (geometryReused) {
                                            // This is true when this geometry is part of a mapped item mapping (and used more than once)
                                            boolean found = false;
                                            // }
                                            if (!found) {
                                                range.setGeometryDataOid(geometryData.getOid());
                                                reusableGeometryData.add(range);
                                                volume = setCalculatedQuantities(renderEngineInstance, geometryInfo, volume);
                                                geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_PrimitiveCount(), indicesAsInt.capacity() / 3);
                                                productToData.put(ifcProduct.getOid(), new TemporaryGeometryData(geometryData.getOid(), renderEngineInstance.getAdditionalData(), indicesAsInt.capacity() / 3, size, mibu, mabu, indicesAsInt, verticesAsDouble, hasTransparency, colors.capacity()));
                                                geometryData.save();
                                                databaseSession.cache((HashMapVirtualObject) geometryData);
                                            }
                                        } else {
                                            // if (sizes.containsKey(size)
                                            // && sizes.get(size).eClass()
                                            // == ifcProduct.eClass()) {
                                            // LOGGER.info("More reuse might
                                            // be possible " + size + " " +
                                            // ifcProduct.eClass().getName()
                                            // + ":" + ifcProduct.getOid() +
                                            // " / " +
                                            // sizes.get(size).eClass().getName()
                                            // + ":" +
                                            // sizes.get(size).getOid());
                                            // }
                                            // if (geometryReused) {
                                            // range.setGeometryDataOid(geometryData.getOid());
                                            // reusableGeometryData.add(range);
                                            // productToData.put(ifcProduct.getOid(), new TemporaryGeometryData(geometryData.getOid(), renderEngineInstance.getArea(), renderEngineInstance.getVolume(), indices.length / 3, size, mibu, mabu, indices, vertices));
                                            // } // TODO else??
                                            // So reuse is on, the data was not found by hash, and this item is not in a mapped item
                                            // By saving it before putting it in the cache/hashmap, we make sure we won't get a BimserverConcurrentModificationException
                                            // TODO Why??
                                            geometryData.save();
                                            databaseSession.cache((HashMapVirtualObject) geometryData);
                                            this.streamingGeometryGenerator.hashes.put(hash, geometryData.getOid());
                                        // sizes.put(size, ifcProduct);
                                        }
                                    } else {
                                        geometryData.save();
                                        databaseSession.cache((HashMapVirtualObject) geometryData);
                                    }
                                    this.streamingGeometryGenerator.setTransformationMatrix(geometryInfo, productTranformationMatrix);
                                    debuggingInfo.put(ifcProduct.getOid(), new DebuggingInfo(productTranformationMatrix, indices.asIntBuffer(), vertices.asFloatBuffer()));
                                    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);
                                }
                            } catch (BimserverDatabaseException | RenderEngineException e) {
                                StreamingGeometryGenerator.LOGGER.error("", e);
                            }
                        }
                        if (geometryReused && map != null) {
                            // We pick the first product and use that product to try and get the original data
                            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();
                                    TemporaryGeometryData masterGeometryData = productToData.get(productDef.getMasterOid());
                                    if (masterGeometryData != null) {
                                        HashMapVirtualObject geometryInfo = new HashMapVirtualObject(queryContext, GeometryPackage.eINSTANCE.getGeometryInfo());
                                        HashMapWrappedVirtualObject bounds = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getBounds());
                                        HashMapWrappedVirtualObject minBounds = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
                                        HashMapWrappedVirtualObject maxBounds = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
                                        geometryInfo.setReference(GeometryPackage.eINSTANCE.getGeometryInfo_Bounds(), bounds);
                                        geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_HasTransparency(), masterGeometryData.hasTransparancy());
                                        geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_NrColors(), masterGeometryData.getNrColors());
                                        geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_NrVertices(), masterGeometryData.getNrVertices());
                                        bounds.set("min", minBounds);
                                        bounds.set("max", maxBounds);
                                        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);
                                        double[] mibu = masterGeometryData.getMibu();
                                        double[] mabu = masterGeometryData.getMabu();
                                        HashMapWrappedVirtualObject boundsUntransformed = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getBounds());
                                        WrappedVirtualObject minBoundsUntransformed = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
                                        WrappedVirtualObject maxBoundsUntransformed = new HashMapWrappedVirtualObject(GeometryPackage.eINSTANCE.getVector3f());
                                        minBoundsUntransformed.set("x", mibu[0]);
                                        minBoundsUntransformed.set("y", mibu[1]);
                                        minBoundsUntransformed.set("z", mibu[2]);
                                        maxBoundsUntransformed.set("x", mabu[0]);
                                        maxBoundsUntransformed.set("y", mabu[1]);
                                        maxBoundsUntransformed.set("z", mabu[2]);
                                        geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_IfcProductOid(), ifcProduct.getOid());
                                        geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_IfcProductUuid(), UuidUtils.toByteArray(ifcProduct.getUuid()));
                                        geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_IfcProductRid(), ifcProduct.getRid());
                                        boundsUntransformed.setReference(GeometryPackage.eINSTANCE.getBounds_Min(), minBoundsUntransformed);
                                        boundsUntransformed.setReference(GeometryPackage.eINSTANCE.getBounds_Max(), maxBoundsUntransformed);
                                        geometryInfo.setReference(GeometryPackage.eINSTANCE.getGeometryInfo_BoundsUntransformed(), boundsUntransformed);
                                        double volume = 0;
                                        if (streamingGeometryGenerator.isCalculateQuantities()) {
                                            ObjectNode additionalData = masterGeometryData.getAdditionalData();
                                            if (additionalData != null) {
                                                geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_AdditionalData(), additionalData.toString());
                                                if (additionalData.has("TOTAL_SURFACE_AREA")) {
                                                    geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_Area(), additionalData.get("TOTAL_SURFACE_AREA").asDouble());
                                                }
                                                if (additionalData.has("TOTAL_SHAPE_VOLUME")) {
                                                    volume = additionalData.get("TOTAL_SHAPE_VOLUME").asDouble();
                                                    geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_Volume(), volume);
                                                }
                                            }
                                        }
                                        geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_PrimitiveCount(), masterGeometryData.getNrPrimitives());
                                        job.getReport().incrementTriangles(masterGeometryData.getNrPrimitives());
                                        this.streamingGeometryGenerator.bytesSavedByMapping.addAndGet(masterGeometryData.getSize());
                                        this.streamingGeometryGenerator.totalBytes.addAndGet(masterGeometryData.getSize());
                                        // First, invert the master's mapping matrix
                                        double[] inverted = Matrix.identity();
                                        if (!Matrix.invertM(inverted, 0, masterProductDef.getMappingMatrix(), 0)) {
                                            LOGGER.info("No inverse, this should not be able to happen at this time, please report");
                                            continue;
                                        }
                                        double[] finalMatrix = Matrix.identity();
                                        double[] totalTranformationMatrix = Matrix.identity();
                                        // Apply the mapping matrix of the product
                                        Matrix.multiplyMM(finalMatrix, 0, productDef.getMappingMatrix(), 0, inverted, 0);
                                        // Apply the product matrix of the product
                                        Matrix.multiplyMM(totalTranformationMatrix, 0, productDef.getProductMatrix(), 0, finalMatrix, 0);
                                        if (geometryGenerationDebugger != null) {
                                        // if (debuggingInfo.containsKey(ifcProduct.getOid())) {
                                        // DebuggingInfo debuggingInfo2 = debuggingInfo.get(ifcProduct.getOid());
                                        // DebuggingInfo debuggingInfo3 = debuggingInfo.get(productDef.getMasterOid());
                                        // 
                                        // if (debuggingInfo2.getIndices().length != debuggingInfo3.getIndices().length) {
                                        // LOGGER.error("Different sizes for indices, weird...");
                                        // LOGGER.error(ifcProduct.getOid() + " / " + productDef.getMasterOid());
                                        // } else {
                                        // for (int i=0; i<debuggingInfo2.getIndices().length; i++) {
                                        // int index = debuggingInfo2.getIndices()[i];
                                        // float[] vertex = new float[]{debuggingInfo2.getVertices()[index * 3], debuggingInfo2.getVertices()[index * 3 + 1], debuggingInfo2.getVertices()[index * 3 + 2], 1};
                                        // float[] transformedOriginal = new float[4];
                                        // Matrix.multiplyMV(transformedOriginal, 0, debuggingInfo2.getProductTranformationMatrix(), 0, vertex, 0);
                                        // float[] transformedNew = new float[4];
                                        // int index2 = debuggingInfo3.getIndices()[i];
                                        // float[] vertex2 = new float[]{debuggingInfo3.getVertices()[index2 * 3], debuggingInfo3.getVertices()[index2 * 3 + 1], debuggingInfo3.getVertices()[index2 * 3 + 2], 1};
                                        // Matrix.multiplyMV(transformedNew, 0, totalTranformationMatrix, 0, vertex2, 0);
                                        // 
                                        // // TODO margin should depend on bb of complete model
                                        // if (!almostTheSame((String)ifcProduct.get("GlobalId"), transformedNew, transformedOriginal, 0.05F)) {
                                        // geometryGenerationDebugger.transformedVertexNotMatching(ifcProduct, transformedOriginal, transformedNew, debuggingInfo2.getProductTranformationMatrix(), totalTranformationMatrix);
                                        // }
                                        // }
                                        // }
                                        // almostTheSame((String)ifcProduct.get("GlobalId"), debuggingInfo2.getProductTranformationMatrix(), totalTranformationMatrix, 0.01D);
                                        // }
                                        }
                                        IntBuffer indices = masterGeometryData.getIndices();
                                        for (int i = 0; i < indices.capacity(); i++) {
                                            this.streamingGeometryGenerator.processExtends(minBounds, maxBounds, totalTranformationMatrix, masterGeometryData.getVertices(), indices.get(i) * 3, generateGeometryResult);
                                        }
                                        HashMapWrappedVirtualObject boundsUntransformedMm = createMmBounds(geometryInfo, boundsUntransformed, generateGeometryResult.getMultiplierToMm());
                                        geometryInfo.set("boundsUntransformedMm", boundsUntransformedMm);
                                        HashMapWrappedVirtualObject boundsMm = createMmBounds(geometryInfo, bounds, generateGeometryResult.getMultiplierToMm());
                                        geometryInfo.set("boundsMm", boundsMm);
                                        float nrTriangles = masterGeometryData.getNrPrimitives();
                                        Density density = new Density(eClass.getName(), (float) volume, getBiggestFaceFromBounds(boundsUntransformedMm), (long) nrTriangles, geometryInfo.getOid());
                                        geometryInfo.setAttribute(GeometryPackage.eINSTANCE.getGeometryInfo_Density(), density.getDensityValue());
                                        generateGeometryResult.addDensity(density);
                                        HashMapVirtualObject referencedData = databaseSession.getFromCache(masterGeometryData.getOid());
                                        Integer currentValue = (Integer) referencedData.get("reused");
                                        referencedData.set("reused", currentValue + 1);
                                        HashMapWrappedVirtualObject dataBounds = (HashMapWrappedVirtualObject) referencedData.get("boundsMm");
                                        extendBounds(boundsMm, dataBounds);
                                        // TODO this keeping track of the amount of reuse, takes it's toll on memory usage. Basically all geometry ends up in memory by the time the Geometry generation is done
                                        // We should try to see whether we can use BDB's mechanism to do partial retrievals/updates of a records here, because we only need to update just one value
                                        // Another, simpler option would be to introduce another layer between GeometryInfo and GeometryData, so we don't have to cache the actual data (vertices etc... the bulk)
                                        // In that case however the BinarySerializer would increase in complexity
                                        // This seems to have been partially solved now since GeometryData does not contain the bulk of the data anymore (the byte[]s are now in "Buffer").
                                        referencedData.saveOverwrite();
                                        geometryInfo.setReference(GeometryPackage.eINSTANCE.getGeometryInfo_Data(), masterGeometryData.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) {
                    Metrics metrics = renderEngine.getMetrics();
                    if (metrics != null) {
                        job.setCpuTimeMs(metrics.getCpuTimeMs());
                        job.setMaxMemoryBytes(metrics.getMaxMemoryBytes());
                    }
                    renderEnginePool.returnObject(renderEngine);
                }
                try {
                    if (!notFoundObjects.isEmpty()) {
                        writeDebugFile(bytes, false, notFoundObjects);
                        StringBuilder sb = new StringBuilder();
                        for (Long key : notFoundObjects.keySet()) {
                            sb.append(key + " (" + notFoundObjects.get(key).getOid() + ")");
                            sb.append(", ");
                        }
                        sb.delete(sb.length() - 2, sb.length());
                        job.setException(new Exception("Missing objects in model (" + sb.toString() + ")"));
                    } else if (writeOutputFiles) {
                        writeDebugFile(bytes, false, null);
                    }
                    in.close();
                } catch (Throwable e) {
                } finally {
                }
                this.streamingGeometryGenerator.jobsDone.incrementAndGet();
                this.streamingGeometryGenerator.updateProgress();
            }
        } catch (Exception e) {
            StreamingGeometryGenerator.LOGGER.error("", e);
            writeDebugFile(bytes, true, null);
            job.setException(e);
        // 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);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Query(org.bimserver.database.queries.om.Query) HashMapWrappedVirtualObject(org.bimserver.shared.HashMapWrappedVirtualObject) HashMap(java.util.HashMap) QueryPart(org.bimserver.database.queries.om.QueryPart) FloatBuffer(java.nio.FloatBuffer) RenderEngineGeometry(org.bimserver.plugins.renderengine.RenderEngineGeometry) RenderEngineModel(org.bimserver.plugins.renderengine.RenderEngineModel) Metrics(org.bimserver.plugins.renderengine.Metrics) QueryObjectProvider(org.bimserver.database.queries.QueryObjectProvider) RenderEngineException(org.bimserver.plugins.renderengine.RenderEngineException) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) DoubleBuffer(java.nio.DoubleBuffer) OidConvertingSerializer(org.bimserver.plugins.serializers.OidConvertingSerializer) StreamingSerializer(org.bimserver.plugins.serializers.StreamingSerializer) EntityNotFoundException(org.bimserver.plugins.renderengine.EntityNotFoundException) Range(org.bimserver.Range) HashMapVirtualObject(org.bimserver.shared.HashMapVirtualObject) ByteArrayInputStream(java.io.ByteArrayInputStream) IntBuffer(java.nio.IntBuffer) BimserverDatabaseException(org.bimserver.BimserverDatabaseException) ObjectListener(org.bimserver.ObjectListener) PluginConfiguration(org.bimserver.plugins.PluginConfiguration) RenderEngine(org.bimserver.plugins.renderengine.RenderEngine) TemporaryGeometryData(org.bimserver.TemporaryGeometryData) HashMapWrappedVirtualObject(org.bimserver.shared.HashMapWrappedVirtualObject) WrappedVirtualObject(org.bimserver.shared.WrappedVirtualObject) Color4f(org.bimserver.Color4f) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) ObjectProviderProxy(org.bimserver.ObjectProviderProxy) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ByteBuffer(java.nio.ByteBuffer) FileNotFoundException(java.io.FileNotFoundException) GeometryGeneratingException(org.bimserver.GeometryGeneratingException) EntityNotFoundException(org.bimserver.plugins.renderengine.EntityNotFoundException) IOException(java.io.IOException) BimserverDatabaseException(org.bimserver.BimserverDatabaseException) RenderEngineException(org.bimserver.plugins.renderengine.RenderEngineException) RenderEngineInstance(org.bimserver.plugins.renderengine.RenderEngineInstance) ProductDef(org.bimserver.ProductDef)

Example 27 with QueryPart

use of org.bimserver.database.queries.om.QueryPart in project BIMserver by opensourceBIM.

the class QueryPartStackFrame method process.

@Override
public boolean process() throws BimserverDatabaseException, QueryException {
    if (typeIterator == null) {
        return true;
    }
    if (tiles != null) {
        List<Long> oids = new ArrayList<>();
        List<Long> oidsFiltered = new ArrayList<>();
        tiles.getTilingInterface().queryOids(oids, oidsFiltered, reusable.getCroid(), null, tiles);
        if (!oids.isEmpty()) {
            queryObjectProvider.push(new QueryOidsStackFrame(queryObjectProvider, partialQuery, reusable, oids));
        }
        if (!oidsFiltered.isEmpty()) {
            QueryPart filteredQueryPart = createFilteredQueryPart(partialQuery);
            queryObjectProvider.push(new QueryOidsStackFrame(queryObjectProvider, filteredQueryPart, reusable, oidsFiltered));
        }
        return true;
    }
    if (typeIterator.hasNext()) {
        EClass eClass = typeIterator.next();
        if (oids != null) {
            List<Long> oids2 = oids.get(eClass);
            if (oids2 != null) {
                queryObjectProvider.push(new QueryOidsAndTypesStackFrame(queryObjectProvider, eClass, partialQuery, reusable, oids2));
            }
        } else if (guids != null) {
            queryObjectProvider.push(new QueryGuidsAndTypesStackFrame(queryObjectProvider, eClass, partialQuery, reusable, guids));
        } else if (names != null) {
            queryObjectProvider.push(new QueryNamesAndTypesStackFrame(queryObjectProvider, eClass, partialQuery, reusable, names));
        } else if (properties != null) {
            queryObjectProvider.push(new QueryPropertiesAndTypesStackFrame(queryObjectProvider, eClass, partialQuery, reusable, properties));
        } else if (classifications != null) {
            queryObjectProvider.push(new QueryClassificationsAndTypesStackFrame(queryObjectProvider, eClass, partialQuery, reusable, classifications));
        } else if (inBoundingBox != null) {
            queryObjectProvider.push(new QueryBoundingBoxStackFrame(queryObjectProvider, eClass, partialQuery, reusable, inBoundingBox));
        } else {
            queryObjectProvider.push(new QueryTypeStackFrame(queryObjectProvider, eClass, reusable, partialQuery));
        }
        return false;
    }
    return true;
}
Also used : QueryPart(org.bimserver.database.queries.om.QueryPart) ArrayList(java.util.ArrayList) EClass(org.eclipse.emf.ecore.EClass)

Example 28 with QueryPart

use of org.bimserver.database.queries.om.QueryPart in project BIMserver by opensourceBIM.

the class GeometryAccellerator method generateOctree.

private Octree generateOctree(OctreeKey key) {
    LOGGER.info("Generating octree: " + key);
    Long start = System.nanoTime();
    try (DatabaseSession databaseSession = bimServer.getDatabase().createSession(OperationType.READ_ONLY)) {
        Bounds totalBounds = new Bounds();
        for (long roid : key.getRoids()) {
            Revision revision = databaseSession.get(roid, OldQuery.getDefault());
            totalBounds.integrate(revision.getBoundsMm());
        }
        Octree octree = new Octree(totalBounds, 9);
        // Assuming all given roids are of projects that all have the same
        // schema
        Revision revision = databaseSession.get(key.getRoids().iterator().next(), OldQuery.getDefault());
        PackageMetaData packageMetaData = bimServer.getMetaDataManager().getPackageMetaData(revision.getProject().getSchema());
        Set<EClass> excluded = new HashSet<>();
        if (key.getExcludedClasses() != null) {
            for (String exclude : key.getExcludedClasses()) {
                excluded.add(packageMetaData.getEClass(exclude));
            }
        }
        Query query = new Query(packageMetaData);
        QueryPart queryPart = query.createQueryPart();
        queryPart.addType(packageMetaData.getEClass("IfcProduct"), true, excluded);
        Include product = queryPart.createInclude();
        product.addType(packageMetaData.getEClass("IfcProduct"), true);
        product.addFieldDirect("geometry");
        Include geometryInfo = product.createInclude();
        geometryInfo.addType(GeometryPackage.eINSTANCE.getGeometryInfo(), false);
        geometryInfo.addFieldDirect("data");
        geometryInfo.addFieldDirect("boundsMm");
        Include boundsInclude = geometryInfo.createInclude();
        boundsInclude.addType(GeometryPackage.eINSTANCE.getBounds(), false);
        boundsInclude.addFieldDirect("min");
        boundsInclude.addFieldDirect("max");
        Include dataInclude = geometryInfo.createInclude();
        dataInclude.addType(GeometryPackage.eINSTANCE.getGeometryData(), false);
        dataInclude.addFieldDirect("boundsMm");
        Include dataBoundsInclude = dataInclude.createInclude();
        dataBoundsInclude.addType(GeometryPackage.eINSTANCE.getBounds(), false);
        dataBoundsInclude.addFieldDirect("min");
        dataBoundsInclude.addFieldDirect("max");
        QueryObjectProvider queryObjectProvider = new QueryObjectProvider(databaseSession, bimServer, query, key.getRoids(), packageMetaData);
        HashMapVirtualObject next = queryObjectProvider.next();
        Map<Long, GeometryDataObject> map = new HashMap<>();
        while (next != null) {
            AbstractHashMapVirtualObject geometry = next.getDirectFeature(packageMetaData.getEReference("IfcProduct", "geometry"));
            if (geometry != null) {
                float density = (float) geometry.get("density");
                long geometryDataId = (long) geometry.get("data");
                AbstractHashMapVirtualObject boundsMm = geometry.getDirectFeature(GeometryPackage.eINSTANCE.getGeometryInfo_BoundsMm());
                GeometryDataObject geometryDataObject = null;
                if (key.getGeometryIdsToReuse().contains(geometryDataId)) {
                    // Special case, we now have to use the complete
                    // bounding box of all reused objects, instead of using
                    // the object's aabb
                    HashMapVirtualObject geometryData = (HashMapVirtualObject) geometry.getDirectFeature(GeometryPackage.eINSTANCE.getGeometryInfo_Data());
                    boundsMm = geometryData.getDirectFeature(GeometryPackage.eINSTANCE.getGeometryData_BoundsMm());
                    geometryDataObject = map.get(geometryData.getOid());
                    if (geometryDataObject == null) {
                        geometryDataObject = new GeometryDataObject(geometryData);
                        map.put(geometryData.getOid(), geometryDataObject);
                    }
                }
                if (boundsMm != null) {
                    AbstractHashMapVirtualObject min = boundsMm.getDirectFeature(GeometryPackage.eINSTANCE.getBounds_Min());
                    AbstractHashMapVirtualObject max = boundsMm.getDirectFeature(GeometryPackage.eINSTANCE.getBounds_Max());
                    HashMapVirtualObject geometryData = (HashMapVirtualObject) geometry.getDirectFeature(GeometryPackage.eINSTANCE.getGeometryInfo_Data());
                    int saveableTriangles = (int) geometryData.get("saveableTriangles");
                    int reused = (int) geometryData.get("reused");
                    int triangles = (int) geometryData.get("nrIndices") / 3;
                    org.bimserver.database.queries.Bounds objectBounds = new org.bimserver.database.queries.Bounds((double) min.get("x"), (double) min.get("y"), (double) min.get("z"), (double) max.get("x"), (double) max.get("y"), (double) max.get("z"));
                    GeometryObject geometryObject = new GeometryObject(next.getOid(), next.eClass(), next.getCroid(), saveableTriangles, reused, triangles, density, objectBounds);
                    Node node = octree.add(geometryObject);
                    geometryObject.setTileId(node.getId());
                    geometryObject.setTileLevel(node.getLevel());
                    geometryObject.setGeometryDataObject(geometryDataObject);
                }
            }
            next = queryObjectProvider.next();
        }
        AtomicLong totalTriangles = new AtomicLong();
        octree.traverseBreathFirst(new Traverser() {

            @Override
            public void traverse(Node node) {
                for (GeometryObject geometryObject : node.getValues()) {
                    totalTriangles.addAndGet(geometryObject.getTriangles());
                }
            }
        });
        LOGGER.info("Total triangles: " + totalTriangles);
        octree.moveGeometryDown(new MoveGeometryDownDecider() {

            @Override
            public boolean shouldMoveDown(GeometryObject geometryObject) {
                GeometryDataObject geometryDataObject = geometryObject.getGeometryDataObject();
                if (geometryDataObject == null) {
                    // It's not reused at all
                    return false;
                }
                return false;
            }
        });
        octree.moveUp(new MoveUpDecider() {

            @Override
            public boolean moveUp(Node node) {
                // TODO use more heuristics
                int totalTriangles = 0;
                for (GeometryObject geometryObject : node.getValues()) {
                    totalTriangles += geometryObject.getTriangles();
                }
                if (totalTriangles < 1200) {
                    return true;
                }
                return false;
            }
        });
        long end = System.nanoTime();
        LOGGER.info("Octree generated in " + ((end - start) / 1000000) + " ms");
        return octree;
    } catch (BimserverDatabaseException e) {
        LOGGER.error("", e);
    } catch (IOException e) {
        LOGGER.error("", e);
    } catch (QueryException e) {
        LOGGER.error("", e);
    }
    return null;
}
Also used : Query(org.bimserver.database.queries.om.Query) OldQuery(org.bimserver.database.OldQuery) DatabaseSession(org.bimserver.database.DatabaseSession) HashMap(java.util.HashMap) QueryPart(org.bimserver.database.queries.om.QueryPart) Include(org.bimserver.database.queries.om.Include) BimserverDatabaseException(org.bimserver.BimserverDatabaseException) EClass(org.eclipse.emf.ecore.EClass) AbstractHashMapVirtualObject(org.bimserver.shared.AbstractHashMapVirtualObject) QueryObjectProvider(org.bimserver.database.queries.QueryObjectProvider) HashSet(java.util.HashSet) PackageMetaData(org.bimserver.emf.PackageMetaData) Bounds(org.bimserver.database.queries.Bounds) Bounds(org.bimserver.database.queries.Bounds) IOException(java.io.IOException) AtomicLong(java.util.concurrent.atomic.AtomicLong) QueryException(org.bimserver.database.queries.om.QueryException) Revision(org.bimserver.models.store.Revision) HashMapVirtualObject(org.bimserver.shared.HashMapVirtualObject) AbstractHashMapVirtualObject(org.bimserver.shared.AbstractHashMapVirtualObject) AtomicLong(java.util.concurrent.atomic.AtomicLong)

Example 29 with QueryPart

use of org.bimserver.database.queries.om.QueryPart in project BIMserver by opensourceBIM.

the class TestNewQueryViaClient method start.

private void start() {
    try (JsonBimServerClientFactory factory = new JsonBimServerClientFactory("http://localhost:8080")) {
        BimServerClient client = factory.create(new UsernamePasswordAuthenticationInfo("admin@bimserver.org", "admin"));
        String projectName = "Test " + new Random().nextInt();
        SProject project = client.getServiceInterface().addProject(projectName, "ifc2x3tc1");
        SDeserializerPluginConfiguration deserializer = client.getServiceInterface().getSuggestedDeserializerForExtension("ifc", project.getOid());
        client.checkinSync(project.getOid(), "Test Model", deserializer.getOid(), false, Paths.get("C:/Git/TestFiles/TestData/data/AC11-FZK-Haus-IFC.ifc"));
        project = client.getServiceInterface().getProjectByPoid(project.getOid());
        System.out.println(project.getName());
        ClientIfcModel model = client.getModel(project, project.getLastRevisionId(), false, false);
        Query query = new Query(model.getPackageMetaData());
        QueryPart queryPart = query.createQueryPart();
        queryPart.addType(Ifc2x3tc1Package.eINSTANCE.getIfcWall(), true);
        for (IfcWall ifcWall : model.getAllWithSubTypes(IfcWall.class)) {
            System.out.println(ifcWall.getGlobalId());
        }
    } catch (ServiceException e) {
        e.printStackTrace();
    } catch (ChannelConnectionException e) {
        e.printStackTrace();
    } catch (PublicInterfaceNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (BimServerClientException e) {
        e.printStackTrace();
    } catch (Exception e1) {
        e1.printStackTrace();
    }
}
Also used : IfcWall(org.bimserver.models.ifc2x3tc1.IfcWall) ClientIfcModel(org.bimserver.client.ClientIfcModel) SDeserializerPluginConfiguration(org.bimserver.interfaces.objects.SDeserializerPluginConfiguration) Query(org.bimserver.database.queries.om.Query) ChannelConnectionException(org.bimserver.shared.ChannelConnectionException) UsernamePasswordAuthenticationInfo(org.bimserver.shared.UsernamePasswordAuthenticationInfo) QueryPart(org.bimserver.database.queries.om.QueryPart) JsonBimServerClientFactory(org.bimserver.client.json.JsonBimServerClientFactory) IOException(java.io.IOException) SProject(org.bimserver.interfaces.objects.SProject) BimServerClientException(org.bimserver.shared.exceptions.BimServerClientException) BimServerClient(org.bimserver.client.BimServerClient) ChannelConnectionException(org.bimserver.shared.ChannelConnectionException) PublicInterfaceNotFoundException(org.bimserver.shared.exceptions.PublicInterfaceNotFoundException) BimServerClientException(org.bimserver.shared.exceptions.BimServerClientException) ServiceException(org.bimserver.shared.exceptions.ServiceException) IOException(java.io.IOException) Random(java.util.Random) ServiceException(org.bimserver.shared.exceptions.ServiceException) PublicInterfaceNotFoundException(org.bimserver.shared.exceptions.PublicInterfaceNotFoundException)

Example 30 with QueryPart

use of org.bimserver.database.queries.om.QueryPart in project BIMserver by opensourceBIM.

the class StreamingCheckinDatabaseAction method generateQuantizedVertices.

private void generateQuantizedVertices(DatabaseSession databaseSession, Revision revision, float[] quantizationMatrix, float multiplierToMm) {
    PackageMetaData packageMetaData = getBimServer().getMetaDataManager().getPackageMetaData(revision.getProject().getSchema());
    Query query = new Query(packageMetaData);
    QueryPart queryPart = query.createQueryPart();
    queryPart.addType(GeometryPackage.eINSTANCE.getGeometryData(), false);
    Include geometryDataInclude = queryPart.createInclude();
    try {
        geometryDataInclude.addType(GeometryPackage.eINSTANCE.getGeometryData(), false);
        geometryDataInclude.addFieldDirect("vertices");
        QueryObjectProvider objectProvider = new QueryObjectProvider(getDatabaseSession(), getBimServer(), query, Collections.singleton(revision.getOid()), packageMetaData);
        HashMapVirtualObject next = objectProvider.next();
        while (next != null) {
            HashMapVirtualObject verticesBuffer = (HashMapVirtualObject) next.get("vertices");
            ByteBuffer verticesData = ByteBuffer.wrap((byte[]) verticesBuffer.get("data"));
            verticesData.order(ByteOrder.LITTLE_ENDIAN);
            FloatBuffer vertices = verticesData.asFloatBuffer();
            ByteBuffer verticesQuantized = quantizeVertices(vertices.array(), quantizationMatrix, multiplierToMm);
            Buffer buffer = getDatabaseSession().create(Buffer.class);
            buffer.setData(verticesQuantized.array());
            next.setReference(GeometryPackage.eINSTANCE.getGeometryData_VerticesQuantized(), buffer.getOid(), -1);
            next.saveOverwrite();
            next = objectProvider.next();
            System.out.println("Generating quantized vertices");
        }
    } catch (Exception e) {
        LOGGER.error("", e);
    }
}
Also used : FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer) Buffer(org.bimserver.models.geometry.Buffer) OldQuery(org.bimserver.database.OldQuery) Query(org.bimserver.database.queries.om.Query) HashMapVirtualObject(org.bimserver.shared.HashMapVirtualObject) PackageMetaData(org.bimserver.emf.PackageMetaData) QueryPart(org.bimserver.database.queries.om.QueryPart) QueryObjectProvider(org.bimserver.database.queries.QueryObjectProvider) Include(org.bimserver.database.queries.om.Include) FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer) BimserverLockConflictException(org.bimserver.database.BimserverLockConflictException) UserException(org.bimserver.shared.exceptions.UserException) ServiceException(org.bimserver.shared.exceptions.ServiceException) IOException(java.io.IOException) ServerException(org.bimserver.shared.exceptions.ServerException) BimserverDatabaseException(org.bimserver.BimserverDatabaseException)

Aggregations

QueryPart (org.bimserver.database.queries.om.QueryPart)36 Query (org.bimserver.database.queries.om.Query)33 QueryObjectProvider (org.bimserver.database.queries.QueryObjectProvider)23 HashMapVirtualObject (org.bimserver.shared.HashMapVirtualObject)22 UserException (org.bimserver.shared.exceptions.UserException)18 EClass (org.eclipse.emf.ecore.EClass)17 Include (org.bimserver.database.queries.om.Include)16 PackageMetaData (org.bimserver.emf.PackageMetaData)16 IOException (java.io.IOException)12 List (java.util.List)10 JsonQueryObjectModelConverter (org.bimserver.database.queries.om.JsonQueryObjectModelConverter)10 OldQuery (org.bimserver.database.OldQuery)9 QueryException (org.bimserver.database.queries.om.QueryException)9 EReference (org.eclipse.emf.ecore.EReference)8 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)7 HashMap (java.util.HashMap)7 HashSet (java.util.HashSet)7 BimserverDatabaseException (org.bimserver.BimserverDatabaseException)6 ServiceException (org.bimserver.shared.exceptions.ServiceException)6 IfcModelInterfaceException (org.bimserver.emf.IfcModelInterfaceException)5