/* 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,2008,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.ds;
import gnu.trove.map.hash.TCustomHashMap;
import org.jcae.mesh.cad.CADEdge;
import org.jcae.mesh.cad.CADExplorer;
import org.jcae.mesh.cad.CADFace;
import org.jcae.mesh.cad.CADShape;
import org.jcae.mesh.cad.CADShapeEnum;
import org.jcae.mesh.cad.CADShapeFactory;
import org.jcae.mesh.cad.CADSolid;
import org.jcae.mesh.cad.CADVertex;
import java.util.LinkedHashSet;
import java.util.Collection;
import java.util.Iterator;
import gnu.trove.map.hash.THashMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Mesh graph.
*/
public class BCADGraph
{
private static final Logger LOGGER=Logger.getLogger(BCADGraph.class.getName());
// Backward link to the model
private final BModel model;
// Cell root
private final BCADGraphCell root;
// Map between topological elements and graph cells
private final Map<CADShape, BCADGraphCell> cadShapeToGraphCell =
new TCustomHashMap<CADShape, BCADGraphCell>(KeepOrientationHashingStrategy.getInstance());
// Map between indices and graph cells or user-defined groups
private final TIntObjectHashMap<BCADGraphCell> indexToCell = new TIntObjectHashMap<BCADGraphCell>();
// First free index
private final int freeIndex;
/**
* Creates a root mesh.
*/
BCADGraph (BModel m, CADShape shape)
{
model = m;
if (shape instanceof CADSolid)
root = new BCADGraphCell(this, shape, CADShapeEnum.SOLID);
else if (shape instanceof CADFace)
root = new BCADGraphCell(this, shape, CADShapeEnum.FACE);
else if (shape instanceof CADEdge)
root = new BCADGraphCell(this, shape, CADShapeEnum.EDGE);
else if (shape instanceof CADVertex)
root = new BCADGraphCell(this, shape, CADShapeEnum.VERTEX);
else
root = new BCADGraphCell(this, shape, CADShapeEnum.COMPOUND);
// Build the whole graph
THashMap<CADShape, CADShape> seen = new THashMap<CADShape, CADShape>();
CADShapeFactory factory = CADShapeFactory.getFactory();
CADExplorer exp = factory.newExplorer();
for (CADShapeEnum cse : CADShapeEnum.iterable(CADShapeEnum.VERTEX, CADShapeEnum.COMPOUND))
{
for (exp.init(shape, cse); exp.more(); exp.next())
{
CADShape sub = exp.current();
if (cadShapeToGraphCell.containsKey(sub))
continue;
BCADGraphCell cell = new BCADGraphCell(this, sub, cse);
cadShapeToGraphCell.put(sub, cell);
CADShape r = seen.get(sub);
if (r != null)
{
BCADGraphCell rev = cadShapeToGraphCell.get(r);
rev.bindReversed(cell);
}
seen.put(sub, sub);
if (LOGGER.isLoggable(Level.FINE))
LOGGER.log(Level.FINE, " Add submesh: "+sub+" "+cell);
}
}
// Add indices
int i = 1;
CADExplorer exp2 = factory.newExplorer();
for (CADShapeEnum cse : CADShapeEnum.iterable(CADShapeEnum.COMPOUND, CADShapeEnum.VERTEX))
{
for (exp.init(shape, cse); exp.more(); exp.next())
{
CADShape s = exp.current();
BCADGraphCell c = cadShapeToGraphCell.get(s);
if (c != null && c.getId() <= 0)
{
c.setId(i);
indexToCell.put(i, c);
i++;
}
}
}
freeIndex = i;
// Add backward links
for (CADShapeEnum cse : CADShapeEnum.iterable(CADShapeEnum.COMPOUND, CADShapeEnum.VERTEX))
{
for (exp.init(shape, cse); exp.more(); exp.next())
{
CADShape s = exp.current();
BCADGraphCell c = cadShapeToGraphCell.get(s);
if (c == null)
continue;
for (CADShapeEnum cse2 :CADShapeEnum.iterable(cse, CADShapeEnum.VERTEX))
{
for (exp2.init(s, cse2); exp2.more(); exp2.next())
{
CADShape s2 = exp2.current();
BCADGraphCell c2 = cadShapeToGraphCell.get(s2);
if (c2 != null)
c2.addParent(c);
}
}
}
}
}
public final BModel getModel()
{
return model;
}
public final BCADGraphCell getRootCell()
{
return root;
}
public final int getFreeIndex()
{
return freeIndex;
}
/**
* Gets a graph cell by its shape
*
* @param s CAD shape
* @return graph cell representing s
*/
public final BCADGraphCell getByShape(CADShape s)
{
return cadShapeToGraphCell.get(s);
}
/**
* Gets a graph cell by its identifier
*
* @param i cell index
* @return graph cell with identifier i
*/
public final BCADGraphCell getById(int i)
{
return indexToCell.get(i);
}
/**
* Returns the list of cells for a given dimension.
*/
public final Collection<BCADGraphCell> getCellList(CADShapeEnum cse)
{
CADExplorer exp = CADShapeFactory.getFactory().newExplorer();
Collection<BCADGraphCell> ret = new LinkedHashSet<BCADGraphCell>();
for (exp.init(root.getShape(), cse); exp.more(); exp.next())
{
CADShape s = exp.current();
BCADGraphCell c = cadShapeToGraphCell.get(s);
if (ret.contains(c))
continue;
ret.add(c);
}
return ret;
}
/**
* Prints the list of geometrical elements.
*/
public final void printShapes()
{
System.out.println("List of geometrical entities");
for (CADShapeEnum cse : CADShapeEnum.iterable(CADShapeEnum.VERTEX, CADShapeEnum.COMPOUND))
{
printShapes(cse, root.shapesExplorer(cse));
}
System.out.println("End list");
}
private static void printShapes(CADShapeEnum cse, Iterator<BCADGraphCell> it)
{
while (it.hasNext())
{
BCADGraphCell s = it.next();
if (cse == CADShapeEnum.VERTEX)
{
CADVertex v = (CADVertex) s.getShape();
double [] coord = v.pnt();
System.out.println("Shape "+s+ " ("+coord[0]+", "+coord[1]+", "+coord[2]+")");
}
else
{
System.out.println("Shape "+s+" ("+Integer.toHexString(s.hashCode())+"):");
for (Iterator<BCADGraphCell> it2 = s.allShapesIterator(); it2.hasNext(); )
{
BCADGraphCell c = it2.next();
System.out.println(" +> shape "+c+" ("+Integer.toHexString(c.hashCode())+")");
}
}
}
}
}