Commit 34f284c5 by Michael Turner

Merge branch 'feature/geo-curves' into 'master'

Additional GEO curves

See merge request !800
parents 7ca455c4 92d1d0de
......@@ -24,6 +24,7 @@ v5.0.0
- Fix issue with reading CCM files due to definition of default arrays
rather than a vector (!797)
- Fix inverted triangles and small memory issue in surface meshing (!798)
- Additional curve types in GEO reader: BSpline, Circle, Ellipse (!800)
**FieldConvert**:
- Add input module for Semtex field files (!777)
......
......@@ -938,10 +938,20 @@ range of geometrical features.
For a full description of the GEO format the user should refer to Gmsh's
documentation. The following commands are currently supported:
\begin{itemize}
\item \inltt{//} (comments)
\item \inltt{//} (i.e. comments)
\item \inltt{Point}
\item \inltt{Line}
\item \inltt{Spline}
\item \inltt{Spline} (through points)
\item \inltt{BSpline} (i.e. a B\'{e}zier curve)
\item \inltt{Ellipse} (arc): as defined in Gmsh's OpenCASCADE kernel, the first
point defines the start of the arc, the second point the centre and the fourth
point the end. The third point is not used. The start point along with the centre
point form the major axis and the minor axis is then computed so that the end
point falls onto the arc. The major axis must always be greater or equal to the
minor axis.
\item \inltt{Circle} (arc): the circle is a special case of the ellipse where the
third point is skipped. The distances between the start and end points and the
centre point must be equal or an error will be thrown.
\item \inltt{Line Loop}
\item \inltt{Plane Surface}
\end{itemize}
......@@ -950,7 +960,7 @@ At the present time, NekMesh does not support the full scripting capabilities of
GEO format. The used GEO files should be a straightforward succession of entity
creations (see list above). This should however allow for the creation of quite
a wide range of 2D geometries by transformation of arbitrary curves into generic
splines.
splines and arcs.
%%% Local Variables:
......
......@@ -412,6 +412,9 @@ TopoDS_Shape CADSystemOCE::BuildGeo(string geo)
map<int, string> points;
map<int, string> lines;
map<int, string> splines;
map<int, string> bsplines;
map<int, string> circles;
map<int, string> ellipses;
map<int, string> loops;
map<int, string> surfs;
......@@ -465,6 +468,18 @@ TopoDS_Shape CADSystemOCE::BuildGeo(string geo)
{
splines[id] = var;
}
else if (boost::iequals(type, "BSpline"))
{
bsplines[id] = var;
}
else if (boost::iequals(type, "Circle"))
{
circles[id] = var;
}
else if (boost::iequals(type, "Ellipse"))
{
ellipses[id] = var;
}
else if (boost::iequals(type, "Line Loop"))
{
// line loops sometimes have negative entries for gmsh
......@@ -522,6 +537,109 @@ TopoDS_Shape CADSystemOCE::BuildGeo(string geo)
BRepBuilderAPI_MakeEdge em(curve);
cEdges[it->first] = em.Edge();
}
for (it = bsplines.begin(); it != bsplines.end(); it++)
{
vector<unsigned int> data;
ParseUtils::GenerateUnOrderedVector(it->second.c_str(), data);
TColgp_Array1OfPnt pointArray(0, data.size() - 1);
for (int i = 0; i < data.size(); i++)
{
pointArray.SetValue(i, cPoints[data[i]]);
}
Handle(Geom_BezierCurve) curve = new Geom_BezierCurve(pointArray);
BRepBuilderAPI_MakeEdge em(curve);
cEdges[it->first] = em.Edge();
}
for (it = circles.begin(); it != circles.end(); it++)
{
vector<unsigned int> data;
ParseUtils::GenerateUnOrderedVector(it->second.c_str(), data);
ASSERTL0(data.size() == 3, "Wrong definition of circle arc");
gp_Pnt start = cPoints[data[0]];
gp_Pnt centre = cPoints[data[1]];
gp_Pnt end = cPoints[data[2]];
NekDouble r1 = start.Distance(centre);
NekDouble r2 = end.Distance(centre);
ASSERTL0(fabs(r1 - r2) < 1e-7, "Non-matching radii");
gp_Circ c;
c.SetLocation(centre);
c.SetRadius(r1);
Handle(Geom_Circle) gc = new Geom_Circle(c);
ShapeAnalysis_Curve sac;
NekDouble p1, p2;
sac.Project(gc, start, 1e-8, start, p1);
sac.Project(gc, end, 1e-8, end, p2);
// Make sure the arc is always of length less than pi
if ((p1 > p2) ^ (fabs(p2 - p1) > M_PI))
{
swap(p1, p2);
}
Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(gc, p1, p2, false);
BRepBuilderAPI_MakeEdge em(tc);
em.Build();
cEdges[it->first] = em.Edge();
}
for (it = ellipses.begin(); it != ellipses.end(); it++)
{
vector<unsigned int> data;
ParseUtils::GenerateUnOrderedVector(it->second.c_str(), data);
ASSERTL0(data.size() == 4, "Wrong definition of ellipse arc");
gp_Pnt start = cPoints[data[0]];
gp_Pnt centre = cPoints[data[1]];
// data[2] useless??
gp_Pnt end = cPoints[data[3]];
NekDouble major = start.Distance(centre);
gp_Vec v1(centre, start);
gp_Vec v2(centre, end);
gp_Vec vx(1.0, 0.0, 0.0);
NekDouble angle = v1.Angle(vx);
// Check for negative rotation
if (v1.Y() < 0)
{
angle *= -1;
}
v2.Rotate(gp_Ax1(), angle);
NekDouble minor = fabs(v2.Y() / sqrt(1.0 - v2.X() * v2.X() / (major * major)));
gp_Elips e;
e.SetLocation(centre);
e.SetMajorRadius(major);
e.SetMinorRadius(minor);
e.Rotate(e.Axis(), angle);
Handle(Geom_Ellipse) ge = new Geom_Ellipse(e);
ShapeAnalysis_Curve sac;
NekDouble p1, p2;
sac.Project(ge, start, 1e-8, start, p1);
sac.Project(ge, end, 1e-8, end, p2);
// Make sure the arc is always of length less than pi
if (fabs(p2 - p1) > M_PI)
{
swap(p1, p2);
}
Handle(Geom_TrimmedCurve) tc = new Geom_TrimmedCurve(ge, p1, p2, true);
BRepBuilderAPI_MakeEdge em(tc);
em.Build();
cEdges[it->first] = em.Edge();
}
// build wires
map<int, TopoDS_Wire> cWires;
......
......@@ -82,4 +82,11 @@
#include <STEPControl_Writer.hxx>
#include <gp_Ax1.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Ellipse.hxx>
#include <gp_Circ.hxx>
#include <gp_Elips.hxx>
#endif
......@@ -106,6 +106,7 @@ IF(NEKTAR_USE_MESHGEN)
ADD_NEKTAR_TEST(MeshGen/2d-cad)
ADD_NEKTAR_TEST(MeshGen/2d-naca)
ADD_NEKTAR_TEST(MeshGen/geo)
ADD_NEKTAR_TEST(MeshGen/t106c)
ADD_NEKTAR_TEST(MeshGen/t106step)
ADD_NEKTAR_TEST(MeshGen/rev LENGTHY)
ENDIF()
......
Point(1) = {0, 0, 0, 1.0};
Point(2) = {0, 1, 0, 1.0};
Point(3) = {1, 0, 0, 1.0};
Point(4) = {0, -2, 0, 1.0};
Point(5) = {-1, -1.5, 0, 1.0};
Point(6) = {-0.5, -1, 0, 1.0};
Point(7) = {-2, -0.5, 0, 1.0};
Point(8) = {-2, 0, 0, 1.0};
Point(9) = {-1.5, 0.5, 0, 1.0};
Circle(1) = {2, 1, 3};
Ellipse(2) = {4, 1, 0, 3};
BSpline(3) = {4, 5, 6, 7};
Spline(4) = {7, 8, 9, 2};
Line Loop(5) = {4, 1, 2, 3};
Plane Surface(6) = {5};
\ No newline at end of file
<NEKTAR>
<MESHING>
<INFORMATION>
<I PROPERTY="CADFile" VALUE="geo.geo" />
<I PROPERTY="MeshType" VALUE="2D" />
</INFORMATION>
<PARAMETERS>
<P PARAM="MinDelta" VALUE="0.1" />
<P PARAM="MaxDelta" VALUE="0.5" />
<P PARAM="EPS" VALUE="0.01" />
<P PARAM="Order" VALUE="4" />
</PARAMETERS>
<BOOLPARAMETERS>
</BOOLPARAMETERS>
</MESHING>
</NEKTAR>
......@@ -2,10 +2,10 @@
<test>
<description>.geo reader test mesh</description>
<executable>NekMesh</executable>
<parameters>-m jac:list t106c.mcf geo.xml:xml:test</parameters>
<parameters>-m jac:list geo.mcf geo.xml:xml:test</parameters>
<files>
<file description="Input File">t106c.mcf</file>
<file description="Input File 2">t106c.geo</file>
<file description="Input File">geo.mcf</file>
<file description="Input File 2">geo.geo</file>
</files>
<metrics>
<metric type="regex" id="1">
......
<?xml version="1.0" encoding="utf-8" ?>
<test>
<description>.geo reader test mesh</description>
<executable>NekMesh</executable>
<parameters>-m jac:list t106c.mcf geo.xml:xml:test</parameters>
<files>
<file description="Input File">t106c.mcf</file>
<file description="Input File 2">t106c.geo</file>
</files>
<metrics>
<metric type="regex" id="1">
<regex>^Total negative Jacobians: (\d+)</regex>
<matches>
<match>
<field id="0">0</field>
</match>
</matches>
</metric>
</metrics>
</test>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment