/* * This program 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 program 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 program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * * (C) Copyright 2012, by EADS France */ package org.jcae.vtk; import gnu.trove.list.array.TIntArrayList; import java.io.IOException; import org.jcae.mesh.xmldata.AmibeWriter; import vtk.vtkDataArray; import vtk.vtkIdTypeArray; import vtk.vtkIntArray; import vtk.vtkNativeLibrary; import vtk.vtkPolyData; import vtk.vtkXMLPolyDataReader; /** * * Save a vtkPolyData mesh as an Amibe mesh * @author Jerome Robert */ public class AmibePolyDataWriter { static { vtkNativeLibrary.LoadNativeLibraries(vtkNativeLibrary.VTKCOMMONDATAMODEL); } private final vtkPolyData polyData; private final String[] groupNames; public AmibePolyDataWriter(vtkPolyData polyData, String[] groupNames) { this.polyData = polyData; this.groupNames = groupNames; } public void write(String outDir) throws IOException { // Amibe writer object for 3D elements AmibeWriter.Dim3 out = new AmibeWriter.Dim3(outDir); out.setFixNoGroup(true); //Read Point Data int n = polyData.GetNumberOfPoints(); for (int i = 0; i < n; i++) out.addNode(polyData.GetPoint(i)); //Beams vtkIdTypeArray lineIdArray = polyData.GetLines().GetData(); n = lineIdArray.GetSize(); for (int i = 0; i < n; i += 3) out.addBeam(lineIdArray.GetValue(i + 1), lineIdArray.GetValue(i + 2)); //Triangles polyData.GetPolys().Squeeze(); vtkIdTypeArray polyIdArray = polyData.GetPolys().GetData(); n = polyIdArray.GetSize(); for (int j = 0; j < n; j += 4) { if (polyIdArray.GetValue(j) != 3) throw new IllegalArgumentException( "Expected cell type 3, found " + polyIdArray.GetValue(j)); out.addTriangle(polyIdArray.GetValue(j + 1), polyIdArray.GetValue(j + 2), polyIdArray.GetValue(j + 3)); } convertGroupData(out); out.finish(); } /** Create group names if they are not provided */ private String[] createGroupNames(vtkDataArray triGrps, vtkDataArray nodeGrps) { int nbGroups = 0; if(triGrps instanceof vtkIntArray) nbGroups = ((vtkIntArray)triGrps).GetValueRange()[1]; if(nodeGrps instanceof vtkIntArray) nbGroups = Math.max(((vtkIntArray)nodeGrps).GetValueRange()[1], nbGroups); String[] toReturn; if(groupNames == null) { toReturn = new String[nbGroups]; for(int i = 0; i < nbGroups; i++) toReturn[i] = Integer.toString(i); } else toReturn = groupNames; if(toReturn.length < nbGroups) throw new IllegalArgumentException( "Invalid group names. Expected size is "+nbGroups+" will provided is "+toReturn.length); return toReturn; } private void convertGroupData(AmibeWriter.Dim3 out) throws IOException { int nbBeams = polyData.GetNumberOfLines(); vtkDataArray array = polyData.GetCellData().GetArray("Groups"); vtkDataArray nArray = polyData.GetPointData().GetArray("Groups"); String[] lGrpNames = createGroupNames(array, nArray); TIntArrayList[] eGroups = new TIntArrayList[lGrpNames.length]; for(int i = 0; i < eGroups.length; i++) eGroups[i] = new TIntArrayList(); if(array instanceof vtkIntArray) { int[] groups = ((vtkIntArray)array).GetJavaArray(); for(int i = 0; i < groups.length; i++) { if(groups[i] > 0) eGroups[groups[i]-1].add(i); } for(int i = 0; i < eGroups.length; i++) { if(!eGroups[i].isEmpty()) { out.nextGroup(lGrpNames[i]); for(int j:eGroups[i].toArray()) { if(j < nbBeams) out.addBeamToGroup(j); else out.addTriaToGroup(j-nbBeams); } } } } for(TIntArrayList t:eGroups) t.clear(); if(nArray instanceof vtkIntArray) { int[] groups = ((vtkIntArray)nArray).GetJavaArray(); for(int i = 0; i < groups.length; i++) { if(groups[i] > 0) eGroups[groups[i]-1].add(i); } for(int i = 0; i < eGroups.length; i++) { if(!eGroups[i].isEmpty()) { out.nextNodeGroup(lGrpNames[i]); for(int j:eGroups[i].toArray()) out.addNodeToGroup(j); } } } } /** Shortcut to convert a VTP file to an Amibe directory */ public static void vtpToAmibe(String inputFile, String outputDir) throws IOException { vtkXMLPolyDataReader reader = new vtkXMLPolyDataReader(); reader.SetFileName(inputFile); reader.Update(); new AmibePolyDataWriter(reader.GetOutput(), null).write(outputDir); } }