/* jCAE stand for Java Computer Aided Engineering. Features are : Small CAD modeler, Finite element mesher, Plugin architecture. Copyright (C) 2006, by EADS CRC Copyright (C) 2007,2009, by EADS France This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.jcae.mesh.bora; import org.jcae.mesh.bora.xmldata.BModelReader; import org.jcae.mesh.bora.ds.BModel; import org.jcae.mesh.bora.ds.BDiscretization; import org.jcae.mesh.bora.ds.BCADGraphCell; import org.jcae.mesh.cad.CADFace; import org.jcae.mesh.cad.CADGeomSurface; import org.jcae.mesh.cad.CADShapeEnum; import org.jcae.viewer3d.bg.ViewableBG; import org.jcae.viewer3d.View; import javax.media.j3d.Appearance; import javax.media.j3d.IndexedGeometryArray; import javax.media.j3d.IndexedTriangleArray; import javax.media.j3d.PointArray; import javax.media.j3d.GeometryArray; import javax.media.j3d.Shape3D; import javax.media.j3d.BranchGroup; import javax.media.j3d.ColoringAttributes; import javax.media.j3d.PointAttributes; import javax.media.j3d.PolygonAttributes; import java.io.FileInputStream; import java.io.File; import java.io.IOException; import java.nio.DoubleBuffer; import java.nio.IntBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.util.Iterator; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.JFrame; import javax.swing.WindowConstants; import org.xml.sax.SAXException; public class SampleBora2D { private final static float absOffsetStep = Float.parseFloat(System.getProperty("javax.media.j3d.zFactorAbs", "20.0f")); private final static float relOffsetStep = Float.parseFloat(System.getProperty("javax.media.j3d.zFactorRel", "2.0f")); private static BranchGroup [] getBranchGroups(BModel model) { BCADGraphCell root = model.getGraph().getRootCell(); // Count faces int nFaces = 0; for (Iterator<BCADGraphCell> it = root.uniqueShapesExplorer(CADShapeEnum.FACE); it.hasNext(); ) { BCADGraphCell face = it.next(); if (face.getOrientation() != 0) { if (face.getReversed() != null) face = face.getReversed(); } BDiscretization d = face.getDiscretizations().iterator().next(); if (null == d) continue; File nodesfile = new File(model.getOutputDir(d), "n"); if (!nodesfile.exists()) continue; File parasfile = new File(model.getOutputDir(d), "p"); if (!parasfile.exists()) continue; nFaces++; } // Count nodes and trias on each face int [] nrNodes = new int[nFaces+1]; int [] nrTria = new int[nFaces+1]; nrNodes[0] = 0; nrTria[0] = 0; nFaces = 0; for (Iterator<BCADGraphCell> it = root.uniqueShapesExplorer(CADShapeEnum.FACE); it.hasNext(); ) { BCADGraphCell face = it.next(); if (face.getOrientation() != 0) { if (face.getReversed() != null) face = face.getReversed(); } BDiscretization d = face.getDiscretizations().iterator().next(); if (null == d) continue; File nodesfile = new File(model.getOutputDir(d), "n"); if (!nodesfile.exists()) continue; File parasfile = new File(model.getOutputDir(d), "p"); if (!parasfile.exists()) continue; nrNodes[nFaces+1] = nrNodes[nFaces] + (int) nodesfile.length() / 24; File triasfile = new File(model.getOutputDir(d), "f"); if (!triasfile.exists()) continue; nrTria[nFaces+1] = nrTria[nFaces] + (int) triasfile.length() / 12; nFaces++; } int nVertices = nrNodes[nFaces]; int nTrias = nrTria[nFaces]; double [] xyz = new double[3*nVertices]; double [] x2 = new double[2*nVertices]; double [] x3d2 = new double[3*nVertices]; int [] trias = new int[3*nTrias]; nFaces = 0; for (Iterator<BCADGraphCell> it = root.uniqueShapesExplorer(CADShapeEnum.FACE); it.hasNext(); ) { BCADGraphCell face = it.next(); if (face.getOrientation() != 0) { if (face.getReversed() != null) face = face.getReversed(); } BDiscretization d = face.getDiscretizations().iterator().next(); if (null == d) continue; CADFace F = (CADFace) face.getShape(); try { File nodesfile = new File(model.getOutputDir(d), "n"); if (!nodesfile.exists()) continue; File parasfile = new File(model.getOutputDir(d), "p"); if (!parasfile.exists()) continue; File triasfile = new File(model.getOutputDir(d), "f"); if (!triasfile.exists()) continue; int nr = nrNodes[nFaces+1] - nrNodes[nFaces]; FileChannel fcP = new FileInputStream(parasfile).getChannel(); MappedByteBuffer bbP = fcP.map(FileChannel.MapMode.READ_ONLY, 0L, fcP.size()); DoubleBuffer parasBuffer = bbP.asDoubleBuffer(); parasBuffer.get(x2, 0, 2*nr); fcP.close(); CADGeomSurface surface = F.getGeomSurface(); for (int i = 0; i < nr; i++) { double [] x3 = surface.value(x2[2*i], x2[2*i+1]); x3d2[3*nrNodes[nFaces]+3*i] = x3[0]; x3d2[3*nrNodes[nFaces]+3*i+1] = x3[1]; x3d2[3*nrNodes[nFaces]+3*i+2] = x3[2]; } FileChannel fcN = new FileInputStream(nodesfile).getChannel(); MappedByteBuffer bbN = fcN.map(FileChannel.MapMode.READ_ONLY, 0L, fcN.size()); DoubleBuffer nodesBuffer = bbN.asDoubleBuffer(); nodesBuffer.get(xyz, 3*nrNodes[nFaces], 3*nr); fcN.close(); nr = nrTria[nFaces+1] - nrTria[nFaces]; FileChannel fcF = new FileInputStream(triasfile).getChannel(); MappedByteBuffer bbF = fcF.map(FileChannel.MapMode.READ_ONLY, 0L, fcF.size()); IntBuffer triasBuffer = bbF.asIntBuffer(); triasBuffer.get(trias, 3*nrTria[nFaces], 3*nr); // Add node offset for (int i = 0; i < 3*nr; i++) trias[3*nrTria[nFaces]+i] += nrNodes[nFaces] - 1; fcF.close(); nFaces++; } catch (Exception ex) { ex.printStackTrace(); } } BranchGroup [] ret = new BranchGroup[4]; PointAttributes pa = new PointAttributes(); pa.setPointSize(4.0f); int iRet = -1; // 3D edges ++iRet; ret[iRet] = new BranchGroup(); IndexedTriangleArray l = new IndexedTriangleArray(nVertices, GeometryArray.COORDINATES, trias.length); l.setCoordinateIndices(0, trias); l.setCoordinates(0, xyz); l.setCapability(GeometryArray.ALLOW_COUNT_READ); l.setCapability(GeometryArray.ALLOW_FORMAT_READ); l.setCapability(GeometryArray.ALLOW_REF_DATA_READ); l.setCapability(IndexedGeometryArray.ALLOW_COORDINATE_INDEX_READ); Appearance triaApp = new Appearance(); triaApp.setPolygonAttributes(new PolygonAttributes(PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_NONE, 0)); triaApp.setColoringAttributes(new ColoringAttributes(1f,0f,0f,ColoringAttributes.SHADE_FLAT)); Shape3D shapeTrias = new Shape3D(l, triaApp); shapeTrias.setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapeTrias.setPickable(false); ret[iRet].addChild(shapeTrias); // Black faces ++iRet; ret[iRet] = new BranchGroup(); Appearance htriApp = new Appearance(); htriApp.setPolygonAttributes(new PolygonAttributes(PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 2.0f*absOffsetStep, false, relOffsetStep)); htriApp.setColoringAttributes(new ColoringAttributes(0.1f,0.1f,0.3f,ColoringAttributes.SHADE_FLAT)); Shape3D hiddenTrias = new Shape3D(l, htriApp); hiddenTrias.setCapability(Shape3D.ALLOW_GEOMETRY_READ); hiddenTrias.setPickable(false); ret[iRet].addChild(hiddenTrias); // 2D nodes ++iRet; ret[iRet] = new BranchGroup(); PointArray p2 = new PointArray(nVertices, GeometryArray.COORDINATES); p2.setCoordinates(0, x3d2); Appearance vert2App = new Appearance(); vert2App.setPointAttributes(pa); vert2App.setColoringAttributes(new ColoringAttributes(0,1,0,ColoringAttributes.SHADE_GOURAUD)); Shape3D shapePoint2=new Shape3D(p2, vert2App); shapePoint2.setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapePoint2.setPickable(false); ret[iRet].addChild(shapePoint2); // 3D nodes ++iRet; ret[iRet] = new BranchGroup(); PointArray p = new PointArray(nVertices, GeometryArray.COORDINATES); p.setCoordinates(0, xyz); Appearance vertApp = new Appearance(); vertApp.setPointAttributes(pa); vertApp.setColoringAttributes(new ColoringAttributes(1f,1f,0f,ColoringAttributes.SHADE_GOURAUD)); Shape3D shapePoint = new Shape3D(p, vertApp); shapePoint.setCapability(Shape3D.ALLOW_GEOMETRY_READ); shapePoint.setPickable(false); ret[iRet].addChild(shapePoint); return ret; } public static void main(String args[]) throws SAXException, IOException { final BModel model = BModelReader.readObject(args[0]); JFrame feFrame = new JFrame("Bora Demo"); final View view = new View(feFrame); feFrame.setSize(800,600); feFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); final BranchGroup [] bgList = getBranchGroups(model); final ViewableBG [] viewList = new ViewableBG[bgList.length]; // bgList: // 0: triangles // 1: triangles without hidden faces // 2: 2D nodes on the 3D surface // 3: 3D nodes final boolean [] active = new boolean[bgList.length]; for (int i = 0; i < bgList.length; i++) { active[i] = true; viewList[i] = new ViewableBG(bgList[i]); } for (int i = 0; i < bgList.length; i++) if (active[i]) view.add(viewList[i]); view.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent event) { char k = event.getKeyChar(); if ('2' == k) active[2] = !active[2]; else if ('3' == k) active[3] = !active[3]; else if ('e' == k) active[0] = !active[0]; else if ('f' == k) active[1] = !active[1]; else if ('q' == k) System.exit(0); else return; for (int i = 0; i < bgList.length; i++) { view.remove(viewList[i]); if (active[i]) view.add(viewList[i]); } } }); view.fitAll(); feFrame.getContentPane().add(view); feFrame.setVisible(true); } }