Hi
Is there any class to shade 3D object. The method I used is public BranchGroup shading() { BranchGroup shadeGroup = new BranchGroup(); shadeGroup.setCapability(BranchGroup.ALLOW_DETACH); TransformGroup transGroup = new TransformGroup(); transGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); transGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); shadeGroup.addChild(transGroup); BoundingSphere bounds = new BoundingSphere(new Point3d(0, 0, 0), 100); Color3f white = new Color3f(0.15f, 0.15f, 0.15f); // Set up the ambient light AmbientLight ambientLightNode = new AmbientLight(white); ambientLightNode.setInfluencingBounds(bounds); shadeGroup.addChild(ambientLightNode); // Set up the directional lights Vector3f light1Direction = new Vector3f(-1.0f, -1.0f, -1.0f); Vector3f light2Direction = new Vector3f(1.0f, -1.0f, -1.0f); Vector3f light3Direction = new Vector3f(1.0f, 1.0f, 1.0f); Vector3f light4Direction = new Vector3f(-1.0f, 1.0f, 1.0f); Color3f light1color = new Color3f(0.5f, 0.5f, 0.5f); Color3f light2color = new Color3f(0.3f, 0.3f, 0.3f); Color3f light3color = new Color3f(0.3f, 0.3f, 0.3f); Color3f light4color = new Color3f(0.3f, 0.3f, 0.3f); DirectionalLight light1 = new DirectionalLight(light1color, light1Direction); light1.setInfluencingBounds(bounds); shadeGroup.addChild(light1); DirectionalLight light2 = new DirectionalLight(light2color, light2Direction); light2.setInfluencingBounds(bounds); shadeGroup.addChild(light2); DirectionalLight light3 = new DirectionalLight(light3color, light3Direction); light3.setInfluencingBounds(bounds); shadeGroup.addChild(light3); DirectionalLight light4 = new DirectionalLight(light4color, light4Direction); light4.setInfluencingBounds(bounds); shadeGroup.addChild(light4); System.out.println("\r\n-----Shading-----"); for (STL_TriInfo triInfo : triangleMap.getMap().values()) { LinkedList<Integer> tri_ptids = triInfo.getPointIds(); double[][] points = new double[4][3]; double[][] normals = new double[4][3]; for (int i = 0; i < tri_ptids.size(); i++) { Integer pt_ids = (Integer) tri_ptids.get(i); normals[i] = pointMap.pt_normal(triangleMap, pt_ids); MathTools.normalize(normals[i]); STL_PointInfo ptinf = pointMap.getPointInfo(pt_ids); points[i] = ptinf.getCurPos(); } VSTriangle vstri = new VSTriangle(points, normals); vstri.setCapability(Node.ENABLE_PICK_REPORTING); PickTool.setCapabilities(vstri, PickTool.INTERSECT_FULL); transGroup.addChild(vstri); } shadeGroup.compile(); return shadeGroup; } After I shade it it appears there are some issue with it and not shade properly. How I can solve it? |
Administrator
|
Hi
Maybe there is a problem with the orientation of the normals for a few triangles. What is the expecting result? Edit.: Your program is incomplete (where are the import clauses?), it's not a SSCCE and you use some classes that aren't part of the public Java3D API, maybe your own code is to blame.
Julien Gouesse | Personal blog | Website
|
Thank you
As you see in the picture, it shad the interior triangles ruther than the surface triangles. Yes there some C++ codes then transform it to java. Hear is the hole class : package fem; import java.awt.BorderLayout; import java.awt.Container; import java.awt.GraphicsConfiguration; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.io.File; import java.text.DecimalFormat; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.Map.Entry; import javax.media.j3d.AmbientLight; import javax.media.j3d.BoundingSphere; import javax.media.j3d.BranchGroup; import javax.media.j3d.Canvas3D; import javax.media.j3d.DirectionalLight; import javax.media.j3d.Node; import javax.media.j3d.Transform3D; import javax.media.j3d.TransformGroup; import javax.swing.GroupLayout; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.LayoutStyle; import javax.vecmath.Color3f; import javax.vecmath.Point3d; import javax.vecmath.Vector3d; import javax.vecmath.Vector3f; //import process.TetrahedronDataProcessor; //import process.TetrahedronDataProcessorFullU; import process.TetrahedronDataProcessorTariq; import com.sun.j3d.utils.picking.PickCanvas; import com.sun.j3d.utils.picking.PickResult; import com.sun.j3d.utils.picking.PickTool; import com.sun.j3d.utils.universe.SimpleUniverse; import com.sun.j3d.utils.universe.ViewingPlatform; import fem.j3d.FemMouseListener; import fem.j3d.MouseBehavior; import fem.stl.MathTools; import fem.stl.STL_EdgeInfo; import fem.stl.STL_EdgeMap; import fem.stl.STL_PointEdgeInfo; import fem.stl.STL_PointEdgeMap; import fem.stl.STL_PointInfo; import fem.stl.STL_PointMap; import fem.stl.STL_TriInfo; import fem.stl.STL_TriMap; import fem.stl.VSTriangle; /* * Created by JFormDesigner on Sat May 16 19:46:20 EST 2015 */ public class LiverDataGUI extends JFrame { private static final long serialVersionUID = 15673197328638756L; private int totalTriangles; private int[][] triangles; private double[][] vertex; private int vertex_num; private double scale = 0.5; private Canvas3D canvas; private SimpleUniverse universe; private BranchGroup groupRoot; //private TetrahedronDataProcessor dataProcessor = new TetrahedronDataProcessor(); //private TetrahedronDataProcessorFullU dataProcessor = new TetrahedronDataProcessorFullU(); private TetrahedronDataProcessorTariq dataProcessor = new TetrahedronDataProcessorTariq(); private BranchGroup shadeBranch; private TransformGroup GeomTrans; private STL_PointMap pointMap; private STL_PointEdgeMap pointEdgeMap; private STL_EdgeMap edgeMap; private STL_TriMap triangleMap; private TetraHedronVolumeDataPopulator meshData; private int pointInConcern; private DecimalFormat df2 = new DecimalFormat("###.######"); public static void main(String[] args) { LiverDataGUI newGUI = new LiverDataGUI(); newGUI.setVisible(true); } public LiverDataGUI() { initComponents(); initCanvas(panelCanVas); //File file = new File("data/liver_tetra_s1.txt"); File file = new File("data/Cubic_tetra_s1.txt"); // File file = new File("data/zaki.txt"); //File file = new File("data/vol_6-4.txt"); //File file = new File("data/Cubic_terra_data copy.txt"); //File file = new File("data/tetra_vol_1.txt"); processFile(file); createSceneGraph(vertex, triangles, vertex_num, totalTriangles); universe.addBranchGraph(groupRoot); } private void initCanvas(JPanel container) { GraphicsConfiguration config = SimpleUniverse .getPreferredConfiguration(); canvas = new Canvas3D(config); container.add(canvas, java.awt.BorderLayout.CENTER); canvas.setFocusable(true); canvas.requestFocus(); universe = new SimpleUniverse(canvas); initUserPosition(); universe.getViewingPlatform().setNominalViewingTransform(); orbitControls(canvas); } private void initComponents() { // JFormDesigner - Component initialization - DO NOT MODIFY // //GEN-BEGIN:initComponents // Generated using JFormDesigner Evaluation license menuBar = new JMenuBar(); menuFile = new JMenu(); menuItemOpen = new JMenuItem(); menuItemSave = new JMenuItem(); menuItemPrint = new JMenuItem(); menuItemExit = new JMenuItem(); menuRotation = new JMenu(); menuItemRotateX = new JMenuItem(); menuItemRotateY = new JMenuItem(); menuItemRotateZ = new JMenuItem(); menuTranslation = new JMenu(); menuItemTranslateX = new JMenuItem(); menuItemTranslateY = new JMenuItem(); menuItemTranslateZ = new JMenuItem(); menuItemTranslateInvX = new JMenuItem(); menuItemTranslateInvY = new JMenuItem(); menuItemTranslateInvZ = new JMenuItem(); menuShading = new JMenu(); menuItemShade = new JMenuItem(); menuItemUnshade = new JMenuItem(); panelCanVas = new JPanel(); panel2 = new JPanel(); panel3 = new JPanel(); buttonSet = new JButton(); labelBodyForceX = new JLabel(); tfBodyForceX = new JTextField(); tfBodyForceY = new JTextField(); tfBodyForceZ = new JTextField(); labelBodyForceY = new JLabel(); labelBodyForceZ = new JLabel(); labelNodeDataX = new JLabel(); tfNodeDataX = new JTextField(); tfNodeDataY = new JTextField(); tfNodeDataZ = new JTextField(); labelNodeDataY = new JLabel(); labelNodeDataZ = new JLabel(); panel5 = new JPanel(); buttonNormalMode = new JButton(); buttonMove = new JButton(); buttonZoomIn = new JButton(); buttonZoomOut = new JButton(); buttonDefaultView = new JButton(); buttonPlot = new JButton(); panel4 = new JPanel(); labelElasticity = new JLabel(); tfElasticity = new JTextField(); labelPoissonRatio = new JLabel(); tfPoissonRatio = new JTextField(); tfElasticity.setText("25300.0"); tfPoissonRatio.setText("0.48"); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { System.exit(0); } }); // ======== this ======== Container contentPane = getContentPane(); // ======== menuBar1 ======== { // ======== menu1 ======== { menuFile.setText("File"); // ---- menuItem2 ---- menuItemOpen.setText("Open"); menuItemOpen.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { if(universe != null) universe.cleanup(); openFile(arg0); createSceneGraph(vertex, triangles, vertex_num, totalTriangles); universe.addBranchGraph(groupRoot); } }); menuFile.add(menuItemOpen); // ---- menuItem3 ---- menuItemSave.setText("Save"); menuFile.add(menuItemSave); // ---- menuItem4 ---- menuItemPrint.setText("Print"); menuFile.add(menuItemPrint); // ---- menuItem5 ---- menuItemExit.setText("Exit"); menuFile.add(menuItemExit); } menuBar.add(menuFile); // ======== menu2 ======== { menuRotation.setText("Rotation"); menuItemRotateX.setText("Rotate X"); menuRotation.add(menuItemRotateX); menuItemRotateY.setText("Rotate Y"); menuRotation.add(menuItemRotateY); menuItemRotateZ.setText("Rotate Z"); menuRotation.add(menuItemRotateZ); } menuBar.add(menuRotation); // ======== menu3 ======== { menuTranslation.setText("Translation"); // ---- menuItem9 ---- menuItemTranslateX.setText("Translate X"); menuTranslation.add(menuItemTranslateX); // ---- menuItem10 ---- menuItemTranslateY.setText("Translate Y"); menuTranslation.add(menuItemTranslateY); // ---- menuItem11 ---- menuItemTranslateZ.setText("Translate Z"); menuTranslation.add(menuItemTranslateZ); // ---- menuItem12 ---- menuItemTranslateInvX.setText("Translate -X"); menuTranslation.add(menuItemTranslateInvX); // ---- menuItem13 ---- menuItemTranslateInvY.setText("Translate -Y"); menuTranslation.add(menuItemTranslateInvY); // ---- menuItem14 ---- menuItemTranslateInvZ.setText("Translate -Z"); menuTranslation.add(menuItemTranslateInvZ); } menuBar.add(menuTranslation); // ======== menu4 ======== { menuShading.setText("Shading"); // ---- menuItem15 ---- menuItemShade.setText("Shade"); menuShading.add(menuItemShade); menuItemShade.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { shade(); } }); // ---- menuItem16 ---- menuItemUnshade.setText("Unshade"); menuShading.add(menuItemUnshade); } menuBar.add(menuShading); } setJMenuBar(menuBar); // ======== panel1 ======== { panelCanVas.setLayout(new BorderLayout()); panelCanVas.setPreferredSize(new java.awt.Dimension(600, 400)); } // ======== panel2 ======== { // ======== panel3 ======== { // ---- button1 ---- buttonSet.setText("Set"); buttonSet.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { dataProcessor .loadData( meshData, pointInConcern, new double[] { Double.parseDouble(tfNodeDataX .getText()), Double.parseDouble(tfNodeDataY .getText()), Double.parseDouble(tfNodeDataZ .getText()) }, new double[] { Double.parseDouble(tfBodyForceX .getText()), Double.parseDouble(tfBodyForceY .getText()), Double.parseDouble(tfBodyForceZ .getText()) }, Double .parseDouble(tfElasticity .getText()), Double .parseDouble(tfPoissonRatio .getText())); double[][] positions = dataProcessor.process(); vertex = positions; for(int i=0;i<triangles.length;i++){ for(int j=0;j<triangles[0].length;j++){ triangles[i][j] = triangles[i][j] -1; } } initCanvas(panelCanVas); createSceneGraph(vertex, triangles, vertex_num, totalTriangles); universe.addBranchGraph(groupRoot); } }); labelBodyForceX.setText("Forces X: "); labelBodyForceY.setText("Y: "); labelBodyForceZ.setText("Z: "); labelNodeDataX.setText("Node X: "); labelNodeDataY.setText("Y: "); labelNodeDataZ.setText("Z: "); tfBodyForceX.setText("10000"); tfBodyForceY.setText("10000"); tfBodyForceZ.setText("10000"); GroupLayout panel3Layout = new GroupLayout(panel3); panel3.setLayout(panel3Layout); panel3Layout .setHorizontalGroup(panel3Layout .createParallelGroup() .addGroup( panel3Layout .createSequentialGroup() .addContainerGap() .addComponent(buttonSet) .addPreferredGap( LayoutStyle.ComponentPlacement.UNRELATED) .addGroup( panel3Layout .createParallelGroup( GroupLayout.Alignment.LEADING, false) .addComponent( labelBodyForceY, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent( labelBodyForceX, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent( labelBodyForceZ, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap( LayoutStyle.ComponentPlacement.RELATED) .addGroup( panel3Layout .createParallelGroup( GroupLayout.Alignment.LEADING, false) .addComponent( tfBodyForceZ, GroupLayout.DEFAULT_SIZE, 102, Short.MAX_VALUE) .addComponent( tfBodyForceY) .addComponent( tfBodyForceX)) .addPreferredGap( LayoutStyle.ComponentPlacement.UNRELATED) .addGroup( panel3Layout .createParallelGroup( GroupLayout.Alignment.TRAILING, false) .addComponent( labelNodeDataX, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent( labelNodeDataY, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent( labelNodeDataZ, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap( LayoutStyle.ComponentPlacement.UNRELATED) .addGroup( panel3Layout .createParallelGroup() .addComponent( tfNodeDataX, GroupLayout.DEFAULT_SIZE, 97, Short.MAX_VALUE) .addComponent( tfNodeDataY, GroupLayout.DEFAULT_SIZE, 97, Short.MAX_VALUE) .addComponent( tfNodeDataZ, GroupLayout.DEFAULT_SIZE, 97, Short.MAX_VALUE)) .addContainerGap())); panel3Layout .setVerticalGroup(panel3Layout .createParallelGroup() .addGroup( panel3Layout .createSequentialGroup() .addContainerGap() .addGroup( panel3Layout .createParallelGroup( GroupLayout.Alignment.BASELINE) .addComponent( buttonSet) .addComponent( labelBodyForceX) .addComponent( tfBodyForceX, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent( labelNodeDataX) .addComponent( tfNodeDataX, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap( LayoutStyle.ComponentPlacement.RELATED) .addGroup( panel3Layout .createParallelGroup( GroupLayout.Alignment.BASELINE) .addComponent( tfBodyForceY, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent( tfNodeDataY, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent( labelBodyForceY) .addComponent( labelNodeDataY)) .addPreferredGap( LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup( panel3Layout .createParallelGroup( GroupLayout.Alignment.BASELINE) .addComponent( tfBodyForceZ, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent( tfNodeDataZ, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent( labelBodyForceZ) .addComponent( labelNodeDataZ)))); } // ======== panel5 ======== { // ---- button2 ---- buttonNormalMode.setText("Normal Mode"); buttonNormalMode.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { normalMode(e); } }); // ---- button3 ---- buttonMove.setText("Move"); // ---- button4 ---- buttonZoomIn.setText("Zoom +"); buttonZoomIn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { scale = scale / 1.1; // processFile(null); } }); // ---- button5 ---- buttonZoomOut.setText("Zoom -"); buttonZoomOut.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (scale <= 100) { scale = scale * 1.1; } // processFile(null); } }); // ---- button6 ---- buttonDefaultView.setText("Default View"); // ---- button7 ---- buttonPlot.setText("Display Plots"); buttonPlot.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { dataProcessor.display(); } }); GroupLayout panel5Layout = new GroupLayout(panel5); panel5.setLayout(panel5Layout); panel5Layout .setHorizontalGroup(panel5Layout .createParallelGroup() .addGroup( GroupLayout.Alignment.TRAILING, panel5Layout .createSequentialGroup() .addContainerGap( GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup( panel5Layout .createParallelGroup( GroupLayout.Alignment.LEADING, false) .addComponent( buttonNormalMode, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent( buttonDefaultView, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(18, 18, 18) .addGroup( panel5Layout .createParallelGroup( GroupLayout.Alignment.LEADING, false) .addComponent( buttonMove, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent( buttonZoomOut, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent( buttonZoomIn, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(18, 18, 18) .addComponent(buttonPlot) .addGap(140, 140, 140))); panel5Layout .setVerticalGroup(panel5Layout .createParallelGroup() .addGroup( panel5Layout .createSequentialGroup() .addGroup( panel5Layout .createParallelGroup( GroupLayout.Alignment.BASELINE) .addComponent( buttonNormalMode) .addComponent( buttonZoomIn) .addComponent( buttonPlot)) .addPreferredGap( LayoutStyle.ComponentPlacement.RELATED) .addGroup( panel5Layout .createParallelGroup( GroupLayout.Alignment.BASELINE) .addComponent( buttonZoomOut) .addComponent( buttonDefaultView)) .addPreferredGap( LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(buttonMove))); } // ======== panel4 ======== { // ---- label4 ---- labelElasticity.setText("Elasticity"); // ---- label5 ---- labelPoissonRatio.setText("Poisson Ratio"); GroupLayout panel4Layout = new GroupLayout(panel4); panel4.setLayout(panel4Layout); panel4Layout .setHorizontalGroup(panel4Layout .createParallelGroup() .addGroup( panel4Layout .createSequentialGroup() .addContainerGap() .addGroup( panel4Layout .createParallelGroup() .addComponent( labelElasticity) .addComponent( labelPoissonRatio)) .addGap(14, 14, 14) .addGroup( panel4Layout .createParallelGroup( GroupLayout.Alignment.LEADING, false) .addComponent( tfElasticity, GroupLayout.PREFERRED_SIZE, 107, GroupLayout.PREFERRED_SIZE) .addComponent( tfPoissonRatio)) .addContainerGap(44, Short.MAX_VALUE))); panel4Layout .setVerticalGroup(panel4Layout .createParallelGroup() .addGroup( panel4Layout .createSequentialGroup() .addContainerGap() .addGroup( panel4Layout .createParallelGroup( GroupLayout.Alignment.BASELINE) .addComponent( labelElasticity) .addComponent( tfElasticity, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addPreferredGap( LayoutStyle.ComponentPlacement.RELATED) .addGroup( panel4Layout .createParallelGroup() .addComponent( labelPoissonRatio) .addComponent( tfPoissonRatio, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addContainerGap( GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))); } GroupLayout panel2Layout = new GroupLayout(panel2); panel2.setLayout(panel2Layout); panel2Layout .setHorizontalGroup(panel2Layout .createParallelGroup() .addGroup( panel2Layout .createSequentialGroup() .addComponent(panel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap( LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(panel4, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap( LayoutStyle.ComponentPlacement.RELATED) .addComponent(panel5, GroupLayout.DEFAULT_SIZE, 341, Short.MAX_VALUE) .addContainerGap())); panel2Layout.setVerticalGroup(panel2Layout .createParallelGroup() .addGroup( GroupLayout.Alignment.TRAILING, panel2Layout .createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE) .addComponent(panel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addComponent(panel4, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(panel5, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)); } GroupLayout contentPaneLayout = new GroupLayout(contentPane); contentPane.setLayout(contentPaneLayout); contentPaneLayout .setHorizontalGroup(contentPaneLayout .createParallelGroup() .addGroup( contentPaneLayout .createSequentialGroup() .addGroup( contentPaneLayout .createParallelGroup() .addComponent( panel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent( panelCanVas, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap())); contentPaneLayout.setVerticalGroup(contentPaneLayout .createParallelGroup().addGroup( contentPaneLayout .createSequentialGroup() .addComponent(panelCanVas, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap( LayoutStyle.ComponentPlacement.RELATED) .addComponent(panel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addContainerGap())); pack(); setLocationRelativeTo(getOwner()); // //GEN-END:initComponents } // JFormDesigner - Variables declaration - DO NOT MODIFY // //GEN-BEGIN:variables // Generated using JFormDesigner Evaluation license private JMenuBar menuBar; private JMenu menuFile; private JMenuItem menuItemOpen; private JMenuItem menuItemSave; private JMenuItem menuItemPrint; private JMenuItem menuItemExit; private JMenu menuRotation; private JMenuItem menuItemRotateX; private JMenuItem menuItemRotateY; private JMenuItem menuItemRotateZ; private JMenu menuTranslation; private JMenuItem menuItemTranslateX; private JMenuItem menuItemTranslateY; private JMenuItem menuItemTranslateZ; private JMenuItem menuItemTranslateInvX; private JMenuItem menuItemTranslateInvY; private JMenuItem menuItemTranslateInvZ; private JMenu menuShading; private JMenuItem menuItemShade; private JMenuItem menuItemUnshade; private JPanel panelCanVas; private JPanel panel2; private JPanel panel3; private JButton buttonSet; private JLabel labelBodyForceX; private JTextField tfBodyForceX; private JTextField tfBodyForceY; private JTextField tfBodyForceZ; private JLabel labelBodyForceY; private JLabel labelBodyForceZ; private JLabel labelNodeDataX; private JTextField tfNodeDataX; private JTextField tfNodeDataY; private JTextField tfNodeDataZ; private JLabel labelNodeDataY; private JLabel labelNodeDataZ; private JPanel panel5; private JButton buttonNormalMode; private JButton buttonMove; private JButton buttonZoomIn; private JButton buttonZoomOut; private JButton buttonDefaultView; private JButton buttonPlot; private JPanel panel4; private JLabel labelElasticity; private JTextField tfElasticity; private JLabel labelPoissonRatio; private JTextField tfPoissonRatio; // JFormDesigner - End of variables declaration //GEN-END:variables public Point3D getPickedPoint(java.awt.event.MouseEvent evt) { PickCanvas picker = new PickCanvas(canvas, groupRoot); picker.setMode(PickTool.GEOMETRY); picker.setShapeLocation(evt); PickResult[] pickResult = picker.pickAllSorted(); if (pickResult != null) { for(PickResult p : pickResult) { if(p.getObject() instanceof Point3D) { return (Point3D)p.getObject(); } } } return null; } public void createSceneGraph(double[][] vertex, int[][] tri, int vertex_num, int tri_num) { groupRoot = new BranchGroup(); groupRoot.setCapability(BranchGroup.ALLOW_DETACH); GeomTrans = new TransformGroup(); GeomTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); GeomTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); groupRoot.addChild(GeomTrans); pointMap = new STL_PointMap(); for (int j = 0; j < vertex_num; j++) { pointMap.addPoint(j, 1, 0.0, vertex[j]); } pointMap.CanonicalScale(scale); for(Entry<Integer, STL_PointInfo> entry : pointMap.getMap().entrySet()) { STL_PointInfo pointInfo = entry.getValue(); double[] pt_coord = pointInfo.getCurPos(); Point3d pt = new Point3d(pt_coord[0], pt_coord[1], pt_coord[2]); Point3D vspt = new Point3D(entry.getKey(), pt); GeomTrans.addChild(vspt); pointInfo.setVSPoint(vspt); } pointEdgeMap = new STL_PointEdgeMap(); for (int i = 0; i < tri_num; i++) { for (int k = 0; k < 4; k++) { Integer pointID = new Integer(tri[i][k]); Integer[] neighIDs = new Integer[3]; if (k == 0) { neighIDs[0] = new Integer(tri[i][1]); neighIDs[1] = new Integer(tri[i][2]); neighIDs[2] = new Integer(tri[i][3]); } if (k == 1) { neighIDs[0] = new Integer(tri[i][0]); neighIDs[1] = new Integer(tri[i][3]); neighIDs[2] = new Integer(tri[i][2]); } if (k == 2) { neighIDs[0] = new Integer(tri[i][0]); neighIDs[1] = new Integer(tri[i][1]); neighIDs[2] = new Integer(tri[i][3]); } if (k == 3) { neighIDs[0] = new Integer(tri[i][0]); neighIDs[1] = new Integer(tri[i][2]); neighIDs[2] = new Integer(tri[i][1]); } pointEdgeMap.addNeighPoints(pointID, neighIDs); System.out.println("1 pt_id =" + pointID + " nei_pts[0] =" + neighIDs[0] + " nei_pts[1] =" + neighIDs[1] + " nei_pts[2] =" + neighIDs[2]); } } System.out.println("-------Finish ptedge_list-------"); System.out.println("-------Remove repeat edges in pointMap-------"); pointEdgeMap.setEdgeIDs(); edgeMap = new STL_EdgeMap(); for (Entry<Integer, STL_PointEdgeInfo> entry : pointEdgeMap.getHashMap().entrySet()) { Integer pointID = entry.getKey(); STL_PointEdgeInfo peInfo = entry.getValue(); STL_PointInfo pointInfo = pointMap.getPointInfo(pointID); double[] pt1 = pointInfo.getCurPos(); LinkedList<Integer> neighEdgeIDs = peInfo.getEdgeIDs(); int index = 0; for (Integer neighID : peInfo.getNeighPoints()) { STL_PointInfo neighPoint = pointMap.getPointInfo(neighID); double[] pt2 = neighPoint.getCurPos(); Line3D vsln = new Line3D(pt1, pt2); //vsln.setCapability(Node.ENABLE_PICK_REPORTING); //PickTool.setCapabilities(vsln, PickTool.INTERSECT_FULL); GeomTrans.addChild(vsln); Integer edgeID = neighEdgeIDs.get(index); double rest_l = MathTools.distance(pt1, pt2); edgeMap.addEdge(edgeID, pointID, neighID, rest_l, vsln); pointInfo.setNeighEdges(edgeID); neighPoint.setNeighEdges(edgeID); index++; System.out.println("2 point ID =" + pointID + " neighbor point ID =" + neighID); } System.out.println("-------eaaaaaae-------"); } System.out.println("------Start TM_Tetra_list-----"); triangleMap = new STL_TriMap(); for(int i=0; i<tri_num; i++) { Integer fpt_id = new Integer(-1); Integer spt_id = new Integer(-1); LinkedList<Integer> pt_ids = new LinkedList<Integer>(); double[][] pts = new double[4][3]; for(int k=0; k<4; k++) { Integer tript_id = new Integer(tri[i][k]); pt_ids.add(tript_id); STL_PointInfo tri_ptinf = pointMap.getPointInfo(tript_id); pts[k] = tri_ptinf.getCurPos(); } LinkedList<Integer> ed_ids = new LinkedList<Integer>(); for(int j=0; j<4; j++) { if(j==0 || j==1|| j==2) { fpt_id = new Integer(tri[i][j]); spt_id = new Integer(tri[i][j+1]); } if(j==3) { fpt_id = new Integer(tri[i][3]); spt_id = new Integer(tri[i][0]); } Integer ed_id = new Integer(-1); STL_PointEdgeInfo fptedge_inf = pointEdgeMap.getPointEdgeInfo(fpt_id); LinkedHashSet<Integer> fneighpts = fptedge_inf.getNeighPoints(); if(fneighpts.contains(spt_id)) { Object[] fneigh_pts_obj = fneighpts.toArray(); for(int k=0; k<fneigh_pts_obj.length; k++) { Integer nei_pt_id = (Integer)fneigh_pts_obj[k]; if(nei_pt_id.intValue() == spt_id.intValue()) { LinkedList<Integer> nei_edids = fptedge_inf.getEdgeIDs(); ed_id = (Integer)nei_edids.get(k); break; } } } else { STL_PointEdgeInfo sptedge_inf = pointEdgeMap.getPointEdgeInfo(spt_id); LinkedHashSet<Integer> sneigh_pts = sptedge_inf.getNeighPoints(); Object[] sneigh_pts_obj = sneigh_pts.toArray(); for(int k=0; k<sneigh_pts_obj.length; k++) { Integer nei_pt_id = (Integer)sneigh_pts_obj[k]; if(nei_pt_id.intValue() == fpt_id.intValue()) { LinkedList<Integer> nei_edids = sptedge_inf.getEdgeIDs(); ed_id = (Integer)nei_edids.get(k); break; } } } ed_ids.add(ed_id); } triangleMap.addTri(new Integer(i), pt_ids, ed_ids); } triangleMap.setPt_NeighTris(pointMap); triangleMap.setEdge_NeighTris(edgeMap); boolean boundary = edgeMap.setPt_Attributes(pointMap); if(boundary == false) { System.out.println("----No Boundary Points----"); pointMap.setAttribute(); } pointMap.setNeigh_PtEdges(triangleMap, edgeMap); pointMap.setIds(); pointMap.setConductivity(); pointMap.setMassDampingVelocity(); pointMap.type(edgeMap); groupRoot.compile(); } private void openFile(java.awt.event.ActionEvent evt) { System.out.println("----Open a file----"); JFileChooser fc = new JFileChooser(); fc.showDialog(null, null); File file = fc.getSelectedFile(); if (fc != null) { processFile(file); } } private void processFile(File file) { System.out.println(file); meshData = new TetraHedronVolumeDataPopulator(file); totalTriangles = meshData.getTriangleNum(); triangles = meshData.getTriangleData(); vertex = meshData.getVertex(); vertex_num = meshData.getVertexNum(); System.out.println("vertex_num=" + vertex_num + " tri_num=" + totalTriangles); } public BranchGroup shading() { BranchGroup shadeGroup = new BranchGroup(); shadeGroup.setCapability(BranchGroup.ALLOW_DETACH); TransformGroup transGroup = new TransformGroup(); transGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ); transGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); shadeGroup.addChild(transGroup); BoundingSphere bounds = new BoundingSphere(new Point3d(0, 0, 0), 100); Color3f white = new Color3f(0.15f, 0.15f, 0.15f); // Set up the ambient light AmbientLight ambientLightNode = new AmbientLight(white); ambientLightNode.setInfluencingBounds(bounds); shadeGroup.addChild(ambientLightNode); // Set up the directional lights Vector3f light1Direction = new Vector3f(-1.0f, -1.0f, -1.0f); Vector3f light2Direction = new Vector3f(1.0f, -1.0f, -1.0f); Vector3f light3Direction = new Vector3f(1.0f, 1.0f, 1.0f); Vector3f light4Direction = new Vector3f(-1.0f, 1.0f, 1.0f); Color3f light1color = new Color3f(0.5f, 0.5f, 0.5f); Color3f light2color = new Color3f(0.3f, 0.3f, 0.3f); Color3f light3color = new Color3f(0.3f, 0.3f, 0.3f); Color3f light4color = new Color3f(0.3f, 0.3f, 0.3f); DirectionalLight light1 = new DirectionalLight(light1color, light1Direction); light1.setInfluencingBounds(bounds); shadeGroup.addChild(light1); DirectionalLight light2 = new DirectionalLight(light2color, light2Direction); light2.setInfluencingBounds(bounds); shadeGroup.addChild(light2); DirectionalLight light3 = new DirectionalLight(light3color, light3Direction); light3.setInfluencingBounds(bounds); shadeGroup.addChild(light3); DirectionalLight light4 = new DirectionalLight(light4color, light4Direction); light4.setInfluencingBounds(bounds); shadeGroup.addChild(light4); System.out.println("\r\n-----Shading-----"); for (STL_TriInfo triInfo : triangleMap.getMap().values()) { LinkedList<Integer> tri_ptids = triInfo.getPointIds(); double[][] points = new double[4][3]; double[][] normals = new double[4][3]; for (int i = 0; i < tri_ptids.size(); i++) { Integer pt_ids = (Integer) tri_ptids.get(i); normals[i] = pointMap.pt_normal(triangleMap, pt_ids); MathTools.normalize(normals[i]); STL_PointInfo ptinf = pointMap.getPointInfo(pt_ids); points[i] = ptinf.getCurPos(); } VSTriangle vstri = new VSTriangle(points, normals); vstri.setCapability(Node.ENABLE_PICK_REPORTING); PickTool.setCapabilities(vstri, PickTool.INTERSECT_FULL); transGroup.addChild(vstri); } shadeGroup.compile(); return shadeGroup; } private void initUserPosition() { ViewingPlatform vp = universe.getViewingPlatform(); TransformGroup steerTG = vp.getViewPlatformTransform(); Transform3D scale = new Transform3D(); steerTG.getTransform(scale); scale.setScale(1 / 100000000); Transform3D t3d = new Transform3D(); steerTG.getTransform(t3d); t3d.mul(scale); t3d.lookAt(new Point3d(100, 0, 100), new Point3d(1000, 0, 1000), new Vector3d(1000, 100, 0)); t3d.invert(); steerTG.setTransform(t3d); } private void orbitControls(Canvas3D c) { MouseBehavior orbit = new MouseBehavior(c); BoundingSphere bounds = new BoundingSphere(new Point3d(0, 0, 0), 1); orbit.setSchedulingBounds(bounds); orbit.setMouseListener(mouseListner); universe.getViewingPlatform().setViewPlatformBehavior(orbit); } private void normalMode(ActionEvent e) { for(Entry<Integer, STL_PointInfo> entry : pointMap.getMap().entrySet()) { STL_PointInfo pt_inf = entry.getValue(); pt_inf.setConductivity(1.0); pt_inf.setSpecificheat(1.0); pt_inf.setTemperature(1.0); pt_inf.setEnvironment_T(1.0); pt_inf.setthermalexpansion(1.0); pt_inf.setPoissonratio(1.0); pt_inf.setShearmodulus(1.0); pt_inf.setDensity(1.0); } } private void shade(){ shadeBranch = shading(); universe.addBranchGraph(shadeBranch); } private Point3d getMousePosition(MouseEvent event) { Point3d mousePos = new Point3d(); canvas.getPixelLocationInImagePlate(event.getX(), event.getY(), mousePos); Transform3D transform = new Transform3D(); canvas.getImagePlateToVworld(transform); transform.transform(mousePos); return mousePos; } private FemMouseListener mouseListner = new FemMouseListener () { private Point3D pointToDrag; @Override public void mousePressed(MouseEvent evt) { pointToDrag = getPickedPoint(evt); } @Override public void mouseClicked(MouseEvent evt) { System.out.println("---Mouse Clicked----"); Point3D point = getPickedPoint(evt); if (point == null) { System.out.println("---No Picked Nodes---"); return; } else { System.out.println("--- Node picked---"); pointInConcern = point.getID(); tfNodeDataX.setText(""+vertex[pointInConcern][0]); tfNodeDataY.setText(""+vertex[pointInConcern][1]); tfNodeDataZ.setText(""+vertex[pointInConcern][2]); } } @Override public void mouseDragged(MouseEvent evt) { if(pointToDrag != null) { System.out.println("--- Node draged---"); pointInConcern = pointToDrag.getID(); double[] xyz = pointMap.getMap().get(pointInConcern).getCurPos(); Point3d newPos = getMousePosition(evt); xyz[0] = newPos.x; xyz[1] = newPos.y; xyz[2] = newPos.z; pointToDrag.update(xyz); tfNodeDataX.setText(""+newPos.x); tfNodeDataY.setText(""+newPos.y); tfNodeDataZ.setText(""+newPos.z); STL_PointEdgeInfo peInfo = pointEdgeMap.getPointEdgeInfo(pointInConcern); for(Integer edgeID : peInfo.getEdgeIDs()) { STL_EdgeInfo edge = edgeMap.getEdge(edgeID); Line3D vsLine = edge.getVSLine(); int anotherID = -1; if(edge.getFpt_Id() == pointInConcern) { anotherID = edge.getSpt_Id(); } else if(edge.getSpt_Id() == pointInConcern ) { anotherID = edge.getFpt_Id(); } if(anotherID != -1) { double[] xyz2 = pointMap.getMap().get(anotherID).getCurPos(); vsLine.update(xyz, xyz2); } } dataProcessor .loadData( meshData, pointInConcern, new double[] { Double.parseDouble(tfNodeDataX .getText()), Double.parseDouble(tfNodeDataY .getText()), Double.parseDouble(tfNodeDataZ .getText()) }, new double[] { Double.parseDouble(tfBodyForceX .getText()), Double.parseDouble(tfBodyForceY .getText()), Double.parseDouble(tfBodyForceZ .getText()) }, Double .parseDouble(tfElasticity .getText()), Double .parseDouble(tfPoissonRatio .getText())); } } @Override public void mouseReleased(MouseEvent evt) { System.out.println("---Mouse Released----"); dataProcessor.process(); } }; } |
Administrator
|
Sorry but you don't use the "official" STL loader org.j3d.loaders.stl.STLFileReader. Why do you shade the interior triangles? Is it intentional?
Julien Gouesse | Personal blog | Website
|
I do not want to shad the interior triangles. But I need to shad only the surface triangles. I do not understand you properly could you please explain more? What is the "official" STL loader "org.j3d.loaders.stl.STLFileReader"? Is it a library class should I use it instead of the current one. If so, Could you please, clarify how I should use it? Currently, I use my own FileLoader. See it below.
package fem; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.io.StreamTokenizer; import java.util.LinkedList; import java.util.List; /** * * @author administrator */ public class FileLoader { private Reader inputReader; private StreamTokenizer tokenizer; /** Creates a new instance of VSTextbyHandFileReader */ public FileLoader(File file) { try { inputReader = new FileReader(file); } catch (java.io.FileNotFoundException e) { System.out.println(e.toString()); } tokenizer = new StreamTokenizer(inputReader); tokenizer.resetSyntax(); tokenizer.whitespaceChars('\0', ' '); tokenizer.wordChars('!', 'z'); tokenizer.eolIsSignificant(true); } public Object[] getNextEventsTokens() { List<String> list = new LinkedList<>(); try { while ((tokenizer.nextToken() != StreamTokenizer.TT_EOF) && (tokenizer.ttype != StreamTokenizer.TT_EOL)) list.add(tokenizer.sval); } catch (java.io.IOException e) { System.out.println(e.toString()); } if (tokenizer.ttype == StreamTokenizer.TT_EOF) return null; else return (list.toArray()); } public void close() { try { inputReader.close(); } catch (IOException e) { System.err.println(e.toString()); } } } |
My current text file is just arranged as
number of (points, elements, nmber of points per element) point 1 point 2 .. . . . . . element 1 element 2 . . . . example for small shape contains of 6 points and 3 elements in tetrahedral of 4 points: 6 3 4 0 0 0 0.1 0 0 0.05 0.05 0 0 0 0.1 0.1 0 0.1 0.05 0.05 0.1 0 1 2 5 0 1 4 5 0 3 4 5 |
Administrator
|
In reply to this post by tamb20
Hi
We provide community support on the tools maintained by the community, this is logical. I force nobody to release any source code but it seems more reasonable to me to advise the use of the libraries and modules tested and developed by several people rather than a (proprietary?) STL loader written by a single person. You can download the source code of the library here: http://code.j3d.org/download.html You can see the source code here too: http://grepcode.com/file/repo1.maven.org/maven2/com.nitayjoffe.thirdparty.org.j3d/j3d-all/1.1/org/j3d/renderer/java3d/loaders/STLLoader.java
Julien Gouesse | Personal blog | Website
|
Thank you
Could you please, declare to me which text format will apply to your code? Is it the format I give to you work with it or not? Also, how your code will read the points , elements and vertexes? Is it by element or vertex or node for shading? I means when you shad the shape, It will shad the internal elements or just the external? How could you do that? Thank you agin. |
Administrator
|
You're welcome. Look at STLAsciiParser for the text based STL file parsing and look at STLBinaryParser for the binary STL file parsing. It's up to you to respect the STL format if you want to use a loader. The STL parser reads the faces but you can access the vertices. I admit that this reader is a bit difficult to use. You can look at the ImageJ 3D viewer (based on Java3D) to see how it is used.
Julien Gouesse | Personal blog | Website
|
Free forum by Nabble | Edit this page |