├── .classpath
├── .gitignore
├── .project
├── .settings
├── org.eclipse.core.resources.prefs
├── org.eclipse.jdt.core.prefs
└── org.eclipse.m2e.core.prefs
├── README.md
├── build
└── build.xml
├── license.txt
├── plugin
├── icon.png
├── plugin.xml
└── version.properties
├── pom.xml
└── src
└── org
└── ifcopenshell
├── ClientRunner.java
├── IfcGeomServerClient.java
├── IfcGeomServerClientEntity.java
├── IfcOpenShellEngine.java
├── IfcOpenShellEnginePlugin.java
├── IfcOpenShellEntityInstance.java
└── IfcOpenShellModel.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /bin
2 | /target/
3 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | IfcOpenShellPlugin
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.m2e.core.maven2Builder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.m2e.core.maven2Nature
21 | org.eclipse.jdt.core.javanature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | encoding/=UTF-8
3 | encoding/plugin=UTF-8
4 | encoding/src=UTF-8
5 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
3 | org.eclipse.jdt.core.compiler.compliance=1.8
4 | org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
5 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
6 | org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
7 | org.eclipse.jdt.core.compiler.release=disabled
8 | org.eclipse.jdt.core.compiler.source=1.8
9 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.m2e.core.prefs:
--------------------------------------------------------------------------------
1 | activeProfiles=
2 | eclipse.preferences.version=1
3 | resolveWorkspaceProjects=true
4 | version=1
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | IfcOpenShell-BIMserver-plugin
2 | =============================
3 |
4 | IfcOpenShell BIMserver plugin
5 |
6 | Occasional problems and solutions
7 | -----------------
8 |
9 | ### The 3D view does not show anything
10 | If you see `org.bimserver.plugins.renderengine.RenderEngineException: java.io.EOFException` in the geometry generation report, have a look at [BIMserver issue #633](https://github.com/opensourceBIM/BIMserver/issues/633) for a possible reason and [solution](https://github.com/opensourceBIM/BIMserver/issues/633#issuecomment-341644945). Updating gcc and libstdc++ may solve the issue.
11 |
12 | ### Some products are missing from the 3D view
13 | If you see `java.lang.Exception: Missing objects in model` in the geometry generation report, IfcOpenShell was not able to generate geometry for these products. This may happen when you use an older version of IfcOpenShell. In that case it may help to update IfcOpenShell to a newer version through the "build version" (previously "commit sha") plugin setting as described in [BIMserver issue #1207](https://github.com/opensourceBIM/BIMserver/issues/1207#issuecomment-878117652).
14 |
--------------------------------------------------------------------------------
/build/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | Copyright (C) 2009-2019 BIMserver.org
2 |
3 | This program is free software: you can redistribute it and/or modify
4 | it under the terms of the GNU Affero General Public License as
5 | published by the Free Software Foundation, either version 3 of the
6 | License, or (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU Affero General Public License for more details.
12 |
13 | You should have received a copy of the GNU Affero General Public License
14 | along with this program. If not, see {@literal}.
--------------------------------------------------------------------------------
/plugin/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opensourceBIM/IfcOpenShell-BIMserver-plugin/e18dd518330518783211e17f93c74fd78bde7c1f/plugin/icon.png
--------------------------------------------------------------------------------
/plugin/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | org.bimserver.plugins.renderengine.RenderEnginePlugin
5 | org.ifcopenshell.IfcOpenShellEnginePlugin
6 | Open source IFC geometry engine visit <a href='http://ifcopenshell.org'>ifcopenshell.org</a>
7 | IfcOpenShell
8 |
9 |
--------------------------------------------------------------------------------
/plugin/version.properties:
--------------------------------------------------------------------------------
1 | build.date=${timestamp}
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | org.opensourcebim
5 | ifcopenshellplugin
6 | 0.5.97-SNAPSHOT
7 | IfcOpenShell-BIMserver-plugin
8 | BIMserver plugin that uses IfcOpenShell to generate geometry from IFC files
9 | https://github.com/opensourceBIM/IfcOpenShell-BIMserver-plugin
10 |
11 | OpenSource BIM
12 | opensourcebim.org
13 |
14 |
15 |
16 | GNU Affero General Public License
17 | http://www.gnu.org/licenses/agpl-3.0.en.html
18 | repo
19 |
20 |
21 |
22 |
23 | Ruben de Laat
24 | ruben@logic-labs.nl
25 |
26 |
27 |
28 | scm:git:https://github.com/opensourceBIM/IfcOpenShell-BIMserver-plugin.git
29 | scm:git:https://github.com/opensourceBIM/IfcOpenShell-BIMserver-plugin.git
30 | https://github.com/opensourceBIM/IfcOpenShell-BIMserver-plugin.git
31 | HEAD
32 |
33 |
34 | GitHub
35 | https://github.com/opensourceBIM/IfcOpenShell-BIMserver-plugin/issues
36 |
37 |
38 |
39 | ossrh
40 | https://oss.sonatype.org/service/local/staging/deploy/maven2/
41 |
42 |
43 | ossrh
44 | https://oss.sonatype.org/content/repositories/snapshots
45 |
46 |
47 |
48 | yyyy-MM-dd'T'HH:mm:ssZ
49 | UTF-8
50 | ${maven.build.timestamp}
51 |
52 |
53 |
54 | org.opensourcebim
55 | pluginbase
56 | 1.5.187
57 |
58 |
59 |
60 |
61 | central
62 | https://repo1.maven.org/maven2
63 |
64 |
65 |
66 | src
67 |
68 |
69 | plugin
70 | true
71 | plugin
72 |
73 |
74 | img
75 | img
76 |
77 |
78 |
79 |
80 | org.codehaus.mojo
81 | build-helper-maven-plugin
82 | 3.6.0
83 |
84 |
85 | attach-plugin
86 | package
87 |
88 | attach-artifact
89 |
90 |
91 |
92 |
93 | plugin/plugin.xml
94 | xml
95 | plugin
96 |
97 |
98 | plugin/icon.png
99 | png
100 | icon
101 |
102 |
103 | ${project.build.outputDirectory}/plugin/version.properties
104 | properties
105 | version
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | maven-compiler-plugin
114 | 3.10.1
115 |
116 | 8
117 |
118 |
119 |
120 | org.sonatype.plugins
121 | nexus-staging-maven-plugin
122 | 1.6.3
123 | true
124 |
125 | ossrh
126 | https://oss.sonatype.org/
127 | false
128 |
129 |
130 |
131 | maven-release-plugin
132 | 2.5.3
133 |
134 |
135 | pom.xml
136 |
137 | false
138 | release
139 | deploy
140 |
141 |
142 |
143 |
144 |
145 |
146 | release
147 |
148 |
149 |
150 | maven-gpg-plugin
151 | 1.5
152 |
153 |
154 | sign-artifacts
155 | verify
156 |
157 | sign
158 |
159 |
160 |
161 | --pinentry-mode
162 | loopback
163 |
164 | ${gpg.keyname}
165 |
166 |
167 |
168 |
169 |
170 | maven-javadoc-plugin
171 | 3.11.2
172 |
173 |
174 | attach-javadocs
175 |
176 | jar
177 |
178 |
179 |
180 |
181 |
182 | maven-source-plugin
183 | 2.4
184 |
185 |
186 | attach-javadocs
187 |
188 | jar
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
--------------------------------------------------------------------------------
/src/org/ifcopenshell/ClientRunner.java:
--------------------------------------------------------------------------------
1 | package org.ifcopenshell;
2 |
3 | /******************************************************************************
4 | * Copyright (C) 2009-2019 BIMserver.org
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Affero General Public License as
8 | * published by the Free Software Foundation, either version 3 of the
9 | * License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Affero General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Affero General Public License
17 | * along with this program. If not, see {@literal}.
18 | *****************************************************************************/
19 |
20 | import java.io.FileInputStream;
21 | import java.io.FileNotFoundException;
22 |
23 | import org.bimserver.plugins.renderengine.RenderEngineException;
24 | import org.bimserver.plugins.renderengine.RenderEngineGeometry;
25 |
26 | public class ClientRunner {
27 |
28 | public static void main(String [] args)
29 | {
30 | try (IfcGeomServerClient client = new IfcGeomServerClient(IfcGeomServerClient.ExecutableSource.S3, IfcOpenShellEnginePlugin.DEFAULT_BUILD_VERSION)) {
31 | try {
32 | client.setCalculateQuantities(true);
33 | } catch (RenderEngineException e1) {
34 | e1.printStackTrace();
35 | }
36 | try {
37 | client.setApplyLayersets(true);
38 | } catch (RenderEngineException e1) {
39 | e1.printStackTrace();
40 | }
41 |
42 | try {
43 | client.loadModel(new FileInputStream(args[0]));
44 | } catch (FileNotFoundException | RenderEngineException e) {
45 | e.printStackTrace();
46 | return;
47 | }
48 |
49 | double t0 = java.lang.System.nanoTime();
50 |
51 | while (client.hasNext()) {
52 | try {
53 | IfcGeomServerClientEntity instance = client.getNext();
54 | if (instance == null) {
55 | System.out.println("Internal error");
56 | return;
57 | }
58 | System.out.println(String.format("%s %s", instance.getType(), instance.getGuid()));
59 | System.out.println(instance.getAllExtendedData().toString());
60 | RenderEngineGeometry geometry = new RenderEngineGeometry(instance.getIndices(), instance.getPositions(), instance.getNormals(), instance.getColors(), instance.getMaterialIndices());
61 | System.out.println(String.format("Vertex buffer size: %d", geometry.getNrVertices()));
62 | System.out.println(String.format("Normal buffer size: %d", geometry.getNrNormals()));
63 | System.out.println(String.format("Index buffer size: %d", geometry.getNrIndices()));
64 | System.out.println(String.format("Material buffer size: %d", geometry.getNrMaterials()));
65 | System.out.println(String.format("Material index buffer size: %d", geometry.getNrMaterialIndices()));
66 | } catch (RenderEngineException e) {
67 | e.printStackTrace();
68 | return;
69 | }
70 | }
71 |
72 | System.out.println(String.format("Conversion took %.2f seconds", (java.lang.System.nanoTime() - t0) / 1.e9));
73 |
74 | } catch (RenderEngineException e) {
75 | e.printStackTrace();
76 | return;
77 | }
78 | System.exit(0);
79 | }
80 | }
--------------------------------------------------------------------------------
/src/org/ifcopenshell/IfcGeomServerClient.java:
--------------------------------------------------------------------------------
1 | package org.ifcopenshell;
2 |
3 | /******************************************************************************
4 | * Copyright (C) 2009-2019 BIMserver.org
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Affero General Public License as
8 | * published by the Free Software Foundation, either version 3 of the
9 | * License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Affero General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Affero General Public License
17 | * along with this program. If not, see {@literal}.
18 | *****************************************************************************/
19 |
20 | import java.io.ByteArrayInputStream;
21 | import java.io.ByteArrayOutputStream;
22 | import java.io.File;
23 | import java.io.IOException;
24 | import java.io.InputStream;
25 | import java.io.OutputStream;
26 | import java.net.URISyntaxException;
27 | import java.net.URL;
28 | import java.nio.ByteBuffer;
29 | import java.nio.ByteOrder;
30 | import java.nio.DoubleBuffer;
31 | import java.nio.FloatBuffer;
32 | import java.nio.file.Files;
33 | import java.nio.file.Path;
34 | import java.nio.file.Paths;
35 | import java.nio.file.attribute.FileTime;
36 | import java.nio.file.attribute.PosixFilePermission;
37 | import java.util.GregorianCalendar;
38 | import java.util.HashSet;
39 | import java.util.Set;
40 | import java.util.zip.ZipInputStream;
41 |
42 | import org.apache.commons.io.IOUtils;
43 | import org.apache.http.Header;
44 | import org.apache.http.client.methods.CloseableHttpResponse;
45 | import org.apache.http.client.methods.HttpGet;
46 | import org.apache.http.client.utils.DateUtils;
47 | import org.apache.http.impl.client.CloseableHttpClient;
48 | import org.apache.http.impl.client.HttpClients;
49 | import org.bimserver.plugins.renderengine.RenderEngineException;
50 | import org.bimserver.shared.exceptions.PluginException;
51 | import org.slf4j.Logger;
52 | import org.slf4j.LoggerFactory;
53 |
54 | import com.google.common.base.Charsets;
55 | import com.google.common.io.ByteStreams;
56 | import com.google.common.io.LittleEndianDataInputStream;
57 | import com.google.common.io.LittleEndianDataOutputStream;
58 |
59 | public class IfcGeomServerClient implements AutoCloseable {
60 | private static final Logger LOGGER = LoggerFactory.getLogger(IfcGeomServerClient.class);
61 |
62 | private boolean calculateQuantities = false;
63 | private boolean applyLayersets = false;
64 | private boolean disableOpeningSubtractions = false;
65 |
66 | public boolean doesCalculateQuantities() {
67 | return calculateQuantities;
68 | }
69 |
70 | public void setCalculateQuantities(boolean calculateQuantities) throws RenderEngineException {
71 | if (process != null) {
72 | throw new RenderEngineException("Cannot be changed when running");
73 | }
74 | this.calculateQuantities = calculateQuantities;
75 | }
76 |
77 | public boolean doesApplyLayersets() {
78 | return applyLayersets;
79 | }
80 |
81 | public void setApplyLayersets(boolean applyLayersets) throws RenderEngineException {
82 | if (process != null) {
83 | throw new RenderEngineException("Cannot be changed when running");
84 | }
85 | this.applyLayersets = applyLayersets;
86 | }
87 |
88 | public boolean disablesOpeningSubtractions(){
89 | return disableOpeningSubtractions;
90 | }
91 |
92 | public void setDisableOpeningSubtractions(boolean disableOpeningSubtractions) throws RenderEngineException {
93 | if (process != null) {
94 | throw new RenderEngineException("Cannot be changed when running");
95 | }
96 | this.disableOpeningSubtractions = disableOpeningSubtractions;
97 | }
98 |
99 | private Process process = null;
100 | private LittleEndianDataInputStream dis = null;
101 | private LittleEndianDataOutputStream dos = null;
102 | private boolean hasMore = false;
103 |
104 | private volatile boolean running = true;
105 |
106 | private Path executableFilename;
107 |
108 | private GregorianCalendar buildDateTime;
109 |
110 | public Path getExecutableFilename() {
111 | return executableFilename;
112 | }
113 |
114 | @Override
115 | public void close() throws RenderEngineException {
116 | running = false;
117 | terminate();
118 | }
119 |
120 | private static String getOs() throws RenderEngineException {
121 | final String os = System.getProperty("os.name").toLowerCase();
122 | if (os.contains("windows")) {
123 | return "win";
124 | } else if (os.contains("osx") || os.contains("os x") || os.contains("darwin") || os.contains("mac")) {
125 | return "osx";
126 | } else if (os.contains("linux")) {
127 | return "linux";
128 | } else {
129 | throw new RenderEngineException(String.format("IfcOpenShell is not available on the %s platorm", os));
130 | }
131 | }
132 |
133 | private static String getExecutableExtension() {
134 | final String os = System.getProperty("os.name").toLowerCase();
135 | if (os.contains("windows")) {
136 | return ".exe";
137 | } else {
138 | return "";
139 | }
140 | }
141 |
142 | public static Path getExecutablePathFromRepo(Path root) throws PluginException {
143 | final String executableName = "IfcGeomServer" + getExecutableExtension();
144 | final String operatingSystem = getOs();
145 | final String bitness = operatingSystem.equals("osx") ? "64" : System.getProperty("sun.arch.data.model");
146 |
147 | return root.resolve("exe").resolve(bitness).resolve(operatingSystem).resolve(executableName);
148 | }
149 |
150 | private Path getSourcePath() throws RenderEngineException {
151 | String name = getClass().getName();
152 | int lastDot = name.lastIndexOf(".");
153 | name = name.substring(lastDot + 1) + ".class";
154 | try {
155 | return Paths.get(this.getClass().getResource(name).toURI()).getParent().getParent().getParent().getParent().getParent();
156 | } catch (URISyntaxException e) {
157 | throw new RenderEngineException(e);
158 | }
159 | }
160 |
161 | public enum ExecutableSource {
162 | REPOSITORY, S3
163 | }
164 |
165 | public IfcGeomServerClient(ExecutableSource source, String buildVersion) throws RenderEngineException {
166 | getExecutable(source, buildVersion, Paths.get(System.getProperty("user.home")));
167 | }
168 |
169 | public IfcGeomServerClient(ExecutableSource source, String buildVersion, Path homeDir) throws RenderEngineException {
170 | getExecutable(source, buildVersion, homeDir);
171 | }
172 |
173 | private void getExecutable(ExecutableSource source, String buildVersion, Path homeDir) throws RenderEngineException {
174 | if (source == ExecutableSource.REPOSITORY) {
175 | try {
176 | this.executableFilename = getExecutablePathFromRepo(getSourcePath());
177 | FileTime fileTime = (FileTime) Files.getAttribute(this.executableFilename, "creationTime");
178 | buildDateTime = new GregorianCalendar();
179 | buildDateTime.setTimeInMillis(fileTime.toMillis());
180 | } catch (PluginException e) {
181 | throw new RenderEngineException(e);
182 | } catch (IOException e) {
183 | throw new RenderEngineException(e);
184 | }
185 | } else if (source == ExecutableSource.S3) {
186 | boolean initialized = false;
187 |
188 | String platform = getPlatform();
189 | try {
190 | String url = "https://s3.amazonaws.com/ifcopenshell-builds/IfcGeomServer-" + buildVersion + "-" + platform + ".zip";
191 |
192 | String baseName = new File(new URL(url).getPath()).getName();
193 | baseName = baseName.substring(0, baseName.length() - 4);
194 | baseName += getExecutableExtension();
195 | this.executableFilename = homeDir.resolve(baseName);
196 |
197 | if (!Files.exists(this.executableFilename)) {
198 | LOGGER.info(String.format("Downloading from %s", url));
199 | Files.createDirectories(this.executableFilename.getParent());
200 | LOGGER.info(String.format("Unzipping to %s", this.executableFilename.toString()));
201 |
202 | try (CloseableHttpClient httpClient = HttpClients.createSystem()) {
203 | HttpGet httpGet = new HttpGet(url);
204 | try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {
205 | if (httpResponse.getStatusLine().getStatusCode() == 200) {
206 | Header lastModified = httpResponse.getFirstHeader("Last-Modified");
207 | LOGGER.info("IfcOpenShell Last Modified: " + lastModified.getValue());
208 | buildDateTime = new GregorianCalendar();
209 | buildDateTime.setTime(DateUtils.parseDate(lastModified.getValue()));
210 |
211 | try (ZipInputStream zipInputStream = new ZipInputStream(httpResponse.getEntity().getContent())) {
212 | try (OutputStream fos = Files.newOutputStream(this.executableFilename)) {
213 | // tfk: assume single entry
214 | zipInputStream.getNextEntry();
215 | ByteStreams.copy(zipInputStream, fos);
216 | }
217 | }
218 |
219 | Files.setAttribute(this.executableFilename, "creationTime", FileTime.fromMillis(buildDateTime.getTimeInMillis()));
220 | } else {
221 | LOGGER.error(httpResponse.getStatusLine().toString());
222 | LOGGER.error("File not found " + url);
223 | throw new RenderEngineException("File not found " + url);
224 | }
225 | }
226 | }
227 |
228 | try {
229 | Set permissions = new HashSet<>();
230 | permissions.add(PosixFilePermission.OWNER_EXECUTE);
231 | permissions.add(PosixFilePermission.OWNER_READ);
232 | permissions.add(PosixFilePermission.OWNER_WRITE);
233 | Files.setPosixFilePermissions(this.executableFilename, permissions);
234 | } catch (Exception e) {}
235 | } else {
236 | FileTime fileTime = (FileTime) Files.getAttribute(this.executableFilename, "creationTime");
237 | buildDateTime = new GregorianCalendar();
238 | buildDateTime.setTimeInMillis(fileTime.toMillis());
239 | }
240 |
241 | initialized = true;
242 | } catch (IOException | PluginException e) {
243 | throw new RenderEngineException(e);
244 | }
245 | if (!initialized) {
246 | throw new RenderEngineException("No IfcGeomServer executable found for platform '" + platform + "'");
247 | }
248 | }
249 | }
250 |
251 | public IfcGeomServerClient(Path executableFilename) throws RenderEngineException {
252 | this.executableFilename = executableFilename;
253 | }
254 |
255 | public void initialize() throws RenderEngineException {
256 | try {
257 | process = Runtime.getRuntime().exec(new String[]{this.executableFilename.toAbsolutePath().toString()});
258 | dos = new LittleEndianDataOutputStream(process.getOutputStream());
259 | dis = new LittleEndianDataInputStream(process.getInputStream());
260 |
261 | if (dis.readInt() != HELLO) {
262 | LOGGER.error("Invalid welcome message received");
263 | terminate();
264 | return;
265 | }
266 |
267 | Hello h = new Hello();
268 | h.read(dis);
269 |
270 | boolean isV070 = h.getString().startsWith("IfcOpenShell-v0.7.0"); // https://github.com/IfcOpenShell/IfcOpenShell/commit/ff73f82798a8e744a0b7e2aaa353252df0a2934c
271 | new Setting(Setting.SettingId.CALCULATE_QUANTITITES, calculateQuantities).write(dos);
272 | new Setting(isV070 ? Setting.SettingId.APPLY_LAYERSETS_V070 : Setting.SettingId.APPLY_LAYERSETS, applyLayersets).write(dos);
273 | new Setting(isV070 ? Setting.SettingId.DISABLE_OPENING_SUBTRACTION_V070 : Setting.SettingId.DISABLE_OPENING_SUBTRACTION, disableOpeningSubtractions).write(dos);
274 | } catch (IOException e) {
275 | throw new RenderEngineException(e);
276 | }
277 | }
278 |
279 | public void loadModel(InputStream inputStream) throws RenderEngineException {
280 | if (process == null) {
281 | initialize();
282 | }
283 |
284 | IfcModel m = new IfcModel(inputStream);
285 | try {
286 | m.write(dos);
287 | askForMore();
288 | } catch (IOException e) {
289 | close();
290 | }
291 | }
292 |
293 | public void loadModel(InputStream inputStream, long length) throws RenderEngineException {
294 | if (process == null) {
295 | initialize();
296 | }
297 |
298 | IfcModel m = new IfcModel(inputStream, length);
299 | try {
300 | m.write(dos);
301 | askForMore();
302 | } catch (IOException e) {
303 | close();
304 | }
305 | }
306 |
307 | private static final int HELLO = 0xff00;
308 | private static final int IFC_MODEL = HELLO + 1;
309 | private static final int GET = IFC_MODEL + 1;
310 | private static final int ENTITY = GET + 1;
311 | private static final int MORE = ENTITY + 1;
312 | private static final int NEXT = MORE + 1;
313 | private static final int BYE = NEXT + 1;
314 | private static final int GET_LOG = BYE + 1;
315 | private static final int LOG = GET_LOG + 1;
316 | private static final int DEFLECTION = LOG + 1;
317 | private static final int SETTING = DEFLECTION + 1;
318 |
319 | private static final String PROTOCOL_VERSION = "IfcOpenShell-0.6.0b0-0";
320 |
321 | abstract static class Command {
322 | abstract void read_contents(LittleEndianDataInputStream s) throws IOException;
323 |
324 | abstract void write_contents(LittleEndianDataOutputStream s) throws IOException;
325 |
326 | int iden;
327 | int len;
328 |
329 | void read(LittleEndianDataInputStream s) throws IOException {
330 | len = s.readInt();
331 | read_contents(s);
332 | }
333 |
334 | void write(LittleEndianDataOutputStream s) throws IOException {
335 | s.writeInt(iden);
336 | ByteArrayOutputStream oss = new ByteArrayOutputStream();
337 | write_contents(new LittleEndianDataOutputStream(oss));
338 |
339 | // Comment Ruben: It seems redundant to send the size twice (when
340 | // sending a String, LittleEndianness should not change the size I
341 | // think)
342 | // Also storing the intermediate results in another buffer can be
343 | // avoided I think, why not send the original s variable to
344 | // write_contents?
345 | s.writeInt(oss.size());
346 | s.write(oss.toByteArray());
347 | s.flush();
348 | }
349 |
350 | Command(int iden) {
351 | this.iden = iden;
352 | }
353 |
354 | protected String readString(LittleEndianDataInputStream s) throws IOException {
355 | int len = s.readInt();
356 | byte[] b = new byte[len];
357 | s.readFully(b);
358 | String str = new String(b);
359 | while (len++ % 4 != 0)
360 | s.read();
361 | return str;
362 | }
363 |
364 | protected float[] readFloatArray(LittleEndianDataInputStream s) throws IOException {
365 | int len = s.readInt() / 4;
366 | float[] fs = new float[len];
367 | for (int i = 0; i < len; ++i) {
368 | fs[i] = s.readFloat();
369 | }
370 | return fs;
371 | }
372 |
373 | protected double[] readDoubleArray(LittleEndianDataInputStream s) throws IOException {
374 | int len = s.readInt() / 8;
375 | double[] fs = new double[len];
376 | for (int i = 0; i < len; ++i) {
377 | fs[i] = s.readDouble();
378 | }
379 | return fs;
380 | }
381 |
382 | protected ByteBuffer readByteBuffer(LittleEndianDataInputStream s) throws IOException {
383 | int byteLength = s.readInt();
384 | byte[] buffer = new byte[byteLength];
385 | s.readFully(buffer);
386 | return ByteBuffer.wrap(buffer);
387 | }
388 |
389 | // This method can be removed as soon as the binaries have been updated
390 | protected ByteBuffer readByteFloatToDoubleBuffer(LittleEndianDataInputStream s) throws IOException {
391 | int byteLength = s.readInt();
392 | byte[] buffer = new byte[byteLength];
393 | s.readFully(buffer);
394 | ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
395 | ByteBuffer newBuffer = ByteBuffer.allocate(buffer.length * 2);
396 | FloatBuffer floatBuffer = byteBuffer.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
397 | DoubleBuffer doubleBuffer = newBuffer.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer();
398 | int capacity = floatBuffer.capacity();
399 | for (int i=0; i 0) {
713 | LOGGER.info("\n" + log);
714 | }
715 |
716 | Bye b = new Bye();
717 | b.write(dos);
718 |
719 | if (dis.readInt() != BYE) {
720 | LOGGER.error("Invalid command sequence encountered");
721 | throw new IOException();
722 | }
723 | b.read(dis);
724 | } catch (Throwable e) {
725 | }
726 |
727 | try {
728 | // Give the executable some time to terminate by itself or kill
729 | // it after 2 seconds have passed
730 | for (int n = 0;;) {
731 | try {
732 | if (process.exitValue() != 0) {
733 | // LOGGER.error(String.format("Exited with non-zero exit
734 | // code: %d", process.exitValue()));
735 | throw new RenderEngineException(String.format("Exited with non-zero exit code: %d", process.exitValue()));
736 | }
737 | break;
738 | } catch (IllegalThreadStateException e) {
739 | if (n++ == 20) {
740 | process.destroy();
741 | LOGGER.error("Forcefully terminated IfcOpenShell process");
742 | break;
743 | }
744 | }
745 | try {
746 | Thread.sleep(100);
747 | } catch (InterruptedException e) {
748 | }
749 | }
750 | } finally {
751 | process.destroyForcibly();
752 | }
753 |
754 | dis = null;
755 | dos = null;
756 | process = null;
757 | }
758 |
759 | private void askForMore() throws IOException {
760 | hasMore = false;
761 | if (dis.readInt() != MORE) {
762 | LOGGER.error("Invalid command sequence encountered");
763 | throw new IOException();
764 | }
765 |
766 | More mr = new More();
767 | mr.read(dis);
768 |
769 | hasMore = mr.hasMore();
770 | }
771 |
772 | public IfcGeomServerClientEntity getNext() throws RenderEngineException {
773 | try {
774 | Get g = new Get();
775 | g.write(dos);
776 |
777 | if (dis.readInt() != ENTITY) {
778 | LOGGER.error("Invalid command sequence encountered");
779 | throw new IOException();
780 | }
781 | Entity e = new Entity();
782 | e.read(dis);
783 |
784 | Next n = new Next();
785 | n.write(dos);
786 |
787 | askForMore();
788 |
789 | return e.getEntity();
790 | } catch (IOException e) {
791 | terminate();
792 | return null;
793 | }
794 | }
795 |
796 | public boolean isRunning() {
797 | return running;
798 | }
799 |
800 | public boolean hasNext() {
801 | return hasMore;
802 | }
803 |
804 | public String getProtocolVersion() {
805 | return PROTOCOL_VERSION;
806 | }
807 |
808 | public GregorianCalendar getBuildDateTime() {
809 | return buildDateTime;
810 | }
811 |
812 | public String getPlatform() throws RenderEngineException {
813 | String platform = "unknown";
814 | String os = getOs();
815 |
816 | if (os == "osx") {
817 | platform = "macos64";
818 | } else {
819 | platform = os.toLowerCase() + System.getProperty("sun.arch.data.model");
820 | }
821 |
822 | return platform;
823 | }
824 | }
--------------------------------------------------------------------------------
/src/org/ifcopenshell/IfcGeomServerClientEntity.java:
--------------------------------------------------------------------------------
1 | package org.ifcopenshell;
2 |
3 | /******************************************************************************
4 | * Copyright (C) 2009-2019 BIMserver.org
5 | *
6 | * This program is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU Affero General Public License as
8 | * published by the Free Software Foundation, either version 3 of the
9 | * License, or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU Affero General Public License for more details.
15 | *
16 | * You should have received a copy of the GNU Affero General Public License
17 | * along with this program. If not, see {@literal}.
18 | *****************************************************************************/
19 |
20 | import java.io.IOException;
21 | import java.nio.ByteBuffer;
22 |
23 | /******************************************************************************
24 | * Copyright (C) 2009-2018 BIMserver.org
25 | *
26 | * This program is free software: you can redistribute it and/or modify
27 | * it under the terms of the GNU Affero General Public License as
28 | * published by the Free Software Foundation, either version 3 of the
29 | * License, or (at your option) any later version.
30 | *
31 | * This program is distributed in the hope that it will be useful,
32 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 | * GNU Affero General Public License for more details.
35 | *
36 | * You should have received a copy of the GNU Affero General Public License
37 | * along with this program. If not, see {@literal}.
38 | *****************************************************************************/
39 |
40 | import org.bimserver.geometry.Matrix;
41 | import org.bimserver.plugins.renderengine.RenderEngineException;
42 |
43 | import com.fasterxml.jackson.databind.ObjectMapper;
44 | import com.fasterxml.jackson.databind.node.ObjectNode;
45 |
46 | public class IfcGeomServerClientEntity {
47 | private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
48 | private long id;
49 | private String guid;
50 | private String name;
51 | private String type;
52 | private long parentId;
53 | private double[] matrix;
54 | private int repId;
55 | private ByteBuffer positions;
56 | private ByteBuffer normals;
57 | private ByteBuffer indices;
58 | private ByteBuffer colors;
59 | private ByteBuffer materialIndices;
60 | private ObjectNode extendedData;
61 |
62 | public IfcGeomServerClientEntity(long id, String guid, String name,
63 | String type, long parentId, double[] matrix, int repId,
64 | ByteBuffer positions, ByteBuffer normals, ByteBuffer indices, ByteBuffer colors,
65 | ByteBuffer materialIndices, String messageRemainder) {
66 | super();
67 | this.id = id;
68 | this.guid = guid;
69 | this.name = name;
70 | this.type = type;
71 | this.parentId = parentId;
72 | this.matrix = Matrix.changeOrientation(matrix);
73 | this.repId = repId;
74 | this.positions = positions;
75 | this.normals = normals;
76 | this.indices = indices;
77 | this.colors = colors;
78 | this.materialIndices = materialIndices;
79 |
80 | if (messageRemainder != null && messageRemainder.length() > 0) {
81 | // un-pad string
82 | try {
83 | this.extendedData = OBJECT_MAPPER.readValue(messageRemainder.trim(), ObjectNode.class);
84 | } catch (IOException e) {
85 | e.printStackTrace();
86 | }
87 | }
88 | }
89 |
90 | public long getId() {
91 | return id;
92 | }
93 |
94 | public String getGuid() {
95 | return guid;
96 | }
97 |
98 | public String getName() {
99 | return name;
100 | }
101 |
102 | public String getType() {
103 | return type;
104 | }
105 |
106 | public long getParentId() {
107 | return parentId;
108 | }
109 |
110 | public double[] getMatrix() {
111 | return matrix;
112 | }
113 |
114 | public int getRepId() {
115 | return repId;
116 | }
117 |
118 | public ByteBuffer getPositions() {
119 | return positions;
120 | }
121 |
122 | public ByteBuffer getNormals() {
123 | return normals;
124 | }
125 |
126 | public ByteBuffer getIndices() {
127 | return indices;
128 | }
129 |
130 | public ByteBuffer getColors() {
131 | return colors;
132 | }
133 |
134 | public ByteBuffer getMaterialIndices() {
135 | return materialIndices;
136 | }
137 |
138 | public ObjectNode getAllExtendedData() throws RenderEngineException {
139 | return this.extendedData;
140 | }
141 | }
--------------------------------------------------------------------------------
/src/org/ifcopenshell/IfcOpenShellEngine.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * *
3 | * This file is part of IfcOpenShell. *
4 | * *
5 | * IfcOpenShell is free software: you can redistribute it and/or modify *
6 | * it under the terms of the Lesser GNU General Public License as published by *
7 | * the Free Software Foundation, either version 3.0 of the License, or *
8 | * (at your option) any later version. *
9 | * *
10 | * IfcOpenShell is distributed in the hope that it will be useful, *
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 | * Lesser GNU General Public License for more details. *
14 | * *
15 | * You should have received a copy of the Lesser GNU General Public License *
16 | * along with this program. If not, see . *
17 | * *
18 | ********************************************************************************/
19 |
20 | /*******************************************************************************
21 | * *
22 | * An intermediate between the Plugin implementation and the Model *
23 | * implementation, nothing fancy going on here. *
24 | * *
25 | ********************************************************************************/
26 |
27 | package org.ifcopenshell;
28 |
29 | /******************************************************************************
30 | * Copyright (C) 2009-2019 BIMserver.org
31 | *
32 | * This program is free software: you can redistribute it and/or modify
33 | * it under the terms of the GNU Affero General Public License as
34 | * published by the Free Software Foundation, either version 3 of the
35 | * License, or (at your option) any later version.
36 | *
37 | * This program is distributed in the hope that it will be useful,
38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 | * GNU Affero General Public License for more details.
41 | *
42 | * You should have received a copy of the GNU Affero General Public License
43 | * along with this program. If not, see {@literal}.
44 | *****************************************************************************/
45 |
46 | import java.io.IOException;
47 | import java.io.InputStream;
48 | import java.nio.file.Path;
49 |
50 | import org.bimserver.plugins.renderengine.Metrics;
51 | import org.bimserver.plugins.renderengine.RenderEngine;
52 | import org.bimserver.plugins.renderengine.RenderEngineException;
53 | import org.bimserver.plugins.renderengine.RenderEngineModel;
54 | import org.slf4j.Logger;
55 | import org.slf4j.LoggerFactory;
56 |
57 | public class IfcOpenShellEngine implements RenderEngine {
58 | private static final Logger LOGGER = LoggerFactory.getLogger(IfcOpenShellEngine.class);
59 | private Path executableFilename;
60 |
61 | private IfcGeomServerClient client;
62 | private boolean calculateQuantities;
63 | private boolean applyLayerSets;
64 | private boolean disableOpeningSubtractions;
65 |
66 | public IfcOpenShellEngine(Path executableFilename, boolean calculateQuantities, boolean applyLayerSets, boolean disableOpeningSubtractions) throws IOException {
67 | this.executableFilename = executableFilename;
68 | this.setCalculateQuantities(calculateQuantities);
69 | this.setApplyLayerSets(applyLayerSets);
70 | this.setDisableOpeningSubtractions(disableOpeningSubtractions);
71 | }
72 |
73 | @Override
74 | public void init() throws RenderEngineException {
75 | LOGGER.debug("Initializing IfcOpenShell engine");
76 |
77 | client = new IfcGeomServerClient(executableFilename);
78 | client.setCalculateQuantities(isCalculateQuantities());
79 | client.setApplyLayersets(isApplyLayerSets());
80 | client.setDisableOpeningSubtractions(isDisableOpeningSubtractions());
81 | }
82 |
83 | @Override
84 | public void close() throws RenderEngineException {
85 | LOGGER.debug("Closing IfcOpenShell engine");
86 | if (client.isRunning()) {
87 | client.close();
88 | }
89 | }
90 |
91 | @Override
92 | public RenderEngineModel openModel(InputStream inputStream, long size) throws RenderEngineException {
93 | if (!client.isRunning()) {
94 | client = new IfcGeomServerClient(executableFilename);
95 | }
96 | try {
97 | return new IfcOpenShellModel(client, inputStream, size);
98 | } catch (IOException e) {
99 | throw new RenderEngineException(e);
100 | }
101 | }
102 |
103 | @Override
104 | public RenderEngineModel openModel(InputStream inputStream) throws RenderEngineException {
105 | if (!client.isRunning()) {
106 | client = new IfcGeomServerClient(executableFilename);
107 | }
108 | try {
109 | return new IfcOpenShellModel(client, inputStream);
110 | } catch (IOException e) {
111 | throw new RenderEngineException(e);
112 | }
113 | }
114 |
115 | public boolean isCalculateQuantities() {
116 | return calculateQuantities;
117 | }
118 |
119 | public void setCalculateQuantities(boolean calculateQuantities) {
120 | this.calculateQuantities = calculateQuantities;
121 | }
122 |
123 | public boolean isApplyLayerSets() {
124 | return applyLayerSets;
125 | }
126 |
127 | public void setApplyLayerSets(boolean applyLayerSets) {
128 | this.applyLayerSets = applyLayerSets;
129 | }
130 |
131 | public boolean isDisableOpeningSubtractions(){
132 | return disableOpeningSubtractions;
133 | }
134 | public void setDisableOpeningSubtractions(boolean disableOpeningSubtractions) {
135 | this.disableOpeningSubtractions = disableOpeningSubtractions;
136 | }
137 |
138 |
139 |
140 | @Override
141 | public Metrics getMetrics() {
142 | return null;
143 | }
144 | }
--------------------------------------------------------------------------------
/src/org/ifcopenshell/IfcOpenShellEnginePlugin.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * *
3 | * This file is part of IfcOpenShell. *
4 | * *
5 | * IfcOpenShell is free software: you can redistribute it and/or modify *
6 | * it under the terms of the Lesser GNU General Public License as published by *
7 | * the Free Software Foundation, either version 3.0 of the License, or *
8 | * (at your option) any later version. *
9 | * *
10 | * IfcOpenShell is distributed in the hope that it will be useful, *
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 | * Lesser GNU General Public License for more details. *
14 | * *
15 | * You should have received a copy of the Lesser GNU General Public License *
16 | * along with this program. If not, see . *
17 | * *
18 | ********************************************************************************/
19 |
20 | /*******************************************************************************
21 | * *
22 | * This class ensures that a valid binary is available for the platform the *
23 | * code is running on. *
24 | * *
25 | ********************************************************************************/
26 |
27 | package org.ifcopenshell;
28 |
29 | /******************************************************************************
30 | * Copyright (C) 2009-2019 BIMserver.org
31 | *
32 | * This program is free software: you can redistribute it and/or modify
33 | * it under the terms of the GNU Affero General Public License as
34 | * published by the Free Software Foundation, either version 3 of the
35 | * License, or (at your option) any later version.
36 | *
37 | * This program is distributed in the hope that it will be useful,
38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 | * GNU Affero General Public License for more details.
41 | *
42 | * You should have received a copy of the GNU Affero General Public License
43 | * along with this program. If not, see {@literal}.
44 | *****************************************************************************/
45 |
46 | import java.io.IOException;
47 | import java.nio.file.Path;
48 |
49 | import org.bimserver.models.store.BooleanType;
50 | import org.bimserver.models.store.ObjectDefinition;
51 | import org.bimserver.models.store.ParameterDefinition;
52 | import org.bimserver.models.store.PrimitiveDefinition;
53 | import org.bimserver.models.store.PrimitiveEnum;
54 | import org.bimserver.models.store.StoreFactory;
55 | import org.bimserver.models.store.StringType;
56 | import org.bimserver.plugins.PluginConfiguration;
57 | import org.bimserver.plugins.PluginContext;
58 | import org.bimserver.plugins.renderengine.RenderEngine;
59 | import org.bimserver.plugins.renderengine.RenderEngineException;
60 | import org.bimserver.plugins.renderengine.RenderEnginePlugin;
61 | import org.bimserver.plugins.renderengine.VersionInfo;
62 | import org.bimserver.shared.exceptions.PluginException;
63 | import org.slf4j.Logger;
64 | import org.slf4j.LoggerFactory;
65 |
66 | public class IfcOpenShellEnginePlugin implements RenderEnginePlugin {
67 | private static final Logger LOGGER = LoggerFactory.getLogger(IfcOpenShellEnginePlugin.class);
68 | public static final String DEFAULT_BUILD_VERSION = "v0.7.0-c7830e9"; // last v0.7.0 version, from 30.05.2024
69 | private static final String BUILD_VERSION = "buildversion";
70 | private static final String CALCULATE_QUANTITIES_SETTING = "calculatequantities";
71 | private static final String APPLY_LAYER_SETS = "applylayersets";
72 | private static final String DISABLE_OPENING_SUBTRACTIONS = "disableopeningsubtrations";
73 | private Path executableFilename;
74 | private VersionInfo versionInfo;
75 | private boolean calculateQuantities = true;
76 | private boolean applyLayerSets = true;
77 | private boolean disableOpeningSubtractions = false;
78 |
79 | @Override
80 | public RenderEngine createRenderEngine(PluginConfiguration pluginConfiguration, String schema) throws RenderEngineException {
81 | try {
82 | return new IfcOpenShellEngine(executableFilename, calculateQuantities, applyLayerSets, disableOpeningSubtractions);
83 | } catch (IOException e) {
84 | throw new RenderEngineException(e);
85 | }
86 | }
87 |
88 | @Override
89 | public void init(PluginContext pluginContext, PluginConfiguration systemSettings) throws PluginException {
90 | // Make sure an executable is downloaded before invoking the plug-in using multiple threads.
91 | // This also checks whether the version of the executable matches the java source.
92 |
93 | if (systemSettings != null) {
94 | calculateQuantities = systemSettings.getBoolean(CALCULATE_QUANTITIES_SETTING, true);
95 | applyLayerSets = systemSettings.getBoolean(APPLY_LAYER_SETS, true);
96 | disableOpeningSubtractions = systemSettings.getBoolean(DISABLE_OPENING_SUBTRACTIONS, false);
97 | }
98 |
99 | String buildVersion = DEFAULT_BUILD_VERSION;
100 | if (systemSettings != null && systemSettings.getString(BUILD_VERSION) != null && !systemSettings.getString(BUILD_VERSION).trim().contentEquals("")) {
101 | // Overruled by system settings
102 | buildVersion = systemSettings.getString(BUILD_VERSION);
103 | LOGGER.info("Using overruled system setting for build version");
104 | }
105 |
106 | try (IfcGeomServerClient test = new IfcGeomServerClient(IfcGeomServerClient.ExecutableSource.S3, buildVersion, pluginContext.getTempDir())) {
107 | executableFilename = test.getExecutableFilename();
108 | versionInfo = new VersionInfo(buildVersion, test.getProtocolVersion(), test.getBuildDateTime(), test.getPlatform());
109 | }
110 |
111 | LOGGER.info("Using " + executableFilename);
112 | }
113 |
114 | @Override
115 | public ObjectDefinition getUserSettingsDefinition() {
116 | return null;
117 | }
118 |
119 | @Override
120 | public ObjectDefinition getSystemSettingsDefinition() {
121 | ObjectDefinition settings = StoreFactory.eINSTANCE.createObjectDefinition();
122 |
123 | PrimitiveDefinition stringType = StoreFactory.eINSTANCE.createPrimitiveDefinition();
124 | stringType.setType(PrimitiveEnum.STRING);
125 |
126 | PrimitiveDefinition booleanType = StoreFactory.eINSTANCE.createPrimitiveDefinition();
127 | booleanType.setType(PrimitiveEnum.BOOLEAN);
128 |
129 | StringType defaultBuildVersion = StoreFactory.eINSTANCE.createStringType();
130 | defaultBuildVersion.setValue(DEFAULT_BUILD_VERSION);
131 |
132 | BooleanType defaultTrue = StoreFactory.eINSTANCE.createBooleanType();
133 | defaultTrue.setValue(true);
134 |
135 | BooleanType defaultFalse = StoreFactory.eINSTANCE.createBooleanType();
136 | defaultFalse.setValue(false);
137 |
138 | ParameterDefinition buildVersionParameter = StoreFactory.eINSTANCE.createParameterDefinition();
139 | buildVersionParameter.setIdentifier(BUILD_VERSION);
140 | buildVersionParameter.setName("Build version");
141 | buildVersionParameter.setDescription("Build version of IfcOpenShell binary, usually consisting of version number and commit SHA. This overrules the default for the currently installed IfcOpenShell plugin");
142 | buildVersionParameter.setType(stringType);
143 | buildVersionParameter.setRequired(false);
144 | buildVersionParameter.setDefaultValue(defaultBuildVersion);
145 |
146 | ParameterDefinition calculateQuantities = StoreFactory.eINSTANCE.createParameterDefinition();
147 | calculateQuantities.setIdentifier(CALCULATE_QUANTITIES_SETTING);
148 | calculateQuantities.setName("Calculate Quantities");
149 | calculateQuantities.setDescription("Calculates volumes and areas, Takes a bit more time (about 15%)");
150 | calculateQuantities.setType(booleanType);
151 | calculateQuantities.setRequired(false);
152 | calculateQuantities.setDefaultValue(defaultTrue);
153 |
154 | ParameterDefinition applyLayerSets = StoreFactory.eINSTANCE.createParameterDefinition();
155 | applyLayerSets.setIdentifier(APPLY_LAYER_SETS);
156 | applyLayerSets.setName("Apply Layer Sets");
157 | applyLayerSets.setDescription("Splits certain objects into several layers, depending on the model can take about 10x more processing time, and results in more geometry");
158 | applyLayerSets.setType(booleanType);
159 | applyLayerSets.setRequired(false);
160 | applyLayerSets.setDefaultValue(defaultTrue);
161 |
162 | ParameterDefinition disableOpeningSubtractions = StoreFactory.eINSTANCE.createParameterDefinition();
163 | disableOpeningSubtractions.setIdentifier(DISABLE_OPENING_SUBTRACTIONS);
164 | disableOpeningSubtractions.setName("Disable Opening Subtractions");
165 | disableOpeningSubtractions.setDescription("Omits subtractions of voiding opening elements form the voided elements.");
166 | disableOpeningSubtractions.setType(booleanType);
167 | disableOpeningSubtractions.setRequired(false);
168 | disableOpeningSubtractions.setDefaultValue(defaultFalse);
169 |
170 | settings.getParameters().add(buildVersionParameter);
171 | settings.getParameters().add(calculateQuantities);
172 | settings.getParameters().add(applyLayerSets);
173 | settings.getParameters().add(disableOpeningSubtractions);
174 | return settings;
175 | }
176 |
177 | public VersionInfo getVersionInfo() {
178 | return versionInfo;
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/src/org/ifcopenshell/IfcOpenShellEntityInstance.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * *
3 | * This file is part of IfcOpenShell. *
4 | * *
5 | * IfcOpenShell is free software: you can redistribute it and/or modify *
6 | * it under the terms of the Lesser GNU General Public License as published by *
7 | * the Free Software Foundation, either version 3.0 of the License, or *
8 | * (at your option) any later version. *
9 | * *
10 | * IfcOpenShell is distributed in the hope that it will be useful, *
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 | * Lesser GNU General Public License for more details. *
14 | * *
15 | * You should have received a copy of the Lesser GNU General Public License *
16 | * along with this program. If not, see . *
17 | * *
18 | ********************************************************************************/
19 |
20 | package org.ifcopenshell;
21 |
22 | /******************************************************************************
23 | * Copyright (C) 2009-2019 BIMserver.org
24 | *
25 | * This program is free software: you can redistribute it and/or modify
26 | * it under the terms of the GNU Affero General Public License as
27 | * published by the Free Software Foundation, either version 3 of the
28 | * License, or (at your option) any later version.
29 | *
30 | * This program is distributed in the hope that it will be useful,
31 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 | * GNU Affero General Public License for more details.
34 | *
35 | * You should have received a copy of the GNU Affero General Public License
36 | * along with this program. If not, see {@literal}.
37 | *****************************************************************************/
38 |
39 | import org.bimserver.plugins.renderengine.RenderEngineException;
40 | import org.bimserver.plugins.renderengine.RenderEngineGeometry;
41 | import org.bimserver.plugins.renderengine.RenderEngineInstance;
42 |
43 | import com.fasterxml.jackson.databind.node.ObjectNode;
44 |
45 | public class IfcOpenShellEntityInstance implements RenderEngineInstance {
46 | private IfcGeomServerClientEntity entity;
47 |
48 | public IfcOpenShellEntityInstance(IfcGeomServerClientEntity entity) {
49 | this.entity = entity;
50 | }
51 |
52 | @Override
53 | public double[] getTransformationMatrix() {
54 | return entity.getMatrix();
55 | }
56 |
57 | @Override
58 | public RenderEngineGeometry generateGeometry() {
59 | if (entity == null) {
60 | return null;
61 | }
62 | return new RenderEngineGeometry(entity.getIndices(), entity.getPositions(), entity.getNormals(), entity.getColors(), entity.getMaterialIndices());
63 | }
64 |
65 | public ObjectNode getAdditionalData() throws RenderEngineException {
66 | return entity.getAllExtendedData();
67 | }
68 | }
--------------------------------------------------------------------------------
/src/org/ifcopenshell/IfcOpenShellModel.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * *
3 | * This file is part of IfcOpenShell. *
4 | * *
5 | * IfcOpenShell is free software: you can redistribute it and/or modify *
6 | * it under the terms of the Lesser GNU General Public License as published by *
7 | * the Free Software Foundation, either version 3.0 of the License, or *
8 | * (at your option) any later version. *
9 | * *
10 | * IfcOpenShell is distributed in the hope that it will be useful, *
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 | * Lesser GNU General Public License for more details. *
14 | * *
15 | * You should have received a copy of the Lesser GNU General Public License *
16 | * along with this program. If not, see . *
17 | * *
18 | ********************************************************************************/
19 |
20 | /*******************************************************************************
21 | * *
22 | * This class communicates with the JNI wrapper of IfcOpenShell. Note that, *
23 | * contrary to the Bonsma IFC engine, if the wrapper crashes it will take the *
24 | * BIMserver down with her. Since loading the wrapper involves loading a *
25 | * considerable binary into memory, it would have been better to make the *
26 | * System.load() call somewhere in IfcOpenShellEngine.java. *
27 | * *
28 | ********************************************************************************/
29 |
30 | package org.ifcopenshell;
31 |
32 | /******************************************************************************
33 | * Copyright (C) 2009-2019 BIMserver.org
34 | *
35 | * This program is free software: you can redistribute it and/or modify
36 | * it under the terms of the GNU Affero General Public License as
37 | * published by the Free Software Foundation, either version 3 of the
38 | * License, or (at your option) any later version.
39 | *
40 | * This program is distributed in the hope that it will be useful,
41 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
42 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43 | * GNU Affero General Public License for more details.
44 | *
45 | * You should have received a copy of the GNU Affero General Public License
46 | * along with this program. If not, see {@literal}.
47 | *****************************************************************************/
48 |
49 | import java.io.IOException;
50 | import java.io.InputStream;
51 | import java.util.Collection;
52 | import java.util.HashMap;
53 | import java.util.Map;
54 |
55 | import org.bimserver.plugins.renderengine.EntityNotFoundException;
56 | import org.bimserver.plugins.renderengine.RenderEngineException;
57 | import org.bimserver.plugins.renderengine.RenderEngineFilter;
58 | import org.bimserver.plugins.renderengine.RenderEngineInstance;
59 | import org.bimserver.plugins.renderengine.RenderEngineModel;
60 | import org.bimserver.plugins.renderengine.RenderEngineSettings;
61 | import org.slf4j.Logger;
62 | import org.slf4j.LoggerFactory;
63 |
64 | public class IfcOpenShellModel implements RenderEngineModel {
65 | private static final Logger LOGGER = LoggerFactory.getLogger(IfcOpenShellModel.class);
66 |
67 | private InputStream ifcInputStream;
68 |
69 | private Map instancesById;
70 |
71 | private IfcGeomServerClient client;
72 |
73 | public IfcOpenShellModel(IfcGeomServerClient client, InputStream ifcInputStream) throws RenderEngineException, IOException {
74 | this.client = client;
75 | this.ifcInputStream = ifcInputStream;
76 |
77 | client.loadModel(ifcInputStream);
78 | }
79 |
80 | public IfcOpenShellModel(IfcGeomServerClient client, InputStream ifcInputStream, long length) throws RenderEngineException, IOException {
81 | this.client = client;
82 | this.ifcInputStream = ifcInputStream;
83 |
84 | client.loadModel(ifcInputStream, length);
85 | }
86 |
87 | @Override
88 | public void close() throws RenderEngineException {
89 | if (instancesById != null) {
90 | instancesById.clear();
91 | }
92 | try {
93 | ifcInputStream.close();
94 | } catch (IOException e) {
95 | LOGGER.error("", e);
96 | }
97 | }
98 |
99 | @Override
100 | public void generateGeneralGeometry() throws RenderEngineException {
101 | // We keep track of instances ourselves
102 | instancesById = new HashMap();
103 |
104 | final double t0 = (double) System.nanoTime();
105 |
106 | while (client.hasNext()) {
107 | IfcGeomServerClientEntity next = client.getNext();
108 | // Store the instance in our dictionary
109 | IfcOpenShellEntityInstance instance = new IfcOpenShellEntityInstance(next);
110 | instancesById.put(next.getId(), instance);
111 | }
112 |
113 | final double t1 = (double) System.nanoTime();
114 |
115 | LOGGER.debug(String.format("Took %.2f seconds to obtain representations for %d entities", (t1-t0) / 1.E9, instancesById.size()));
116 | }
117 |
118 | @Override
119 | public RenderEngineInstance getInstanceFromExpressId(long expressId) throws RenderEngineException {
120 | if (instancesById.containsKey(expressId)) {
121 | return instancesById.get(expressId);
122 | } else {
123 | // Probably something went wrong with the processing of this element in
124 | // the IfcOpenShell binary, as it has not been included in the enumerated
125 | // set of elements with geometry.
126 | throw new EntityNotFoundException("Entity " + expressId + " not found in model");
127 | }
128 | }
129 |
130 | @Override
131 | public void setFormat(int format, int mask) throws RenderEngineException {
132 | }
133 |
134 | @Override
135 | public void setSettings(RenderEngineSettings settings) throws RenderEngineException {
136 | }
137 |
138 | @Override
139 | public void setFilter(RenderEngineFilter renderEngineFilter) {
140 | }
141 |
142 | @Override
143 | public Collection listInstances() throws RenderEngineException {
144 | return null;
145 | }
146 | }
--------------------------------------------------------------------------------