/* jCAE stand for Java Computer Aided Engineering. Features are : Small CAD
modeler, Finite element mesher, Plugin architecture.
Copyright (C) 2004,2005,2006, by EADS CRC
Copyright (C) 2007, 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.amibe.ds;
import java.util.Collection;
public class TriangleHE extends Triangle
{
private static final long serialVersionUID = 3364148266246993225L;
// In this class, adjacency relations are supported by an HalfEdge instance,
// which is created by ElementFactory.createTriangle.
private HalfEdge e0;
/**
* Constructor.
*/
TriangleHE(Vertex v0, Vertex v1, Vertex v2)
{
super(v0, v1, v2);
}
@Override
public final void copy(Triangle src)
{
super.copy(src);
e0.copy(((TriangleHE) src).e0);
}
/**
* Gets an <code>AbstractHalfEdge</code> instance bound to this triangle.
* This method returns <code>HalfEdge</code> 0.
* @return an <code>HalfEdge</code> instance bound to this triangle
*/
@Override
public final HalfEdge getAbstractHalfEdge()
{
return e0;
}
/**
* Gets an <code>AbstractHalfEdge</code> instance bound to this triangle.
* This method returns <code>HalfEdge</code> 0, argument is unused
* @param that dummy argument
* @return an <code>HalfEdge</code> instance bound to this triangle
*/
@Override
public HalfEdge getAbstractHalfEdge(AbstractHalfEdge that)
{
return e0;
}
/**
* Sets <code>HalfEdge</code> 0 of this triangle. This method must not
* be called, it is meant to be used by {@link ElementFactory#createTriangle}.
*
* @param e edge to set as edge 0 of this triangle
*/
final void setHalfEdge(HalfEdge e)
{
e0 = e;
}
/**
* Sets attributes for all edges of this triangle.
*
* @param attr attributes to set on edges
*/
@Override
public void setAttributes(int attr)
{
e0.setAttributes(attr);
e0.next().setAttributes(attr);
e0.prev().setAttributes(attr);
}
/**
* Resets attributes for all edges of this triangle.
*
* @param attr attributes to reset on edges
*/
@Override
public void clearAttributes(int attr)
{
e0.clearAttributes(attr);
e0.next().clearAttributes(attr);
e0.prev().clearAttributes(attr);
}
/**
* Checks if some attributes of this triangle are set.
*
* @param attr attributes to check
* @return <code>true</code> if any edge of this triangle has
* one of these attributes set, <code>false</code> otherwise
*/
@Override
public boolean hasAttributes(int attr)
{
return e0.hasAttributes(attr) || e0.next().hasAttributes(attr) || e0.prev().hasAttributes(attr);
}
@Override
public final String toString()
{
StringBuilder r = new StringBuilder(super.toString());
r.append("\nEdge attributes: ").append(e0.getAttributes());
if (null != e0.next())
{
r.append(" n=").append(e0.next().getAttributes());
if (null != e0.prev())
r.append(" p=").append(e0.prev().getAttributes());
}
return r.toString();
}
/** Replace this triangle by t in v link */
private void replaceTriangle(Vertex v, Triangle t)
{
if(v.getLink() == this)
v.setLink(t);
else if(!v.isManifold())
{
Triangle[] ts = (Triangle[])v.getLink();
for(int i = 0; i < ts.length; i++)
if(ts[i] == this)
ts[i] = t;
}
}
/** Split at barycenter */
public void split(Mesh mesh)
{
Vertex uv = mesh.createVertex(0,0,0);
uv.add(v0);
uv.add(v1);
uv.add(v2);
uv.scale(1/3.0);
split(mesh, uv, null);
}
private void glue(HalfEdge oldHE, Triangle t)
{
AbstractHalfEdge newHE = t.getAbstractHalfEdge();
oldHE.sym().glue(newHE);
newHE.setAttributes(oldHE.getAttributes());
}
public void split(Mesh mesh, Vertex v, Collection<Triangle> output)
{
assert v != null;
//TODO reuse the current instance and create only 2 new triangles
Triangle t1 = mesh.createTriangle(v, v0, v1);
replaceTriangle(v0, t1);
t1.setGroupId(getGroupId());
Triangle t2 = mesh.createTriangle(v, v1, v2);
replaceTriangle(v1, t2);
t2.setGroupId(getGroupId());
Triangle t3 = mesh.createTriangle(v, v2, v0);
replaceTriangle(v2, t3);
t3.setGroupId(getGroupId());
v.setLink(t1);
AbstractHalfEdge t1he = t1.getAbstractHalfEdge().next();
AbstractHalfEdge t2he = t2.getAbstractHalfEdge().next();
AbstractHalfEdge t3he = t3.getAbstractHalfEdge().next();
t1he.glue(t2he.next());
t2he.glue(t3he.next());
t3he.glue(t1he.next());
HalfEdge oldHE = e0;
glue(oldHE, t2);
oldHE = oldHE.next();
glue(oldHE, t3);
oldHE = oldHE.next();
glue(oldHE, t1);
if(output != null)
{
output.add(t1);
output.add(t2);
output.add(t3);
}
if(mesh.hasNodes())
mesh.add(v);
mesh.add(t1);
mesh.add(t2);
mesh.add(t3);
mesh.remove(this);
}
}