Search in sources :

Example 6 with AbstractHashMapVirtualObject

use of org.bimserver.shared.AbstractHashMapVirtualObject 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)

Aggregations

AbstractHashMapVirtualObject (org.bimserver.shared.AbstractHashMapVirtualObject)6 HashMapVirtualObject (org.bimserver.shared.HashMapVirtualObject)4 IOException (java.io.IOException)3 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 AtomicLong (java.util.concurrent.atomic.AtomicLong)3 BimserverDatabaseException (org.bimserver.BimserverDatabaseException)3 OldQuery (org.bimserver.database.OldQuery)3 QueryObjectProvider (org.bimserver.database.queries.QueryObjectProvider)3 Include (org.bimserver.database.queries.om.Include)3 Query (org.bimserver.database.queries.om.Query)3 QueryException (org.bimserver.database.queries.om.QueryException)3 QueryPart (org.bimserver.database.queries.om.QueryPart)3 EClass (org.eclipse.emf.ecore.EClass)3 List (java.util.List)2 DatabaseSession (org.bimserver.database.DatabaseSession)2 PackageMetaData (org.bimserver.emf.PackageMetaData)2 Revision (org.bimserver.models.store.Revision)2 ByteBuffer (java.nio.ByteBuffer)1 DateFormat (java.text.DateFormat)1