/******************************************************************************* * Copyright (c) 2012, 2013 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.opencascade.jme; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.eclipse.swt.widgets.Display; import org.jcae.opencascade.jni.BRepMesh_IncrementalMesh; import org.jcae.opencascade.jni.TopAbs_ShapeEnum; import org.jcae.opencascade.jni.TopExp_Explorer; import org.jcae.opencascade.jni.TopoDS_Face; import org.jcae.opencascade.jni.TopoDS_Shape; import org.simantics.opencascade.OCCTTool; import com.jme3.app.Application; import com.jme3.material.Material; import com.jme3.math.ColorRGBA; import com.jme3.renderer.RenderManager; import com.jme3.scene.Geometry; import com.jme3.scene.Mesh; import com.jme3.scene.Node; import com.jme3.scene.Spatial; public class JmeSolidObject { public static double deflection = 0.001; public static double featureAngle = 30; public static boolean computeNormals = true; public static boolean cleanPart = false; public static boolean mergePoints = false; private Application app; private TopoDS_Shape shape; private List actors = new ArrayList(2); private List solid = new ArrayList(1); private List edges = new ArrayList(1); public JmeSolidObject(Application app,TopoDS_Shape shape) { this.shape = shape; this.app = app; } public void visualizeSolid(boolean showEdges, boolean showVertices) { visualizeSolid(true, showEdges, showVertices); } public void visualizeSolid(boolean showFaces, boolean showEdges, boolean showVertices) { clearActorsSWT(); Mesh data = createSolidMesh(shape); if (data == null) return; if (showFaces) { solid.add(createActor(data)); } if (showEdges) { Spatial edge = createEdgesActor(data); edges.add(edge); if (showVertices) { actors.add(createVerticesActor(edge)); } } actors.addAll(solid); actors.addAll(edges); showActorsSWT(); } public void visualizeFaces(boolean showEdges, boolean showVertices) { clearActorsSWT(); Collection datas = createFaceMeshes(shape); for (Mesh data : datas) { solid.add(createActor(data)); if (showEdges) { Spatial edgesActor = createEdgesActor(data); edges.add(edgesActor); if (showVertices) { actors.add(createVerticesActor(edgesActor)); } } } actors.addAll(solid); actors.addAll(edges); showActorsSWT(); } public List getActors() { return actors; } public List getSolid() { return solid; } public List getEdges() { return edges; } public void showActorsSWT() { assert (Thread.currentThread() == Display.getDefault().getThread()); Node root = (Node)(app.getRenderManager().getMainView("Default").getScenes().get(0)); for (Spatial act : actors) { root.attachChild(act); } } public void showActors() { Display.getDefault().asyncExec(new Runnable() { @Override public void run() { showActorsSWT(); } }); } public void clearActorsSWT() { assert (Thread.currentThread() == Display.getDefault().getThread()); if (actors.size() == 0) return; for (Spatial act : actors) { act.removeFromParent(); } actors.clear(); solid.clear(); edges.clear(); } private void clearActorsSWT(List actors) { assert (Thread.currentThread() == Display.getDefault().getThread()); if (actors.size() == 0) return; for (Spatial act : actors) { act.removeFromParent(); } } public void clearActors() { if (actors.size() == 0) return; final List temp = new ArrayList(actors.size()); temp.addAll(actors); actors.clear(); solid.clear(); edges.clear(); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { clearActorsSWT(temp); } }); } public void dispose() { if (shape != null) { shape.delete(); shape = null; } clearActors(); } public void delete() { if (shape != null) { shape.delete(); shape = null; } clearActorsSWT(); } private static double TOLERANCE = 0.01; public static Mesh createSolidMesh(TopoDS_Shape shape) { double volume = OCCTTool.getBoundingBoxDiagonal(shape); if (volume < TOLERANCE) return null; BRepMesh_IncrementalMesh mesh = new BRepMesh_IncrementalMesh(shape,deflection*volume); TopExp_Explorer expFace = new TopExp_Explorer(); List meshPoints = new ArrayList(); List meshTriangles = new ArrayList(); for (expFace.init(shape, TopAbs_ShapeEnum.FACE); expFace.more(); expFace.next()) { TopoDS_Face face = (TopoDS_Face) expFace.current(); OCCTTool.appendToMesh(face, meshPoints, meshTriangles); face.delete(); } if (meshPoints.size() == 0 || meshTriangles.size() == 0) return null; Mesh data = JmeOCCTTool.createPartGrid(meshPoints, meshTriangles); expFace.delete(); mesh.delete(); return data; } public static Collection createFaceMeshes(TopoDS_Shape shape) { double volume = OCCTTool.getBoundingBoxDiagonal(shape); Collection faces = new ArrayList(); if (volume > TOLERANCE) { BRepMesh_IncrementalMesh mesh = new BRepMesh_IncrementalMesh(shape,deflection*volume); TopExp_Explorer expFace = new TopExp_Explorer(); for (expFace.init(shape, TopAbs_ShapeEnum.FACE); expFace.more(); expFace.next()) { TopoDS_Face face = (TopoDS_Face) expFace.current(); Mesh data = JmeOCCTTool.createPartGrid(face); face.delete(); faces.add(data); } expFace.delete(); mesh.delete(); } return faces; } public Spatial createActor(Mesh partGrid) { Geometry geom = new Geometry(); geom.setMesh(partGrid); ColorRGBA color = new ColorRGBA(1.0f, 1.0f, 0.0f, 1.0f); //Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); //mat.setColor("Color", color); Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md"); mat.setColor("Diffuse", color); mat.setColor("Ambient", color); mat.setColor("Specular", new ColorRGBA(1, 1, 1, 1)); mat.setBoolean("UseMaterialColors", true); geom.setMaterial(mat); geom.updateModelBound(); return geom; } public Spatial createEdgesActor(Mesh partGrid) { Mesh edgeMesh = JmeOCCTTool.createEdgeMesh(partGrid); edgeMesh.setLineWidth(2.f); Geometry geom = new Geometry(); geom.setMesh(edgeMesh); Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); ColorRGBA color = new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f); mat.setColor("Color", color); geom.setMaterial(mat); geom.updateModelBound(); return geom; } public Spatial createVerticesActor(Spatial partEdgesActor) { Geometry edgeGeom = (Geometry)partEdgesActor; Mesh vertexMesh = JmeOCCTTool.createVertexMesh(edgeGeom.getMesh()); Geometry geom = new Geometry(); geom.setMesh(vertexMesh); Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); ColorRGBA color = new ColorRGBA(0.0f, 0.0f, 0.0f, 1.0f); mat.setColor("Color", color); geom.setMaterial(mat); geom.updateModelBound(); return geom; } }