Example usage for java.nio DoubleBuffer capacity

List of usage examples for java.nio DoubleBuffer capacity

Introduction

In this page you can find the example usage for java.nio DoubleBuffer capacity.

Prototype

public final int capacity() 

Source Link

Document

Returns the capacity of this buffer.

Usage

From source file:Main.java

/**
 * Creates a double array from the provided {@link DoubleBuffer}.
 * //from   w  ww  .  ja  va2 s .c o m
 * @param buffer {@link DoubleBuffer} the data source.
 * @return double array containing the data of the buffer.
 */
public static double[] getDoubleArrayFromBuffer(DoubleBuffer buffer) {
    double[] array = null;
    if (buffer.hasArray()) {
        array = buffer.array();
    } else {
        buffer.rewind();
        array = new double[buffer.capacity()];
        buffer.get(array);
    }
    return array;
}

From source file:org.bimserver.geometry.GeometryRunner.java

@Override
public void run() {
    Thread.currentThread().setName("GeometryRunner");
    long start = System.nanoTime();
    job.setStartNanos(start);//from w ww.j a va 2  s. c  om
    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())) {
                if (originalQuery.getQueryParts().get(0).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) {
                            if (originalQuery.getQueryParts().get(0).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<Integer, 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, Integer> oidToEid = oidConvertingSerializer.getOidToEid();
                        Map<Long, DebuggingInfo> debuggingInfo = new HashMap<>();

                        for (HashMapVirtualObject ifcProduct : objects) {
                            if (!this.streamingGeometryGenerator.running) {
                                return;
                            }
                            Integer expressId = oidToEid.get(ifcProduct.getOid());
                            try {
                                RenderEngineInstance renderEngineInstance = renderEngineModel
                                        .getInstanceFromExpressId(expressId);
                                RenderEngineGeometry geometry = renderEngineInstance.generateGeometry();
                                boolean translate = true;
                                // if (geometry == null ||
                                // geometry.getIndices().length == 0) {
                                // LOGGER.info("Running again...");
                                // renderEngineModel.setFilter(renderEngineFilterTransformed);
                                // geometry =
                                // renderEngineInstance.generateGeometry();
                                // if (geometry != null) {
                                // translate = false;
                                // }
                                // renderEngineModel.setFilter(renderEngineFilter);
                                // }

                                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_Bounds(), bounds);
                                    bounds.setAttribute(GeometryPackage.eINSTANCE.getBounds_Min(), minBounds);
                                    bounds.setAttribute(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.setAttribute(GeometryPackage.eINSTANCE.getBounds_Min(),
                                            minBoundsUntranslated);
                                    boundsUntransformed.setAttribute(GeometryPackage.eINSTANCE.getBounds_Max(),
                                            maxBoundsUntranslated);

                                    geometryInfo.setAttribute(
                                            GeometryPackage.eINSTANCE.getGeometryInfo_BoundsUntransformed(),
                                            boundsUntransformed);

                                    double volume = 0;
                                    ObjectNode additionalData = renderEngineInstance.getAdditionalData();
                                    if (streamingGeometryGenerator.isCalculateQuantities()) {
                                        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);
                                            }
                                        }
                                    }

                                    HashMapVirtualObject geometryData = new HashMapVirtualObject(queryContext,
                                            GeometryPackage.eINSTANCE.getGeometryData());

                                    geometryData.set("type", databaseSession.getCid(eClass));
                                    ByteBuffer indices = geometry.getIndices();
                                    IntBuffer indicesAsInt = indices.order(ByteOrder.LITTLE_ENDIAN)
                                            .asIntBuffer();
                                    geometryData.setAttribute(
                                            GeometryPackage.eINSTANCE.getGeometryData_Reused(), 1);
                                    geometryData.setAttribute(
                                            GeometryPackage.eINSTANCE.getGeometryData_Indices(),
                                            createBuffer(queryContext, indices));
                                    geometryData.set("nrIndices", indicesAsInt.capacity());
                                    ByteBuffer vertices = geometry.getVertices();
                                    DoubleBuffer verticesAsDouble = vertices.order(ByteOrder.LITTLE_ENDIAN)
                                            .asDoubleBuffer();
                                    geometryData.set("nrVertices", verticesAsDouble.capacity());
                                    geometryData.setAttribute(
                                            GeometryPackage.eINSTANCE.getGeometryData_Vertices(),
                                            createBuffer(queryContext, vertices));
                                    ByteBuffer normals = geometry.getNormals();
                                    FloatBuffer normalsAsFloat = normals.order(ByteOrder.LITTLE_ENDIAN)
                                            .asFloatBuffer();
                                    geometryData.set("nrNormals", normalsAsFloat.capacity());
                                    geometryData.setAttribute(
                                            GeometryPackage.eINSTANCE.getGeometryData_Normals(),
                                            createBuffer(queryContext, normals));

                                    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]);
                                    IntBuffer materialIndices = geometry.getMaterialIndices()
                                            .order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
                                    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);
                                                }
                                                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.set(GeometryPackage.eINSTANCE.getColorPack_Data(),
                                                    colorMap2.toByteArray());
                                            colorPack.save();
                                            geometryData.setReference(
                                                    GeometryPackage.eINSTANCE.getGeometryData_ColorPack(),
                                                    colorPack.getOid(), 0);
                                        }
                                        if (colorMap.usedColors() == 0) {
                                        } 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.setAttribute(
                                                    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.setAttribute(
                                                    GeometryPackage.eINSTANCE.getGeometryData_MostUsedColor(),
                                                    color);
                                        }
                                        if (hasMaterial) {
                                            geometryData.set("nrColors", colors.capacity());
                                            geometryData.set(
                                                    GeometryPackage.eINSTANCE.getGeometryData_ColorsQuantized(),
                                                    createBuffer(queryContext, colors));
                                        } 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.setAttribute(
                                            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.setAttribute(GeometryPackage.eINSTANCE.getBounds_Min(),
                                            geometryDataBoundsMin);
                                    geometryDataBounds.setAttribute(GeometryPackage.eINSTANCE.getBounds_Max(),
                                            geometryDataBoundsMax);
                                    geometryData.setAttribute(
                                            GeometryPackage.eINSTANCE.getGeometryData_BoundsMm(),
                                            geometryDataBounds);

                                    if (volume == 0) {
                                        volume = getVolumeFromBounds(boundsUntransformed);
                                    }
                                    float nrTriangles = geometry.getNrIndices() / 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;
                                            // for (Range r :
                                            // reusableGeometryData) {
                                            // if (r.isSimilar(range)) {
                                            // geometryInfo.setReference(GeometryPackage.eINSTANCE.getGeometryInfo_Data(),
                                            // r.getGeometryDataOid(), 0);
                                            // float[] offset =
                                            // r.getOffset(range);
                                            // ProductDef productDef =
                                            // map.get(ifcProduct.getOid());
                                            // double[] mappedItemMatrix =
                                            // null;
                                            // if (productDef != null &&
                                            // productDef.getMatrix() !=
                                            // null) {
                                            // mappedItemMatrix =
                                            // productDef.getMatrix();
                                            // } else {
                                            // Matrix.translateM(mappedItemMatrix,
                                            // 0, offset[0], offset[1],
                                            // offset[2]);
                                            // }
                                            // double[] result = new
                                            // double[16];
                                            // Matrix.multiplyMM(result, 0,
                                            // mappedItemMatrix, 0,
                                            // productTranformationMatrix,
                                            // 0);
                                            // setTransformationMatrix(geometryInfo,
                                            // result); // Overwritten?
                                            // bytesSavedByTransformation.addAndGet(size);
                                            // found = true;
                                            // break;
                                            // }
                                            // }
                                            if (!found) {
                                                range.setGeometryDataOid(geometryData.getOid());
                                                reusableGeometryData.add(range);

                                                if (streamingGeometryGenerator.isCalculateQuantities()) {
                                                    if (additionalData != null) {
                                                        geometryInfo.setAttribute(
                                                                GeometryPackage.eINSTANCE
                                                                        .getGeometryInfo_AdditionalData(),
                                                                additionalData.toString());
                                                        if (additionalData.has("SURFACE_AREA_ALONG_Z")) {
                                                            geometryInfo.setAttribute(
                                                                    GeometryPackage.eINSTANCE
                                                                            .getGeometryInfo_Area(),
                                                                    additionalData.get("SURFACE_AREA_ALONG_Z")
                                                                            .asDouble());
                                                        }
                                                        if (additionalData.has("TOTAL_SHAPE_VOLUME")) {
                                                            geometryInfo.setAttribute(
                                                                    GeometryPackage.eINSTANCE
                                                                            .getGeometryInfo_Volume(),
                                                                    additionalData.get("TOTAL_SHAPE_VOLUME")
                                                                            .asDouble());
                                                        }
                                                    }
                                                }

                                                geometryInfo.setAttribute(
                                                        GeometryPackage.eINSTANCE
                                                                .getGeometryInfo_PrimitiveCount(),
                                                        indicesAsInt.capacity() / 3);

                                                productToData.put(ifcProduct.getOid(),
                                                        new TemporaryGeometryData(geometryData.getOid(),
                                                                additionalData, 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
                                            geometryData.save(); // TODO Why??

                                            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");

                                // for (Object rep : representations) {
                                // if (rep instanceof
                                // IfcShapeRepresentation) {
                                // IfcShapeRepresentation
                                // ifcShapeRepresentation =
                                // (IfcShapeRepresentation)rep;
                                // if
                                // (!"Curve2D".equals(ifcShapeRepresentation.getRepresentationType()))
                                // {
                                // ignoreNotFound = false;
                                // }
                                // }
                                // }
                                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.setAttribute(
                                                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());

                                        boundsUntransformed.setAttribute(
                                                GeometryPackage.eINSTANCE.getBounds_Min(),
                                                minBoundsUntransformed);
                                        boundsUntransformed.setAttribute(
                                                GeometryPackage.eINSTANCE.getBounds_Max(),
                                                maxBoundsUntransformed);
                                        geometryInfo.setAttribute(
                                                GeometryPackage.eINSTANCE.getGeometryInfo_BoundsUntransformed(),
                                                boundsUntransformed);

                                        ObjectNode additionalData = masterGeometryData.getAdditionalData();
                                        double volume = 0;
                                        if (additionalData != null) {
                                            geometryInfo.setAttribute(
                                                    GeometryPackage.eINSTANCE.getGeometryInfo_AdditionalData(),
                                                    additionalData.toString());
                                            if (additionalData.has("SURFACE_AREA_ALONG_Z")) {
                                                geometryInfo.setAttribute(
                                                        GeometryPackage.eINSTANCE.getGeometryInfo_Area(),
                                                        additionalData.get("SURFACE_AREA_ALONG_Z").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) {
                    renderEnginePool.returnObject(renderEngine);
                }
                try {
                    if (!notFoundObjects.isEmpty()) {
                        writeDebugFile(bytes, false, notFoundObjects);
                        StringBuilder sb = new StringBuilder();
                        for (Integer 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);
}

From source file:org.bimserver.geometry.StreamingGeometryGenerator.java

private ByteBuffer quantizeVertices(DoubleBuffer vertices, double[] quantizationMatrix, double multiplierToMm) {
    ByteBuffer quantizedBuffer = ByteBuffer.wrap(new byte[vertices.capacity() * 2]);
    quantizedBuffer.order(ByteOrder.LITTLE_ENDIAN);

    double[] vertex = new double[4];
    double[] result = new double[4];
    vertex[3] = 1;//w ww  .j  a v a2  s .  co m
    int nrVertices = vertices.capacity();
    for (int i = 0; i < nrVertices; i += 3) {
        vertex[0] = vertices.get(i);
        vertex[1] = vertices.get(i + 1);
        vertex[2] = vertices.get(i + 2);

        if (multiplierToMm != 1f) {
            vertex[0] = vertex[0] * multiplierToMm;
            vertex[1] = vertex[1] * multiplierToMm;
            vertex[2] = vertex[2] * multiplierToMm;
        }

        Matrix.multiplyMV(result, 0, quantizationMatrix, 0, vertex, 0);

        quantizedBuffer.putShort((short) result[0]);
        quantizedBuffer.putShort((short) result[1]);
        quantizedBuffer.putShort((short) result[2]);
    }

    return quantizedBuffer;
}