Commit 7bbf58d2 authored by mike's avatar mike

added factories to the CADsystem

parent b5474726
......@@ -192,6 +192,7 @@ INCLUDE (ThirdPartyOCC)
INCLUDE (ThirdPartyTetGen)
INCLUDE (ThirdPartyANN)
INCLUDE (ThirdPartyCCM)
INCLUDE (ThirdPartyCFI)
INCLUDE (Doxygen)
......
......@@ -2,17 +2,17 @@
#
# ThirdParty configuration for Nektar++
#
# Star CCM i/o
# Star CCM i/o
#
########################################################################
OPTION(NEKTAR_USE_CCM
OPTION(NEKTAR_USE_CCM
"CCM star i/o library is available." OFF)
IF( NEKTAR_USE_CCM )
FIND_LIBRARY(CCMIO_LIBRARY NAMES "ccmio" "adf" PATHS /usr/local/lib ${Nektar++_TP_LIBRARY_DIRS})
IF( CCMIO_LIBRARY )
MESSAGE(STATUS "Found Ccmio: ${CCMIO_LIBRARY}")
MESSAGE(STATUS "Found Ccmio: ${CCMIO_LIBRARY}")
MARK_AS_ADVANCED(CCMIO_LIBRARY)
ADD_DEFINITIONS(-DNEKTAR_USE_CCM)
FIND_PATH (CCMIO_INCLUDE_DIR ccmio.h)
......
......@@ -15,7 +15,7 @@ IF(NEKTAR_USE_MESHGEN)
ELSE()
SET(BUILD_OCC ON)
ENDIF()
OPTION(THIRDPARTY_BUILD_OCC "Build OpenCascade library from ThirdParty."
${BUILD_OCC})
......@@ -33,7 +33,7 @@ IF(NEKTAR_USE_MESHGEN)
IF(WIN32)
MESSAGE(SEND_ERROR "Cannot currently use OpenCascade with Nektar++ on Windows")
ENDIF()
EXTERNALPROJECT_ADD(
opencascade-6.9
PREFIX ${TPSRC}
......
......@@ -36,13 +36,6 @@
#ifndef NEKMESHUTILS_CADSYSTEM_CADCURVE
#define NEKMESHUTILS_CADSYSTEM_CADCURVE
#include <boost/shared_ptr.hpp>
#include <LibUtilities/BasicUtils/SharedArray.hpp>
#include <LibUtilities/Memory/NekMemoryManager.hpp>
#include <NekMeshUtils/CADSystem/OpenCascade.h>
#include <NekMeshUtils/CADSystem/CADObj.h>
#include <NekMeshUtils/CADSystem/CADVert.h>
#include <NekMeshUtils/CADSystem/CADSurf.h>
......@@ -66,7 +59,7 @@ public:
/**
* @brief Default constructor.
*/
CADCurve(int i, TopoDS_Shape in);
CADCurve(){};
~CADCurve(){};
......@@ -75,7 +68,11 @@ public:
*
* @return Array of two entries, min and max parametric coordinate.
*/
Array<OneD, NekDouble> Bounds();
virtual Array<OneD, NekDouble> Bounds()
{
ASSERTL0(false,"must be implement at derived level");
return Array<OneD, NekDouble>();
}
/**
* @brief Calculates the arclength between the two paremetric points \p ti
......@@ -85,7 +82,11 @@ public:
* @param tf Second parametric coordinate.
* @return Arc length between \p ti and \p tf.
*/
NekDouble Length(NekDouble ti, NekDouble tf);
virtual NekDouble Length(NekDouble ti, NekDouble tf)
{
ASSERTL0(false,"must be implement at derived level");
return 0.0;
}
/**
* @brief Gets the location (x,y,z) in an array out of the curve at
......@@ -94,12 +95,20 @@ public:
* @param t Parametric coordinate
* @return Array of x,y,z
*/
Array<OneD, NekDouble> P(NekDouble t);
virtual Array<OneD, NekDouble> P(NekDouble t)
{
ASSERTL0(false,"must be implement at derived level");
return Array<OneD, NekDouble>();
}
/**
* @brief Gets the second derivatives at t
*/
Array<OneD, NekDouble> D2(NekDouble t);
virtual Array<OneD, NekDouble> D2(NekDouble t)
{
ASSERTL0(false,"must be implement at derived level");
return Array<OneD, NekDouble>();
}
/**
* @brief Calculates the parametric coordinate and arclength location
......@@ -110,14 +119,22 @@ public:
*
* @todo This really needs improving for accuracy.
*/
NekDouble tAtArcLength(NekDouble s);
virtual NekDouble tAtArcLength(NekDouble s)
{
ASSERTL0(false,"must be implement at derived level");
return 0.0;
}
/**
* @brief Gets the start and end of the curve.
*
* @return Array with 6 entries of endpoints x1,y1,z1,x2,y2,z2.
*/
Array<OneD, NekDouble> GetMinMax();
virtual Array<OneD, NekDouble> GetMinMax()
{
ASSERTL0(false,"must be implement at derived level");
return Array<OneD, NekDouble>();
}
/// set the ids of the surfaces either side of the curve
void SetAdjSurf(std::vector<CADSurfSharedPtr> i)
......@@ -152,11 +169,7 @@ public:
return m_mainVerts;
}
private:
/// OpenCascade object of the curve.
BRepAdaptor_Curve m_occCurve;
/// OpenCascade edge
TopoDS_Edge m_occEdge;
protected:
/// Length of edge
NekDouble m_length;
/// List of surfaces which this curve belongs to.
......@@ -166,6 +179,11 @@ private:
};
typedef boost::shared_ptr<CADCurve> CADCurveSharedPtr;
typedef LibUtilities::NekFactory<EngineKey,CADCurve> CADCurveFactory;
CADCurveFactory& GetCADCurveFactory();
}
}
......
......@@ -53,12 +53,6 @@ enum cadType
surf
};
/**
* @brief class for CAD curves.
*
* This class wraps the OpenCascade BRepAdaptor_Curve class for use with
* Nektar++.
*/
class CADObj
{
public:
......
......@@ -36,14 +36,9 @@
#ifndef NekMeshUtils_CADSYSTEM_CADSURF
#define NekMeshUtils_CADSYSTEM_CADSURF
#include <boost/shared_ptr.hpp>
#include <LibUtilities/BasicUtils/SharedArray.hpp>
#include <LibUtilities/Memory/NekMemoryManager.hpp>
#include <NekMeshUtils/CADSystem/OpenCascade.h>
#include <NekMeshUtils/CADSystem/CADObj.h>
#include <NekMeshUtils/CADSystem/CADVert.h>
#include <NekMeshUtils/CADSystem/CADSystem.h>
namespace Nektar
{
......@@ -53,18 +48,6 @@ namespace NekMeshUtils
class CADCurve;
typedef boost::shared_ptr<CADCurve> CADCurveSharedPtr;
/**
* @brief struct which descibes a collection of cad edges which for a
* loop on the cad surface
*/
struct EdgeLoop
{
std::vector<CADCurveSharedPtr> edges;
std::vector<int> edgeo; //0 is forward 1 is backward
Array<OneD, NekDouble> center;
NekDouble area;
};
/**
* @brief class for handleing a cad surface
*/
......@@ -77,7 +60,7 @@ public:
/**
* @brief Default constructor.
*/
CADSurf(int i, TopoDS_Shape in, std::vector<EdgeLoop> ein);
CADSurf(){};
~CADSurf(){};
......@@ -100,16 +83,10 @@ public:
*
* @return Array of 4 entries with parametric umin,umax,vmin,vmax.
*/
Array<OneD, NekDouble> GetBounds()
virtual Array<OneD, NekDouble> GetBounds()
{
Array<OneD,NekDouble> b(4);
b[0] = m_occSurface.FirstUParameter();
b[1] = m_occSurface.LastUParameter();
b[2] = m_occSurface.FirstVParameter();
b[3] = m_occSurface.LastVParameter();
return b;
ASSERTL0(false,"must be implement at derived level");
return Array<OneD, NekDouble>();
}
/**
......@@ -118,7 +95,11 @@ public:
* @param uv Array of u and v parametric coords.
* @return Array of xyz components of normal vector.
*/
Array<OneD, NekDouble> N (Array<OneD, NekDouble> uv);
virtual Array<OneD, NekDouble> N (Array<OneD, NekDouble> uv)
{
ASSERTL0(false,"must be implement at derived level");
return Array<OneD, NekDouble>();
}
/**
* @brief Get the set of first derivatives at parametric point u,v
......@@ -126,7 +107,11 @@ public:
* @param uv Array of u and v parametric coords.
* @return Array of xyz copmonents of first derivatives.
*/
Array<OneD, NekDouble> D1 (Array<OneD, NekDouble> uv);
virtual Array<OneD, NekDouble> D1 (Array<OneD, NekDouble> uv)
{
ASSERTL0(false,"must be implement at derived level");
return Array<OneD, NekDouble>();
}
/**
* @brief Get the set of second derivatives at parametric point u,v
......@@ -134,7 +119,11 @@ public:
* @param uv array of u and v parametric coords
* @return array of xyz copmonents of second derivatives
*/
Array<OneD, NekDouble> D2 (Array<OneD, NekDouble> uv);
virtual Array<OneD, NekDouble> D2 (Array<OneD, NekDouble> uv)
{
ASSERTL0(false,"must be implement at derived level");
return Array<OneD, NekDouble>();
}
/**
* @brief Get the x,y,z at parametric point u,v.
......@@ -142,7 +131,11 @@ public:
* @param uv Array of u and v parametric coords.
* @return Array of xyz location.
*/
Array<OneD, NekDouble> P (Array<OneD, NekDouble> uv);
virtual Array<OneD, NekDouble> P (Array<OneD, NekDouble> uv)
{
ASSERTL0(false,"must be implement at derived level");
return Array<OneD, NekDouble>();
}
/**
* @brief Performs a reverse look up to find u,v and x,y,z.
......@@ -150,12 +143,40 @@ public:
* @param p Array of xyz location
* @return The parametric location of xyz on this surface
*/
Array<OneD, NekDouble> locuv(Array<OneD, NekDouble> p);
virtual Array<OneD, NekDouble> locuv(Array<OneD, NekDouble> p)
{
ASSERTL0(false,"must be implement at derived level");
return Array<OneD, NekDouble>();
}
/**
* @brief does unconstrained locuv to project point from anywhere
* and calculate the distance between the orthonormal projection to the surface
* and the point
*/
virtual NekDouble DistanceTo(Array<OneD, NekDouble> p)
{
ASSERTL0(false,"must be implement at derived level");
return 0.0;
}
/**
* @brief takes a point from anywhere find the nearest surface point and its
* uv
*/
virtual void ProjectTo(Array<OneD, NekDouble> &tp, Array<OneD, NekDouble> &uv)
{
ASSERTL0(false,"must be implement at derived level");
}
/**
* @brief returns true if the surface is flat (2D)
* @brief returns curvature at point uv
*/
bool IsPlane();
virtual NekDouble Curvature(Array<OneD, NekDouble> uv)
{
ASSERTL0(false,"must be implement at derived level");
return 0.0;
}
/**
* @brief sets the flag to reverse the normal for this suface,
......@@ -172,50 +193,26 @@ public:
return !m_correctNormal;
}
/**
* @brief surface needs to know if it is bounded by only two curves
*/
void SetTwoC()
{
m_hasTwoCurves = true;
}
/**
* @brief query two curves
*/
bool GetTwoC(){return m_hasTwoCurves;}
/**
* @brief does unconstrained locuv to project point from anywhere
*/
NekDouble DistanceTo(Array<OneD, NekDouble> p);
void ProjectTo(Array<OneD, NekDouble> &tp, Array<OneD, NekDouble> &uv);
/**
* @brief returns curvature at point uv
*/
NekDouble Curvature(Array<OneD, NekDouble> uv);
private:
void Initialise(int i, TopoDS_Shape in);
/// Function which tests the the value of uv used is within the surface
void Test(Array<OneD, NekDouble> uv);
protected:
/// normal
bool m_correctNormal;
/// flag to alert the mesh generation to a potential problem is both
/// curves have only two points in the mesh
bool m_hasTwoCurves;
/// OpenCascade object for surface.
BRepAdaptor_Surface m_occSurface;
/// Alternate OpenCascade object for surface. Used by reverse lookup.
Handle(Geom_Surface) m_s;
/// Function which tests the the value of uv used is within the surface
virtual void Test(Array<OneD, NekDouble> uv)
{
ASSERTL0(false,"must be implement at derived level");
}
/// List of bounding edges in loops with orientation.
std::vector<EdgeLoop> m_edges;
};
typedef boost::shared_ptr<CADSurf> CADSurfSharedPtr;
typedef LibUtilities::NekFactory<EngineKey,CADSurf> CADSurfFactory;
CADSurfFactory& GetCADSurfFactory();
}
}
......
......@@ -33,14 +33,10 @@
//
////////////////////////////////////////////////////////////////////////////////
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <NekMeshUtils/CADSystem/CADSystem.h>
#include <NekMeshUtils/CADSystem/CADObj.h>
#include <NekMeshUtils/CADSystem/CADVert.h>
#include <NekMeshUtils/CADSystem/CADCurve.h>
#include <NekMeshUtils/CADSystem/CADSurf.h>
#include "CADSystem.h"
#include "CADVert.h"
#include "CADCurve.h"
#include "CADSurf.h"
using namespace std;
......@@ -49,414 +45,42 @@ namespace Nektar
namespace NekMeshUtils
{
string CADSystem::GetName()
std::ostream& operator<<(std::ostream&os, const EngineKey& rhs)
{
return m_name;
return os << rhs.second;
}
void CADSystem::Report()
EngineFactory& GetEngineFactory()
{
cout << endl << "CAD report:" << endl;
cout << "\tCAD has: " << m_curves.size() << " curves." << endl;
cout << "\tCAD has: " << m_surfs.size() << " surfaces." << endl;
typedef Loki::SingletonHolder<EngineFactory, Loki::CreateUsingNew,
Loki::NoDestroy, Loki::SingleThreaded>
Type;
return Type::Instance();
}
Array<OneD, NekDouble> CADSystem::GetBoundingBox()
CADVertFactory& GetCADVertFactory()
{
Array<OneD, NekDouble> bound(6);
bound[0] = numeric_limits<double>::max(); // xmin
bound[1] = numeric_limits<double>::min(); // xmax
bound[2] = numeric_limits<double>::max(); // ymin
bound[3] = numeric_limits<double>::min(); // ymax
bound[4] = numeric_limits<double>::max(); // zmin
bound[5] = numeric_limits<double>::min(); // zmax
for (int i = 1; i <= m_curves.size(); i++)
{
CADCurveSharedPtr c = GetCurve(i);
Array<OneD, NekDouble> ends = c->GetMinMax();
bound[0] = min(bound[0], min(ends[0], ends[3]));
bound[1] = max(bound[1], max(ends[0], ends[3]));
bound[2] = min(bound[2], min(ends[1], ends[4]));
bound[3] = max(bound[3], max(ends[1], ends[4]));
bound[4] = min(bound[4], min(ends[2], ends[5]));
bound[5] = max(bound[5], max(ends[2], ends[5]));
}
return bound;
typedef Loki::SingletonHolder<CADVertFactory, Loki::CreateUsingNew,
Loki::NoDestroy, Loki::SingleThreaded>
Type;
return Type::Instance();
}
vector<int> CADSystem::GetBoundarySurfs()
CADCurveFactory& GetCADCurveFactory()
{
vector<int> ret;
set<int> surfs;
vector<CADCurveSharedPtr> cs;
Array<OneD, NekDouble> bound = GetBoundingBox();
for (int i = 1; i <= m_curves.size(); i++)
{
CADCurveSharedPtr c = GetCurve(i);
Array<OneD, NekDouble> ends = c->GetMinMax();
if((fabs(bound[0] - ends[0]) < 1e-4 ||
fabs(bound[0] - ends[3]) < 1e-4 ||
fabs(bound[1] - ends[0]) < 1e-4 ||
fabs(bound[1] - ends[3]) < 1e-4)
&&
(fabs(bound[2] - ends[1]) < 1e-4 ||
fabs(bound[2] - ends[4]) < 1e-4 ||
fabs(bound[3] - ends[1]) < 1e-4 ||
fabs(bound[3] - ends[4]) < 1e-4)
&&
(fabs(bound[4] - ends[2]) < 1e-4 ||
fabs(bound[4] - ends[5]) < 1e-4 ||
fabs(bound[5] - ends[2]) < 1e-4 ||
fabs(bound[5] - ends[5]) < 1e-4) )
{
//curve touches on bounding box
cs.push_back(c);
}
}
for(int i = 0; i < cs.size(); i++)
{
vector<CADSurfSharedPtr> s = cs[i]->GetAdjSurf();
for(int j = 0; j < s.size(); j++)
{
surfs.insert(s[j]->GetId());
}
}
set<int>::iterator it;
for(it = surfs.begin(); it != surfs.end(); it++)
{
ret.push_back(*it);
}
return ret;
typedef Loki::SingletonHolder<CADCurveFactory, Loki::CreateUsingNew,
Loki::NoDestroy, Loki::SingleThreaded>
Type;
return Type::Instance();
}
bool CADSystem::LoadCAD()
CADSurfFactory& GetCADSurfFactory()
{
if (!boost::filesystem::exists(m_name.c_str()))
{
return false;
}
string ext;
size_t pos = m_name.find(".");
ext = m_name.substr(pos);
if (boost::iequals(ext, ".STEP") || boost::iequals(ext, ".STP"))
{
// Takes step file and makes OpenCascade shape
STEPControl_Reader reader;
reader = STEPControl_Reader();
reader.ReadFile(m_name.c_str());
reader.NbRootsForTransfer();
reader.TransferRoots();
shape = reader.OneShape();
if (shape.IsNull())
{
return false;
}
}
else if (boost::iequals(ext, ".IGES") || boost::iequals(ext, ".IGS"))
{
// Takes IGES file and makes OpenCascade shape
IGESControl_Reader reader;
reader = IGESControl_Reader();
reader.ReadFile(m_name.c_str());
reader.NbRootsForTransfer();
reader.TransferRoots();
shape = reader.OneShape();
if (shape.IsNull())
{
return false;
}
}
else
{
return false;
}
// faces and verts can be extracted straight from shape
TopTools_IndexedMapOfShape mapOfVerts, mapOfFaces;
TopExp::MapShapes(shape, TopAbs_VERTEX, mapOfVerts);
TopExp::MapShapes(shape, TopAbs_FACE, mapOfFaces);
// edges need to be built from loops around faces to elimiate degen and
// hanging edges
TopTools_IndexedMapOfShape mapOfEdges;
// build map of verticies
for (int i = 1; i <= mapOfVerts.Extent(); i++)
{
TopoDS_Shape v = mapOfVerts.FindKey(i);
AddVert(i, v);
}
// For each face of the geometry, get the local edges which bound it. If
// they are valid (their type != 7), then add them to an edge map. This
// filters out the dummy edges which OCC uses.
for (int i = 1; i <= mapOfFaces.Extent(); i++)
{
TopoDS_Shape face = mapOfFaces.FindKey(i);
TopTools_IndexedMapOfShape localEdges;
TopExp::MapShapes(face, TopAbs_EDGE, localEdges);
for (int j = 1; j <= localEdges.Extent(); j++)
{