use of org.bimserver.GeometryGeneratingException in project BIMserver by opensourceBIM.
the class DownloadProjectsDatabaseAction method execute.
@Override
public IfcModelInterface execute() throws UserException, BimserverLockConflictException, BimserverDatabaseException {
User user = getUserByUoid(getAuthorization().getUoid());
Project project = null;
String projectName = "";
IfcModelSet ifcModelSet = new IfcModelSet();
long incrSize = 0;
for (long roid : roids) {
Revision revision = getRevisionByRoid(roid);
for (ConcreteRevision subRevision : revision.getConcreteRevisions()) {
incrSize += subRevision.getSize();
}
}
final long totalSize = incrSize;
final AtomicLong total = new AtomicLong();
PluginConfiguration serializerPluginConfiguration = getDatabaseSession().get(StorePackage.eINSTANCE.getPluginConfiguration(), serializerOid, OldQuery.getDefault());
PackageMetaData lastPackageMetaData = null;
IfcHeader ifcHeader = null;
Map<Integer, Long> pidRoidMap = new HashMap<>();
for (long roid : roids) {
Revision revision = getRevisionByRoid(roid);
project = revision.getProject();
pidRoidMap.put(project.getId(), roid);
if (getAuthorization().hasRightsOnProjectOrSuperProjectsOrSubProjects(user, project)) {
for (ConcreteRevision concreteRevision : revision.getConcreteRevisions()) {
ifcHeader = concreteRevision.getIfcHeader();
PackageMetaData packageMetaData = getBimServer().getMetaDataManager().getPackageMetaData(concreteRevision.getProject().getSchema());
lastPackageMetaData = packageMetaData;
IfcModel subModel = getDatabaseSession().createServerModel(packageMetaData, pidRoidMap);
;
int highestStopId = findHighestStopRid(project, concreteRevision);
OldQuery query = new OldQuery(packageMetaData, concreteRevision.getProject().getId(), concreteRevision.getId(), revision.getOid(), Deep.YES, highestStopId);
subModel.addChangeListener(new IfcModelChangeListener() {
@Override
public void objectAdded(IdEObject idEObject) {
total.incrementAndGet();
if (totalSize == 0) {
setProgress("Preparing download...", 0);
} else {
setProgress("Preparing download...", (int) Math.round(100.0 * total.get() / totalSize));
}
}
});
query.updateOidCounters(concreteRevision, getDatabaseSession());
getDatabaseSession().getMap(subModel, query);
projectName += concreteRevision.getProject().getName() + "-";
subModel.getModelMetaData().setDate(concreteRevision.getDate());
try {
checkGeometry(serializerPluginConfiguration, getBimServer().getPluginManager(), subModel, project, concreteRevision, revision);
} catch (GeometryGeneratingException e) {
throw new UserException(e);
}
ifcModelSet.add(subModel);
}
} else {
throw new UserException("User has no rights on project " + project.getOid());
}
}
IfcModelInterface ifcModel = getDatabaseSession().createServerModel(lastPackageMetaData, pidRoidMap);
if (ifcModelSet.size() == 1) {
ifcModel = ifcModelSet.iterator().next();
} else {
try {
ifcModel = getBimServer().getMergerFactory().createMerger(getDatabaseSession(), getAuthorization().getUoid()).merge(project, ifcModelSet, new ModelHelper(getBimServer().getMetaDataManager(), ifcModel));
} catch (MergeException e) {
throw new UserException(e);
}
}
if (ifcHeader != null) {
ifcHeader.load();
ifcModel.getModelMetaData().setIfcHeader(ifcHeader);
}
if (projectName.endsWith("-")) {
projectName = projectName.substring(0, projectName.length() - 1);
}
ifcModel.getModelMetaData().setName(projectName);
return ifcModel;
}
use of org.bimserver.GeometryGeneratingException in project BIMserver by opensourceBIM.
the class DownloadDatabaseAction method execute.
@Override
public IfcModelInterface execute() throws UserException, BimserverLockConflictException, BimserverDatabaseException, ServerException {
Revision revision = getRevisionByRoid(roid);
PluginConfiguration serializerPluginConfiguration = getDatabaseSession().get(StorePackage.eINSTANCE.getPluginConfiguration(), serializerOid, OldQuery.getDefault());
getAuthorization().canDownload(roid);
if (revision == null) {
throw new UserException("Revision with oid " + roid + " not found");
}
Project project = revision.getProject();
User user = getUserByUoid(getAuthorization().getUoid());
try {
getAuthorization().canDownload(roid);
} catch (UserException e) {
if (!getAuthorization().hasRightsOnProjectOrSuperProjectsOrSubProjects(user, project)) {
throw new UserException("User has insufficient rights to download revisions from this project");
}
}
IfcModelSet ifcModelSet = new IfcModelSet();
long incrSize = 0;
EList<ConcreteRevision> concreteRevisions = revision.getConcreteRevisions();
if (concreteRevisions.size() == 0) {
throw new ServerException("No concrete revisions in revision");
}
for (ConcreteRevision subRevision : concreteRevisions) {
incrSize += subRevision.getSize();
}
final long totalSize = incrSize;
final AtomicLong total = new AtomicLong();
IfcHeader ifcHeader = null;
PackageMetaData lastPackageMetaData = null;
Map<Integer, Long> pidRoidMap = new HashMap<>();
pidRoidMap.put(project.getId(), roid);
for (ConcreteRevision concreteRevision : concreteRevisions) {
if (concreteRevision.getUser().getOid() != ignoreUoid) {
PackageMetaData packageMetaData = getBimServer().getMetaDataManager().getPackageMetaData(concreteRevision.getProject().getSchema());
lastPackageMetaData = packageMetaData;
IfcModel subModel = getDatabaseSession().createServerModel(packageMetaData, pidRoidMap);
ifcHeader = concreteRevision.getIfcHeader();
int highestStopId = findHighestStopRid(project, concreteRevision);
OldQuery query = new OldQuery(packageMetaData, concreteRevision.getProject().getId(), concreteRevision.getId(), concreteRevision.getOid(), Deep.YES, highestStopId);
subModel.addChangeListener(new IfcModelChangeListener() {
@Override
public void objectAdded(IdEObject idEObject) {
total.incrementAndGet();
if (totalSize == 0) {
setProgress("Preparing download...", 0);
} else {
setProgress("Preparing download...", (int) Math.round(100.0 * total.get() / totalSize));
}
}
});
query.updateOidCounters(concreteRevision, getDatabaseSession());
getDatabaseSession().getMap(subModel, query);
if (serializerPluginConfiguration != null) {
try {
checkGeometry(serializerPluginConfiguration, getBimServer().getPluginManager(), subModel, project, concreteRevision, revision);
} catch (GeometryGeneratingException e) {
throw new UserException(e);
}
}
subModel.getModelMetaData().setDate(concreteRevision.getDate());
ifcModelSet.add(subModel);
}
}
IfcModelInterface ifcModel = getDatabaseSession().createServerModel(lastPackageMetaData, pidRoidMap);
if (ifcModelSet.size() > 1) {
try {
ifcModel = getBimServer().getMergerFactory().createMerger(getDatabaseSession(), getAuthorization().getUoid()).merge(revision.getProject(), ifcModelSet, new ModelHelper(getBimServer().getMetaDataManager(), ifcModel));
} catch (MergeException e) {
throw new UserException(e);
}
} else {
ifcModel = ifcModelSet.iterator().next();
}
if (ifcHeader != null) {
ifcHeader.load();
ifcModel.getModelMetaData().setIfcHeader(ifcHeader);
}
ifcModel.getModelMetaData().setName(project.getName() + "." + revision.getId());
ifcModel.getModelMetaData().setRevisionId(project.getRevisions().indexOf(revision) + 1);
if (user != null) {
ifcModel.getModelMetaData().setAuthorizedUser(user.getName());
}
ifcModel.getModelMetaData().setDate(revision.getDate());
if (revision.getProject().getGeoTag() != null) {
// ifcModel.setLon(revision.getProject().getGeoTag().getX());
// ifcModel.setLat(revision.getProject().getGeoTag().getY());
// ifcModel.setAltitude((int)
// revision.getProject().getGeoTag().getZ());
// ifcModel.setDirectionAngle(revision.getProject().getGeoTag().getDirectionAngle());
// try {
// CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:" +
// revision.getProject().getGeoTag().getEpsg());
// CoordinateReferenceSystem targetCRS =
// DefaultGeocentricCRS.CARTESIAN;
// MathTransform transform = CRS.findMathTransform(sourceCRS,
// targetCRS, true);
// float[] in = new
// float[]{revision.getProject().getGeoTag().getX1(),
// revision.getProject().getGeoTag().getY1(),
// revision.getProject().getGeoTag().getZ1()};
// float[] result = new float[3];
// transform.transform(in, 0, result, 0, 1);
// IfcModel.setLon(result[0]);
// IfcModel.setLat(result[1]);
// } catch (NoSuchAuthorityCodeException e) {
// LOGGER.error("", e);
// } catch (FactoryException e) {
// LOGGER.error("", e);
// } catch (MismatchedDimensionException e) {
// LOGGER.error("", e);
// } catch (TransformException e) {
// LOGGER.error("", e);
// }
}
return ifcModel;
}
use of org.bimserver.GeometryGeneratingException in project BIMserver by opensourceBIM.
the class CommitTransactionDatabaseAction method execute.
@Override
public ConcreteRevision execute() throws UserException, BimserverLockConflictException, BimserverDatabaseException {
Project project = getProjectByPoid(longTransaction.getPoid());
User user = getUserByUoid(authorization.getUoid());
if (project == null) {
throw new UserException("Project with poid " + longTransaction.getPoid() + " not found");
}
if (!authorization.hasRightsOnProjectOrSuperProjects(user, project)) {
throw new UserException("User has no rights to checkin models to this project");
}
if (!MailSystem.isValidEmailAddress(user.getUsername())) {
throw new UserException("Users must have a valid e-mail address to checkin");
}
long size = 0;
Revision previousRevision = project.getLastRevision();
ConcreteRevision previousConcreteRevision = null;
if (previousRevision != null) {
previousConcreteRevision = previousRevision.getConcreteRevisions().get(0);
}
if (project.getLastRevision() != null) {
size += project.getLastRevision().getSize();
}
for (Change change : longTransaction.getChanges()) {
if (change instanceof CreateObjectChange) {
size++;
} else if (change instanceof RemoveObjectChange) {
size--;
}
}
Revision oldLastRevision = project.getLastRevision();
CreateRevisionResult result = createNewConcreteRevision(getDatabaseSession(), size, project, user, comment.trim());
ConcreteRevision concreteRevision = result.getConcreteRevision();
if (previousConcreteRevision != null) {
concreteRevision.setIfcHeader(previousConcreteRevision.getIfcHeader());
}
revision = concreteRevision.getRevisions().get(0);
project.setLastRevision(revision);
final NewRevisionAdded newRevisionAdded = getDatabaseSession().create(NewRevisionAdded.class);
newRevisionAdded.setDate(new Date());
newRevisionAdded.setExecutor(user);
newRevisionAdded.setRevision(concreteRevision.getRevisions().get(0));
newRevisionAdded.setProject(project);
newRevisionAdded.setAccessMethod(getAccessMethod());
OidCounters originalOidCounters = null;
PackageMetaData packageMetaData = getBimServer().getMetaDataManager().getPackageMetaData(project.getSchema());
if (oldLastRevision != null) {
int highestStopId = AbstractDownloadDatabaseAction.findHighestStopRid(project, oldLastRevision.getLastConcreteRevision());
OldQuery query = new OldQuery(longTransaction.getPackageMetaData(), project.getId(), oldLastRevision.getId(), -1, Deep.YES, highestStopId);
originalOidCounters = query.updateOidCounters(oldLastRevision.getLastConcreteRevision(), getDatabaseSession());
} else {
originalOidCounters = new OidCounters();
}
getDatabaseSession().addPostCommitAction(new PostCommitAction() {
@Override
public void execute() throws UserException {
getBimServer().getNotificationsManager().notify(new SConverter().convertToSObject(newRevisionAdded));
try {
getBimServer().getLongTransactionManager().remove(longTransaction.getTid());
} catch (NoTransactionException e) {
LOGGER.error("", e);
}
}
});
SummaryMap summaryMap = null;
if (oldLastRevision != null && oldLastRevision.getConcreteRevisions().size() == 1 && oldLastRevision.getConcreteRevisions().get(0).getSummary() != null) {
summaryMap = new SummaryMap(packageMetaData, oldLastRevision.getConcreteRevisions().get(0).getSummary());
} else {
summaryMap = new SummaryMap(packageMetaData);
}
// First create all new objects
Transaction transaction = new Transaction(getBimServer(), previousRevision, project, concreteRevision, getDatabaseSession());
for (Change change : longTransaction.getChanges()) {
if (change instanceof CreateObjectChange) {
try {
CreateObjectChange createObjectChange = (CreateObjectChange) change;
change.execute(transaction);
getDatabaseSession().addStartOid(createObjectChange.geteClass(), createObjectChange.getOid());
} catch (IOException | QueryException e) {
e.printStackTrace();
}
summaryMap.add(((CreateObjectChange) change).geteClass(), 1);
}
}
// Then do the rest
for (Change change : longTransaction.getChanges()) {
if (!(change instanceof CreateObjectChange)) {
if (change instanceof RemoveObjectChange) {
summaryMap.remove(((RemoveObjectChange) change).geteClass(), 1);
}
try {
change.execute(transaction);
} catch (IOException e) {
e.printStackTrace();
} catch (QueryException e) {
e.printStackTrace();
}
}
}
for (HashMapVirtualObject object : transaction.getCreated()) {
getDatabaseSession().save(object);
}
for (HashMapVirtualObject object : transaction.getUpdated()) {
getDatabaseSession().save(object, concreteRevision.getId());
}
for (HashMapVirtualObject object : transaction.getDeleted()) {
getDatabaseSession().delete(object, concreteRevision.getId());
}
setProgress("Generating inverses/opposites...", -1);
Revision newRevision = result.getRevisions().get(0);
long newRoid = newRevision.getOid();
try {
fixInverses(packageMetaData, newRoid, summaryMap.getSummaryMap());
} catch (QueryException | IOException e1) {
e1.printStackTrace();
}
int highestStopId = AbstractDownloadDatabaseAction.findHighestStopRid(concreteRevision.getProject(), concreteRevision);
QueryContext queryContext = new QueryContext(getDatabaseSession(), packageMetaData, project.getId(), concreteRevision.getId(), concreteRevision.getRevisions().get(0).getOid(), concreteRevision.getOid(), highestStopId);
Map<String, Long> startOids = getDatabaseSession().getStartOids();
if (startOids == null) {
throw new BimserverDatabaseException("No objects changed");
}
for (EClass eClass : packageMetaData.getEClasses()) {
if (startOids.containsKey(eClass.getEPackage().getName() + "." + eClass.getName())) {
long oid = startOids.get(eClass.getEPackage().getName() + "." + eClass.getName());
if (!DatabaseSession.perRecordVersioning(eClass)) {
originalOidCounters.putIfAbsent(eClass, oid);
}
}
}
queryContext.setOidCounters(originalOidCounters);
concreteRevision.setOidCounters(originalOidCounters == null ? null : originalOidCounters.getBytes());
if (getBimServer().getServerSettingsCache().getServerSettings().isGenerateGeometryOnCheckin()) {
if (regenerateAllGeometry) {
setProgress("Generating Geometry...", -1);
try {
GeometryGenerationReport report = new GeometryGenerationReport();
report.setOriginalDeserializer("No deserializer, low level call");
report.setOriginalIfcFileName("No file, low level call");
report.setOriginalIfcFileSize(-1);
StreamingGeometryGenerator streamingGeometryGenerator = new StreamingGeometryGenerator(getBimServer(), null, -1L, report);
GenerateGeometryResult generateGeometry = streamingGeometryGenerator.generateGeometry(authorization.getUoid(), getDatabaseSession(), queryContext, summaryMap.count());
concreteRevision.setMultiplierToMm(generateGeometry.getMultiplierToMm());
concreteRevision.setBounds(generateGeometry.getBounds());
concreteRevision.setBoundsUntransformed(generateGeometry.getBoundsUntransformed());
generateDensityAndBounds(result, generateGeometry, concreteRevision);
final GeometryGenerationReport finalReport = report;
getDatabaseSession().addPostCommitAction(new PostCommitAction() {
@Override
public void execute() throws UserException {
if (finalReport != null) {
byte[] htmlBytes = finalReport.toHtml().getBytes(Charsets.UTF_8);
byte[] jsonBytes = finalReport.toJson().toString().getBytes(Charsets.UTF_8);
try (DatabaseSession tmpSession = getBimServer().getDatabase().createSession(OperationType.POSSIBLY_WRITE)) {
AddGeometryReports addGeometryReports = new AddGeometryReports(tmpSession, AccessMethod.INTERNAL, htmlBytes, jsonBytes, finalReport.getTimeToGenerateMs(), authorization.getUoid(), revision.getOid());
try {
tmpSession.executeAndCommitAction(addGeometryReports);
} catch (ServerException e1) {
LOGGER.error("", e1);
}
} catch (BimserverDatabaseException e1) {
LOGGER.error("", e1);
}
}
getBimServer().getNotificationsManager().notify(new NewRevisionNotification(getBimServer(), project.getOid(), revision.getOid(), authorization));
}
});
} catch (GeometryGeneratingException e) {
throw new UserException(e);
}
revision.setHasGeometry(true);
} else {
if (previousRevision != null) {
byte[] htmlBytes = null;
byte[] jsonBytes = null;
long timeToGenerate = -1;
for (ExtendedData previousExtendedData : previousRevision.getExtendedData()) {
ExtendedDataSchema previousSchema = previousExtendedData.getSchema();
if (previousSchema.getName().contentEquals("GEOMETRY_GENERATION_REPORT_HTML_1_1")) {
htmlBytes = previousExtendedData.getFile().getData();
} else if (previousSchema.getName().contentEquals("GEOMETRY_GENERATION_REPORT_JSON_1_1")) {
jsonBytes = previousExtendedData.getFile().getData();
}
}
byte[] finalHtmlBytes = htmlBytes;
byte[] finalJsonBytes = jsonBytes;
getDatabaseSession().addPostCommitAction(new PostCommitAction() {
public void execute() throws UserException {
try (DatabaseSession tmpSession = getBimServer().getDatabase().createSession(OperationType.POSSIBLY_WRITE)) {
AddGeometryReports addGeometryReports = new AddGeometryReports(tmpSession, AccessMethod.INTERNAL, finalHtmlBytes, finalJsonBytes, timeToGenerate, authorization.getUoid(), revision.getOid());
try {
tmpSession.executeAndCommitAction(addGeometryReports);
} catch (ServerException e1) {
LOGGER.error("", e1);
}
} catch (BimserverDatabaseException e1) {
LOGGER.error("", e1);
}
}
});
concreteRevision.setMultiplierToMm(previousConcreteRevision.getMultiplierToMm());
concreteRevision.setBounds(previousConcreteRevision.getBounds());
concreteRevision.setBoundsUntransformed(previousConcreteRevision.getBoundsUntransformed());
newRevision.setBounds(previousRevision.getBounds());
newRevision.setBoundsUntransformed(previousRevision.getBoundsUntransformed());
newRevision.setBoundsMm(previousRevision.getBoundsMm());
newRevision.setBoundsUntransformedMm(previousRevision.getBoundsUntransformedMm());
// TODO validate this, contains ids?
newRevision.setDensityCollection(previousRevision.getDensityCollection());
revision.setHasGeometry(true);
}
}
}
concreteRevision.setSummary(summaryMap.toRevisionSummary(getDatabaseSession()));
getDatabaseSession().store(concreteRevision);
getDatabaseSession().store(project);
return concreteRevision;
}
use of org.bimserver.GeometryGeneratingException in project BIMserver by opensourceBIM.
the class CheckoutDatabaseAction method realCheckout.
private IfcModel realCheckout(Project project, Revision revision, DatabaseSession databaseSession, User user) throws BimserverLockConflictException, BimserverDatabaseException, UserException {
PluginConfiguration serializerPluginConfiguration = getDatabaseSession().get(StorePackage.eINSTANCE.getPluginConfiguration(), serializerOid, OldQuery.getDefault());
final long totalSize = revision.getSize();
final AtomicLong total = new AtomicLong();
IfcModelSet ifcModelSet = new IfcModelSet();
PackageMetaData lastPackageMetaData = null;
for (ConcreteRevision subRevision : revision.getConcreteRevisions()) {
PackageMetaData packageMetaData = getBimServer().getMetaDataManager().getPackageMetaData(subRevision.getProject().getSchema());
lastPackageMetaData = packageMetaData;
IfcModel subModel = new BasicIfcModel(packageMetaData, null);
int highestStopId = findHighestStopRid(project, subRevision);
OldQuery query = new OldQuery(packageMetaData, subRevision.getProject().getId(), subRevision.getId(), revision.getOid(), Deep.YES, highestStopId);
subModel.addChangeListener(new IfcModelChangeListener() {
@Override
public void objectAdded(IdEObject idEObject) {
total.incrementAndGet();
if (totalSize == 0) {
setProgress("Preparing checkout...", 0);
} else {
setProgress("Preparing checkout...", (int) Math.round(100.0 * total.get() / totalSize));
}
}
});
getDatabaseSession().getMap(subModel, query);
try {
checkGeometry(serializerPluginConfiguration, getBimServer().getPluginManager(), subModel, project, subRevision, revision);
} catch (GeometryGeneratingException e) {
throw new UserException(e);
}
subModel.getModelMetaData().setDate(subRevision.getDate());
ifcModelSet.add(subModel);
}
IfcModelInterface ifcModel = new BasicIfcModel(lastPackageMetaData, null);
if (ifcModelSet.size() > 1) {
try {
ifcModel = getBimServer().getMergerFactory().createMerger(getDatabaseSession(), getAuthorization().getUoid()).merge(revision.getProject(), ifcModelSet, new ModelHelper(getBimServer().getMetaDataManager(), ifcModel));
} catch (MergeException e) {
throw new UserException(e);
}
} else {
ifcModel = ifcModelSet.iterator().next();
}
ifcModel.getModelMetaData().setName(project.getName() + "." + revision.getId());
ifcModel.getModelMetaData().setRevisionId(project.getRevisions().indexOf(revision) + 1);
ifcModel.getModelMetaData().setAuthorizedUser(user.getName());
ifcModel.getModelMetaData().setDate(new Date());
return (IfcModel) ifcModel;
}
use of org.bimserver.GeometryGeneratingException in project BIMserver by opensourceBIM.
the class StreamingGeometryGenerator method generateGeometry.
@SuppressWarnings("unchecked")
public GenerateGeometryResult generateGeometry(long uoid, final DatabaseSession databaseSession, QueryContext queryContext, long nrObjects) throws BimserverDatabaseException, GeometryGeneratingException {
GenerateGeometryResult generateGeometryResult = new GenerateGeometryResult();
packageMetaData = queryContext.getPackageMetaData();
productClass = packageMetaData.getEClass("IfcProduct");
geometryFeature = (EReference) productClass.getEStructuralFeature("geometry");
representationFeature = productClass.getEStructuralFeature("Representation");
representationsFeature = packageMetaData.getEClass("IfcProductDefinitionShape").getEStructuralFeature("Representations");
itemsFeature = packageMetaData.getEClass("IfcShapeRepresentation").getEStructuralFeature("Items");
mappingSourceFeature = packageMetaData.getEClass("IfcMappedItem").getEStructuralFeature("MappingSource");
GregorianCalendar now = new GregorianCalendar();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
debugIdentifier = dateFormat.format(now.getTime()) + " (" + report.getOriginalIfcFileName() + ")";
long start = System.nanoTime();
String pluginName = "";
if (queryContext.getPackageMetaData().getSchema() == Schema.IFC4) {
pluginName = "org.bimserver.ifc.step.serializer.Ifc4StepStreamingSerializerPlugin";
} else if (queryContext.getPackageMetaData().getSchema() == Schema.IFC2X3TC1) {
pluginName = "org.bimserver.ifc.step.serializer.Ifc2x3tc1StepStreamingSerializerPlugin";
} else {
throw new GeometryGeneratingException("Unknown schema " + queryContext.getPackageMetaData().getSchema());
}
reuseGeometry = bimServer.getServerSettingsCache().getServerSettings().isReuseGeometry();
optimizeMappedItems = bimServer.getServerSettingsCache().getServerSettings().isOptimizeMappedItems();
report.setStart(new GregorianCalendar());
report.setIfcSchema(queryContext.getPackageMetaData().getSchema());
report.setUseMappingOptimization(optimizeMappedItems);
report.setReuseGeometry(reuseGeometry);
try {
final StreamingSerializerPlugin ifcSerializerPlugin = (StreamingSerializerPlugin) bimServer.getPluginManager().getPlugin(pluginName, true);
if (ifcSerializerPlugin == null) {
throw new UserException("No IFC serializer found");
}
User user = (User) databaseSession.get(uoid, org.bimserver.database.OldQuery.getDefault());
UserSettings userSettings = user.getUserSettings();
report.setUserName(user.getName());
report.setUserUserName(user.getUsername());
RenderEnginePluginConfiguration renderEngine = null;
if (eoid != -1) {
renderEngine = databaseSession.get(eoid, OldQuery.getDefault());
} else {
renderEngine = userSettings.getDefaultRenderEngine();
}
if (renderEngine == null) {
throw new UserException("No default render engine has been selected for this user");
}
renderEngineName = renderEngine.getName();
int availableProcessors = Runtime.getRuntime().availableProcessors();
report.setAvailableProcessors(availableProcessors);
int maxSimultanousThreads = Math.min(bimServer.getServerSettingsCache().getServerSettings().getRenderEngineProcesses(), availableProcessors);
if (maxSimultanousThreads < 1) {
maxSimultanousThreads = 1;
}
final RenderEngineSettings settings = new RenderEngineSettings();
settings.setPrecision(Precision.SINGLE);
settings.setIndexFormat(IndexFormat.AUTO_DETECT);
settings.setGenerateNormals(true);
settings.setGenerateTriangles(true);
settings.setGenerateWireFrame(false);
final RenderEngineFilter renderEngineFilter = new RenderEngineFilter();
RenderEnginePool renderEnginePool = bimServer.getRenderEnginePools().getRenderEnginePool(packageMetaData.getSchema(), renderEngine.getPluginDescriptor().getPluginClassName(), bimServer.getPluginSettingsCache().getPluginSettings(renderEngine.getOid()));
report.setRenderEngineName(renderEngine.getName());
report.setRenderEnginePluginVersion(renderEngine.getPluginDescriptor().getPluginBundleVersion().getVersion());
VersionInfo versionInfo = renderEnginePool.getRenderEngineFactory().getVersionInfo();
report.setRenderEngineVersion(versionInfo);
// TODO there must be a cleaner way of getting this info, since it's in the database...
RenderEngine engine = renderEnginePool.borrowObject();
try {
applyLayerSets = engine.isApplyLayerSets();
report.setApplyLayersets(applyLayerSets);
calculateQuantities = engine.isCalculateQuantities();
report.setCalculateQuantities(calculateQuantities);
} finally {
renderEnginePool.returnObject(engine);
}
// TODO reuse, pool the pools :) Or something smarter
// TODO reuse queue, or try to determine a realistic size, or don't use a fixed-size queue
ThreadPoolExecutor executor = new ThreadPoolExecutor(maxSimultanousThreads, maxSimultanousThreads, 24, TimeUnit.HOURS, new ArrayBlockingQueue<Runnable>(10000000));
JsonQueryObjectModelConverter jsonQueryObjectModelConverter = new JsonQueryObjectModelConverter(packageMetaData);
String queryNameSpace = packageMetaData.getSchema().name().toLowerCase() + "-stdlib";
// All references should already be direct, since this is now done in BimServer on startup, quite the hack...
Include objectPlacement = jsonQueryObjectModelConverter.getDefineFromFile(queryNameSpace + ":ObjectPlacement", true);
Set<EClass> classes = null;
if (queryContext.getOidCounters() != null) {
classes = queryContext.getOidCounters().keySet();
} else {
classes = packageMetaData.getEClasses();
}
float multiplierToMm = processUnits(databaseSession, queryContext);
generateGeometryResult.setMultiplierToMm(multiplierToMm);
// Phase 1 (mapped item detection) sometimes detects that mapped items have invalid (unsupported) RepresentationIdentifier values, this set keeps track of objects to skip in Phase 2 because of that
Set<Long> toSkip = new HashSet<>();
// Less than 100 objects -> Use 1 object per process (so we have progress indication per 1%)
// More than 100 objects -> Use # objects / 100 objects per process
// Unless the amount of objects becomes > 100 / process, than cap it on 100
int regularObjectCount = 0;
Set<EClass> typesToDo = new HashSet<>();
Set<Long> done = new HashSet<>();
for (EClass eClass : classes) {
if (packageMetaData.getEClass("IfcProduct").isSuperTypeOf(eClass)) {
Query query2 = new Query(eClass.getName() + "Main query", packageMetaData);
QueryPart queryPart2 = query2.createQueryPart();
queryPart2.addType(eClass, false);
Include representationInclude = queryPart2.createInclude();
representationInclude.addType(eClass, false);
representationInclude.addFieldDirect("Representation");
Include representationsInclude = representationInclude.createInclude();
representationsInclude.addType(packageMetaData.getEClass("IfcProductRepresentation"), true);
representationsInclude.addFieldDirect("Representations");
Include itemsInclude = representationsInclude.createInclude();
itemsInclude.addType(packageMetaData.getEClass("IfcShapeRepresentation"), false);
itemsInclude.addFieldDirect("Items");
itemsInclude.addFieldDirect("ContextOfItems");
Include mappingSourceInclude = itemsInclude.createInclude();
mappingSourceInclude.addType(packageMetaData.getEClass("IfcMappedItem"), false);
mappingSourceInclude.addFieldDirect("MappingSource");
mappingSourceInclude.addFieldDirect("MappingTarget");
Include representationMap = mappingSourceInclude.createInclude();
representationMap.addType(packageMetaData.getEClass("IfcRepresentationMap"), false);
representationMap.addFieldDirect("MappedRepresentation");
Include createInclude = representationMap.createInclude();
createInclude.addType(packageMetaData.getEClass("IfcShapeRepresentation"), true);
Include targetInclude = mappingSourceInclude.createInclude();
targetInclude.addType(packageMetaData.getEClass("IfcCartesianTransformationOperator3D"), false);
targetInclude.addFieldDirect("Axis1");
targetInclude.addFieldDirect("Axis2");
targetInclude.addFieldDirect("Axis3");
targetInclude.addFieldDirect("LocalOrigin");
queryPart2.addInclude(objectPlacement);
Map<Long, Map<Long, ProductDef>> representationMapToProduct = new HashMap<>();
QueryObjectProvider queryObjectProvider2 = new QueryObjectProvider(databaseSession, bimServer, query2, Collections.singleton(queryContext.getRoid()), packageMetaData);
HashMapVirtualObject next = queryObjectProvider2.next();
while (next != null) {
if (next.eClass() == eClass) {
AbstractHashMapVirtualObject representation = next.getDirectFeature(representationFeature);
if (representation != null) {
Set<HashMapVirtualObject> representations = representation.getDirectListFeature(representationsFeature);
if (representations != null) {
boolean foundValidContext = false;
for (HashMapVirtualObject representationItem : representations) {
if (usableContext(representationItem)) {
foundValidContext = true;
break;
}
}
boolean stop = false;
Set<String> counts = new HashSet<>();
for (HashMapVirtualObject representationItem : representations) {
String representationIdentifier = (String) representationItem.get("RepresentationIdentifier");
if (counts.contains(representationIdentifier)) {
stop = true;
} else {
counts.add(representationIdentifier);
}
}
if (stop) {
next = queryObjectProvider2.next();
continue;
}
for (HashMapVirtualObject representationItem : representations) {
if (!usableContext(representationItem) && foundValidContext) {
continue;
}
if (hasValidRepresentationIdentifier(representationItem)) {
Set<HashMapVirtualObject> items = representationItem.getDirectListFeature(itemsFeature);
if (items == null || items.size() > 1) {
// Only if there is just one item, we'll store this for reuse
// TODO actually we could store them for > 1 as well, only they should only be used (2nd stage) for products that use the exact same items, for now
regularObjectCount++;
continue;
}
// So this next loop always results in 1 (or no) loops
for (HashMapVirtualObject item : items) {
report.addRepresentationItem(item.eClass().getName());
if (!packageMetaData.getEClass("IfcMappedItem").isSuperTypeOf(item.eClass())) {
regularObjectCount++;
// All non IfcMappedItem objects will be done in phase 2
continue;
}
AbstractHashMapVirtualObject mappingTarget = item.getDirectFeature(packageMetaData.getEReference("IfcMappedItem", "MappingTarget"));
AbstractHashMapVirtualObject mappingSourceOfMappedItem = item.getDirectFeature(packageMetaData.getEReference("IfcMappedItem", "MappingSource"));
if (mappingSourceOfMappedItem == null) {
LOGGER.info("No mapping source");
continue;
}
AbstractHashMapVirtualObject mappedRepresentation = mappingSourceOfMappedItem.getDirectFeature(packageMetaData.getEReference("IfcRepresentationMap", "MappedRepresentation"));
if (!hasValidRepresentationIdentifier(mappedRepresentation)) {
// Skip this mapping, we should store somewhere that this object should also be skipped in the normal way
String identifier = (String) mappedRepresentation.get("RepresentationIdentifier");
report.addSkippedBecauseOfInvalidRepresentationIdentifier(identifier);
toSkip.add(next.getOid());
continue;
}
double[] mappingMatrix = Matrix.identity();
double[] productMatrix = Matrix.identity();
if (mappingTarget != null) {
AbstractHashMapVirtualObject axis1 = mappingTarget.getDirectFeature(packageMetaData.getEReference("IfcCartesianTransformationOperator", "Axis1"));
AbstractHashMapVirtualObject axis2 = mappingTarget.getDirectFeature(packageMetaData.getEReference("IfcCartesianTransformationOperator", "Axis2"));
AbstractHashMapVirtualObject axis3 = mappingTarget.getDirectFeature(packageMetaData.getEReference("IfcCartesianTransformationOperator3D", "Axis3"));
AbstractHashMapVirtualObject localOrigin = mappingTarget.getDirectFeature(packageMetaData.getEReference("IfcCartesianTransformationOperator", "LocalOrigin"));
double[] a1 = null;
double[] a2 = null;
double[] a3 = null;
if (axis3 != null) {
List<Double> list = (List<Double>) axis3.get("DirectionRatios");
a3 = new double[] { list.get(0), list.get(1), list.get(2) };
Vector.normalize(a3);
} else {
a3 = new double[] { 0, 0, 1 };
}
if (axis1 != null) {
List<Double> list = (List<Double>) axis1.get("DirectionRatios");
a1 = new double[] { list.get(0), list.get(1), list.get(2) };
Vector.normalize(a1);
} else {
if (a3[0] == 1 && a3[1] == 0 && a3[2] == 0) {
a1 = new double[] { 0, 1, 0 };
} else {
a1 = new double[] { 1, 0, 0 };
}
}
double[] xVec = Vector.scalarProduct(Vector.dot(a1, a3), a3);
double[] xAxis = Vector.subtract(a1, xVec);
Vector.normalize(xAxis);
if (axis2 != null) {
List<Double> list = (List<Double>) axis2.get("DirectionRatios");
a2 = new double[] { list.get(0), list.get(1), list.get(2) };
Vector.normalize(a2);
} else {
a2 = new double[] { 0, 1, 0 };
}
double[] tmp = Vector.scalarProduct(Vector.dot(a2, a3), a3);
double[] yAxis = Vector.subtract(a2, tmp);
tmp = Vector.scalarProduct(Vector.dot(a2, xAxis), xAxis);
yAxis = Vector.subtract(yAxis, tmp);
Vector.normalize(yAxis);
a2 = yAxis;
a1 = xAxis;
List<Double> t = (List<Double>) localOrigin.get("Coordinates");
mappingMatrix = new double[] { a1[0], a1[1], a1[2], 0, a2[0], a2[1], a2[2], 0, a3[0], a3[1], a3[2], 0, t.get(0).doubleValue(), t.get(1).doubleValue(), t.get(2).doubleValue(), 1 };
}
AbstractHashMapVirtualObject placement = next.getDirectFeature(packageMetaData.getEReference("IfcProduct", "ObjectPlacement"));
if (placement != null) {
productMatrix = placementToMatrix(placement);
}
AbstractHashMapVirtualObject mappingSource = item.getDirectFeature(mappingSourceFeature);
if (mappingSource != null) {
Map<Long, ProductDef> map = representationMapToProduct.get(((HashMapVirtualObject) mappingSource).getOid());
if (map == null) {
map = new LinkedHashMap<>();
representationMapToProduct.put(((HashMapVirtualObject) mappingSource).getOid(), map);
}
ProductDef pd = new ProductDef(next.getOid());
pd.setMappedItemOid(item.getOid());
pd.setObject(next);
pd.setProductMatrix(productMatrix);
pd.setMappingMatrix(mappingMatrix);
pd.setRepresentationOid(representationItem.getOid());
map.put(next.getOid(), pd);
}
}
} else {
report.addSkippedBecauseOfInvalidRepresentationIdentifier((String) representationItem.get("RepresentationIdentifier"));
}
}
}
}
}
next = queryObjectProvider2.next();
}
for (Long repMapId : representationMapToProduct.keySet()) {
Map<Long, ProductDef> map = representationMapToProduct.get(repMapId);
// When there is more than one instance using this mapping
if (map.size() > 1) {
Query query = new Query("Reuse query " + eClass.getName(), packageMetaData);
query.setDoubleBuffer(true);
QueryPart queryPart = query.createQueryPart();
// QueryPart queryPart3 = query.createQueryPart();
queryPart.addType(eClass, false);
// queryPart3.addType(packageMetaData.getEClass("IfcMappedItem"), false);
long masterOid = map.values().iterator().next().getOid();
double[] inverted = Matrix.identity();
ProductDef masterProductDef = map.get(masterOid);
if (!Matrix.invertM(inverted, 0, masterProductDef.getMappingMatrix(), 0)) {
LOGGER.debug("No inverse, this mapping will be skipped and processed as normal");
// TODO we should however be able to squeeze out a little more reuse by finding another master...
continue;
}
Set<Long> representationOids = new HashSet<>();
for (ProductDef pd : map.values()) {
done.add(pd.getOid());
if (!optimizeMappedItems) {
queryPart.addOid(pd.getOid());
representationOids.add(pd.getRepresentationOid());
// In theory these should be fused together during querying
// queryPart3.addOid(pd.getMappedItemOid());
} else {
pd.setMasterOid(masterOid);
}
}
if (optimizeMappedItems) {
queryPart.addOid(masterOid);
representationOids.add(masterProductDef.getRepresentationOid());
}
LOGGER.debug("Running " + map.size() + " objects in one batch because of reused geometry " + (eClass.getName()));
// queryPart3.addInclude(jsonQueryObjectModelConverter.getDefineFromFile("ifc2x3tc1-stdlib:IfcMappedItem"));
processQuery(databaseSession, queryContext, generateGeometryResult, ifcSerializerPlugin, settings, renderEngineFilter, renderEnginePool, executor, eClass, query, queryPart, true, map, map.size(), representationOids);
}
}
typesToDo.add(eClass);
}
}
// LOGGER.info("Regular object count: " + regularObjectCount);
int maxObjectsPerFile = regularObjectCount / 100;
if (regularObjectCount < 100) {
maxObjectsPerFile = 1;
}
if (maxObjectsPerFile > 100) {
maxObjectsPerFile = 100;
}
// maxObjectsPerFile = 1;
report.setMaxPerFile(maxObjectsPerFile);
for (EClass eClass : typesToDo) {
Query query3 = new Query("Remaining " + eClass.getName(), packageMetaData);
QueryPart queryPart3 = query3.createQueryPart();
queryPart3.addType(eClass, false);
Include include3 = queryPart3.createInclude();
include3.addType(eClass, false);
include3.addFieldDirect("Representation");
Include rInclude = include3.createInclude();
rInclude.addType(packageMetaData.getEClass("IfcProductRepresentation"), true);
rInclude.addFieldDirect("Representations");
Include representationsInclude2 = rInclude.createInclude();
representationsInclude2.addType(packageMetaData.getEClass("IfcShapeModel"), true);
representationsInclude2.addFieldDirect("ContextOfItems");
Query query = new Query("Main " + eClass.getName(), packageMetaData);
query.setDoubleBuffer(true);
QueryPart queryPart = query.createQueryPart();
int written = 0;
QueryObjectProvider queryObjectProvider2 = new QueryObjectProvider(databaseSession, bimServer, query3, Collections.singleton(queryContext.getRoid()), packageMetaData);
HashMapVirtualObject next = queryObjectProvider2.next();
Set<Long> representationOids = new HashSet<>();
while (next != null) {
// Not sure why the duplicate code in the next 20 lines
if (next.eClass() == eClass && !done.contains(next.getOid()) && !toSkip.contains(next.getOid())) {
AbstractHashMapVirtualObject representation = next.getDirectFeature(representationFeature);
if (representation != null) {
Set<HashMapVirtualObject> list = representation.getDirectListFeature(packageMetaData.getEReference("IfcProductRepresentation", "Representations"));
Set<Long> goForIt = goForIt(list);
if (!goForIt.isEmpty()) {
if (next.eClass() == eClass && !done.contains(next.getOid())) {
representation = next.getDirectFeature(representationFeature);
if (representation != null) {
list = representation.getDirectListFeature(packageMetaData.getEReference("IfcProductRepresentation", "Representations"));
Set<Long> goForIt2 = goForIt(list);
if (!goForIt2.isEmpty()) {
queryPart.addOid(next.getOid());
representationOids.addAll(goForIt2);
written++;
if (written >= maxObjectsPerFile) {
processQuery(databaseSession, queryContext, generateGeometryResult, ifcSerializerPlugin, settings, renderEngineFilter, renderEnginePool, executor, eClass, query, queryPart, false, null, written, representationOids);
query = new Query("Main " + eClass.getName(), packageMetaData);
query.setDoubleBuffer(true);
queryPart = query.createQueryPart();
written = 0;
representationOids.clear();
}
}
}
}
}
}
}
next = queryObjectProvider2.next();
}
if (written > 0) {
processQuery(databaseSession, queryContext, generateGeometryResult, ifcSerializerPlugin, settings, renderEngineFilter, renderEnginePool, executor, eClass, query, queryPart, false, null, written, representationOids);
}
}
allJobsPushed = true;
executor.shutdown();
executor.awaitTermination(24, TimeUnit.HOURS);
// TODO, disable?
if (true) {
LOGGER.debug("Generating quantized vertices");
double[] quantizationMatrix = createQuantizationMatrixFromBounds(generateGeometryResult.getBoundsUntransformed(), multiplierToMm);
for (Long id : geometryDataMap.keySet()) {
Tuple<HashMapVirtualObject, ByteBuffer> tuple = geometryDataMap.get(id);
HashMapVirtualObject buffer = new HashMapVirtualObject(queryContext, GeometryPackage.eINSTANCE.getBuffer());
// Buffer buffer = databaseSession.create(Buffer.class);
buffer.set("data", quantizeVertices(tuple.getB().asDoubleBuffer(), quantizationMatrix, multiplierToMm).array());
// buffer.setData(quantizeVertices(tuple.getB(), quantizationMatrix, multiplierToMm).array());
// databaseSession.store(buffer);
buffer.save();
HashMapVirtualObject geometryData = tuple.getA();
geometryData.set("verticesQuantized", buffer.getOid());
int reused = (int) geometryData.eGet(GeometryPackage.eINSTANCE.getGeometryData_Reused());
int nrTriangles = (int) geometryData.eGet(GeometryPackage.eINSTANCE.getGeometryData_NrIndices()) / 3;
int saveableTriangles = Math.max(0, (reused - 1)) * nrTriangles;
geometryData.set("saveableTriangles", saveableTriangles);
// if (saveableTriangles > 0) {
// System.out.println("Saveable triangles: " + saveableTriangles);
// }
geometryData.saveOverwrite();
}
}
long end = System.nanoTime();
long total = totalBytes.get() - (bytesSavedByHash.get() + bytesSavedByTransformation.get() + bytesSavedByMapping.get());
LOGGER.info("Rendertime: " + Formatters.nanosToString(end - start) + ", " + "Reused (by hash): " + Formatters.bytesToString(bytesSavedByHash.get()) + ", Reused (by transformation): " + Formatters.bytesToString(bytesSavedByTransformation.get()) + ", Reused (by mapping): " + Formatters.bytesToString(bytesSavedByMapping.get()) + ", Total: " + Formatters.bytesToString(totalBytes.get()) + ", Final: " + Formatters.bytesToString(total));
if (report.getNumberOfDebugFiles() > 0) {
LOGGER.error("[" + report.getOriginalIfcFileName() + "] Number of erroneous files: " + report.getNumberOfDebugFiles());
}
SkippedBecauseOfInvalidRepresentation skipped = report.getSkippedBecauseOfInvalidRepresentationIdentifier();
if (skipped.hasImportant()) {
LOGGER.warn("[" + report.getOriginalIfcFileName() + "] Number of representations skipped:");
for (String identifier : skipped.getImportantSet()) {
LOGGER.warn("\t" + identifier + ": " + skipped.get(identifier));
}
}
String dump = geometryGenerationDebugger.dump();
if (dump != null) {
LOGGER.info(dump);
}
} catch (Exception e) {
running = false;
LOGGER.error("", e);
report.setEnd(new GregorianCalendar());
throw new GeometryGeneratingException(e);
}
report.setEnd(new GregorianCalendar());
try {
if (report.getNumberOfDebugFiles() > 0) {
writeDebugFile();
}
} catch (IOException e) {
LOGGER.debug("", e);
}
return generateGeometryResult;
}
Aggregations