Skip to content
Snippets Groups Projects
Commit 96fe8118 authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

more work on stl representations

parent 8ae51f98
No related branches found
No related tags found
No related merge requests found
...@@ -178,12 +178,9 @@ SOrientedBoundingBox GFace::getOBB() ...@@ -178,12 +178,9 @@ SOrientedBoundingBox GFace::getOBB()
} }
} }
else if(buildSTLTriangulation()) { else if(buildSTLTriangulation()) {
int N = va_geom_triangles->getNumVertices(); for (unsigned int i = 0; i < stl_vertices.size(); i++){
for (int i = 0; i < N; i++) { GPoint p = point(stl_vertices[i]);
SPoint3 p((va_geom_triangles->getVertexArray(3 * i))[0], vertices.push_back(SPoint3(p.x(), p.y(), p.z()));
(va_geom_triangles->getVertexArray(3 * i))[1],
(va_geom_triangles->getVertexArray(3 * i))[2]);
vertices.push_back(p);
} }
} }
else { else {
...@@ -789,10 +786,16 @@ SVector3 GFace::normal(const SPoint2 &param) const ...@@ -789,10 +786,16 @@ SVector3 GFace::normal(const SPoint2 &param) const
return n; return n;
} }
bool GFace::buildRepresentationCross() bool GFace::buildRepresentationCross(bool force)
{ {
if(cross.size()){
if(force)
cross.clear();
else
return true;
}
if(geomType() != Plane){ if(geomType() != Plane){
// don't try again
cross.clear(); cross.clear();
cross.push_back(SPoint3(0., 0., 0.)); cross.push_back(SPoint3(0., 0., 0.));
return false; return false;
...@@ -804,7 +807,6 @@ bool GFace::buildRepresentationCross() ...@@ -804,7 +807,6 @@ bool GFace::buildRepresentationCross()
GEdge *ge = *it; GEdge *ge = *it;
if(ge->geomType() == GEntity::DiscreteCurve || if(ge->geomType() == GEntity::DiscreteCurve ||
ge->geomType() == GEntity::BoundaryLayerCurve){ ge->geomType() == GEntity::BoundaryLayerCurve){
// don't try again
cross.clear(); cross.clear();
cross.push_back(SPoint3(0., 0., 0.)); cross.push_back(SPoint3(0., 0., 0.));
return false; return false;
...@@ -853,8 +855,8 @@ bool GFace::buildRepresentationCross() ...@@ -853,8 +855,8 @@ bool GFace::buildRepresentationCross()
} }
if(end_line) cross.push_back(pt_last_inside); if(end_line) cross.push_back(pt_last_inside);
} }
// if we couldn't determine a cross, add a dummy point so that // if we couldn't determine a cross, add a dummy point so that we
// we won't try again // won't try again unless we force the recomputation
if(!cross.size()){ if(!cross.size()){
cross.push_back(SPoint3(0., 0., 0.)); cross.push_back(SPoint3(0., 0., 0.));
return false; return false;
...@@ -862,69 +864,81 @@ bool GFace::buildRepresentationCross() ...@@ -862,69 +864,81 @@ bool GFace::buildRepresentationCross()
return true; return true;
} }
struct graphics_point{
double xyz[3];
SVector3 n;
};
bool GFace::buildSTLTriangulation(bool force) bool GFace::buildSTLTriangulation(bool force)
{ {
// Build a simple triangulation for surfaces which we know are not if(stl_triangles.size()){
// trimmed if(force){
if(geomType() != ParametricSurface && geomType() != ProjectionFace) stl_vertices.clear();
return false; stl_triangles.clear();
}
if(va_geom_triangles){
if(force)
delete va_geom_triangles;
else else
return true; return true;
} }
// Build a simple triangulation for surfaces which we know are not
// trimmed
if(geomType() == ParametricSurface || geomType() == ProjectionFace){
const int nu = 64, nv = 64; const int nu = 64, nv = 64;
va_geom_triangles = new VertexArray(3, 2 * (nu - 1) * (nv - 1));
graphics_point p[nu][nv];
Range<double> ubounds = parBounds(0); Range<double> ubounds = parBounds(0);
Range<double> vbounds = parBounds(1); Range<double> vbounds = parBounds(1);
double umin = ubounds.low(), umax = ubounds.high(); double umin = ubounds.low(), umax = ubounds.high();
double vmin = vbounds.low(), vmax = vbounds.high(); double vmin = vbounds.low(), vmax = vbounds.high();
for(int i = 0; i < nu; i++){ for(int i = 0; i < nu; i++){
for(int j = 0; j < nv; j++){ for(int j = 0; j < nv; j++){
double u = umin + (double)i / (double)(nu - 1) * (umax - umin); double u = umin + (double)i / (double)(nu - 1) * (umax - umin);
double v = vmin + (double)j / (double)(nv - 1) * (vmax - vmin); double v = vmin + (double)j / (double)(nv - 1) * (vmax - vmin);
GPoint gp = point(u, v); stl_vertices.push_back(SPoint2(u, v));
p[i][j].xyz[0] = gp.x();
p[i][j].xyz[1] = gp.y();
p[i][j].xyz[2] = gp.z();
p[i][j].n = normal(SPoint2(u, v));
} }
} }
// i,j+1 *---* i+1,j+1
// | / |
// i,j *---* i+1,j
unsigned int c = CTX::instance()->color.geom.surface;
unsigned int col[4] = {c, c, c, c};
for(int i = 0; i < nu - 1; i++){ for(int i = 0; i < nu - 1; i++){
for(int j = 0; j < nv - 1; j++){ for(int j = 0; j < nv - 1; j++){
double x1[3] = {p[i][j].xyz[0], p[i + 1][j].xyz[0], p[i + 1][j + 1].xyz[0]}; stl_triangles.push_back(i * nv + j);
double y1[3] = {p[i][j].xyz[1], p[i + 1][j].xyz[1], p[i + 1][j + 1].xyz[1]}; stl_triangles.push_back((i + 1) * nv + j);
double z1[3] = {p[i][j].xyz[2], p[i + 1][j].xyz[2], p[i + 1][j + 1].xyz[2]}; stl_triangles.push_back((i + 1) * nv + j + 1);
SVector3 n1[3] = {p[i][j].n, p[i + 1][j].n, p[i + 1][j + 1].n}; stl_triangles.push_back(i * nv + j);
va_geom_triangles->add(x1, y1, z1, n1, col); stl_triangles.push_back((i + 1) * nv + j + 1);
double x2[3] = {p[i][j].xyz[0], p[i + 1][j + 1].xyz[0], p[i][j + 1].xyz[0]}; stl_triangles.push_back(i * nv + j + 1);
double y2[3] = {p[i][j].xyz[1], p[i + 1][j + 1].xyz[1], p[i][j + 1].xyz[1]};
double z2[3] = {p[i][j].xyz[2], p[i + 1][j + 1].xyz[2], p[i][j + 1].xyz[2]};
SVector3 n2[3] = {p[i][j].n, p[i + 1][j + 1].n, p[i][j + 1].n};
va_geom_triangles->add(x2, y2, z2, n2, col);
} }
} }
va_geom_triangles->finalize();
return true; return true;
} }
// build STL for general surfaces here
return false;
}
bool GFace::fillVertexArray(bool force)
{
if(va_geom_triangles){
if(force)
delete va_geom_triangles;
else
return true;
}
if(!buildSTLTriangulation(force)) return false;
if(stl_triangles.empty()) return false;
va_geom_triangles = new VertexArray(3, stl_triangles.size() / 3);
unsigned int c = CTX::instance()->color.geom.surface;
unsigned int col[4] = {c, c, c, c};
for (unsigned int i = 0; i < stl_triangles.size(); i += 3){
SPoint2 &p1(stl_vertices[stl_triangles[i]]);
SPoint2 &p2(stl_vertices[stl_triangles[i + 1]]);
SPoint2 &p3(stl_vertices[stl_triangles[i + 2]]);
GPoint gp1 = point(p1);
GPoint gp2 = point(p2);
GPoint gp3 = point(p3);
double x[3] = {gp1.x(), gp2.x(), gp3.x()};
double y[3] = {gp1.y(), gp2.y(), gp3.y()};
double z[3] = {gp1.z(), gp2.z(), gp3.z()};
SVector3 n[3] = {normal(p1), normal(p2), normal(p3)};
va_geom_triangles->add(x, y, z, n, col);
}
va_geom_triangles->finalize();
}
// by default we assume that straight lines are geodesics // by default we assume that straight lines are geodesics
SPoint2 GFace::geodesic(const SPoint2 &pt1 , const SPoint2 &pt2 , double t) SPoint2 GFace::geodesic(const SPoint2 &pt1 , const SPoint2 &pt2 , double t)
{ {
......
...@@ -191,13 +191,15 @@ class GFace : public GEntity ...@@ -191,13 +191,15 @@ class GFace : public GEntity
virtual void writeGEO(FILE *fp); virtual void writeGEO(FILE *fp);
// fill the crude representation cross // fill the crude representation cross
virtual bool buildRepresentationCross(); virtual bool buildRepresentationCross(bool force=false);
// build a STL triangulation and fills the vertex array // build an STL triangulation (or do nothing if it already exists,
// va_geom_triangles (or do nothing if it already exists, unless // unless force=true)
// force=true)
virtual bool buildSTLTriangulation(bool force=false); virtual bool buildSTLTriangulation(bool force=false);
// fill the vertex array using an STL triangulation
bool fillVertexArray(bool force=false);
// recompute the mean plane of the surface from a list of points // recompute the mean plane of the surface from a list of points
void computeMeanPlane(const std::vector<MVertex*> &points); void computeMeanPlane(const std::vector<MVertex*> &points);
void computeMeanPlane(const std::vector<SPoint3> &points); void computeMeanPlane(const std::vector<SPoint3> &points);
......
...@@ -94,7 +94,6 @@ class GFaceCompound : public GFace { ...@@ -94,7 +94,6 @@ class GFaceCompound : public GFace {
ModelType getNativeType() const { return GmshModel; } ModelType getNativeType() const { return GmshModel; }
void * getNativePtr() const { return 0; } void * getNativePtr() const { return 0; }
virtual SPoint2 getCoordinates(MVertex *v) const; virtual SPoint2 getCoordinates(MVertex *v) const;
virtual bool buildRepresentationCross(){ return false; }
virtual double curvatureMax(const SPoint2 &param) const; virtual double curvatureMax(const SPoint2 &param) const;
virtual int genusGeom (); virtual int genusGeom ();
private: private:
......
...@@ -152,12 +152,9 @@ SOrientedBoundingBox GRegion::getOBB() ...@@ -152,12 +152,9 @@ SOrientedBoundingBox GRegion::getOBB()
} }
} }
else if ((*b_face)->buildSTLTriangulation()) { else if ((*b_face)->buildSTLTriangulation()) {
int N = (*b_face)->va_geom_triangles->getNumVertices(); for (unsigned int i = 0; i < (*b_face)->stl_vertices.size(); i++){
for(int i = 0; i < N; i++) { GPoint p = (*b_face)->point((*b_face)->stl_vertices[i]);
SPoint3 p(((*b_face)->va_geom_triangles->getVertexArray(3*i))[0], vertices.push_back(SPoint3(p.x(), p.y(), p.z()));
((*b_face)->va_geom_triangles->getVertexArray(3*i))[1],
((*b_face)->va_geom_triangles->getVertexArray(3*i))[2]);
vertices.push_back(p);
} }
} }
else { else {
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include "OCCEdge.h" #include "OCCEdge.h"
#include "OCCFace.h" #include "OCCFace.h"
#include "Numeric.h" #include "Numeric.h"
#include "VertexArray.h"
#include "Context.h" #include "Context.h"
#if defined(HAVE_OCC) #if defined(HAVE_OCC)
...@@ -84,7 +83,6 @@ OCCFace::OCCFace(GModel *m, TopoDS_Face _s, int num, TopTools_IndexedMapOfShape ...@@ -84,7 +83,6 @@ OCCFace::OCCFace(GModel *m, TopoDS_Face _s, int num, TopTools_IndexedMapOfShape
umax += fabs(du) / 100.0; umax += fabs(du) / 100.0;
vmax += fabs(dv) / 100.0; vmax += fabs(dv) / 100.0;
occface = BRep_Tool::Surface(s); occface = BRep_Tool::Surface(s);
if(!CTX::instance()->batch) buildSTLTriangulation();
} }
Range<double> OCCFace::parBounds(int i) const Range<double> OCCFace::parBounds(int i) const
...@@ -305,16 +303,15 @@ surface_params OCCFace::getSurfaceParams() const ...@@ -305,16 +303,15 @@ surface_params OCCFace::getSurfaceParams() const
bool OCCFace::buildSTLTriangulation(bool force) bool OCCFace::buildSTLTriangulation(bool force)
{ {
if(va_geom_triangles){ if(stl_triangles.size()){
if(force) if(force){
delete va_geom_triangles; stl_vertices.clear();
stl_triangles.clear();
}
else else
return true; return true;
} }
stl_vertices.clear();
stl_triangles.clear();
Bnd_Box aBox; Bnd_Box aBox;
BRepBndLib::Add(s, aBox); BRepBndLib::Add(s, aBox);
Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
...@@ -355,23 +352,6 @@ bool OCCFace::buildSTLTriangulation(bool force) ...@@ -355,23 +352,6 @@ bool OCCFace::buildSTLTriangulation(bool force)
stl_triangles.push_back(p3 - 1); stl_triangles.push_back(p3 - 1);
} }
va_geom_triangles = new VertexArray(3, stl_triangles.size() / 3);
unsigned int c = CTX::instance()->color.geom.surface;
unsigned int col[4] = {c, c, c, c};
for (unsigned int i = 0; i < stl_triangles.size(); i += 3){
SPoint2 &p1(stl_vertices[stl_triangles[i]]);
SPoint2 &p2(stl_vertices[stl_triangles[i + 1]]);
SPoint2 &p3(stl_vertices[stl_triangles[i + 2]]);
GPoint gp1 = GFace::point(p1);
GPoint gp2 = GFace::point(p2);
GPoint gp3 = GFace::point(p3);
double x[3] = {gp1.x(), gp2.x(), gp3.x()};
double y[3] = {gp1.y(), gp2.y(), gp3.y()};
double z[3] = {gp1.z(), gp2.z(), gp3.z()};
SVector3 n[3] = {normal(p1), normal(p2), normal(p3)};
va_geom_triangles->add(x, y, z, n, col);
}
va_geom_triangles->finalize();
return true; return true;
} }
......
...@@ -237,6 +237,17 @@ class drawGFace { ...@@ -237,6 +237,17 @@ class drawGFace {
void _drawParametricGFace(GFace *f) void _drawParametricGFace(GFace *f)
{ {
if (f->geomType() == GEntity::CompoundSurface) return; if (f->geomType() == GEntity::CompoundSurface) return;
if(CTX::instance()->geom.surfaceType > 0){
// avoid reentrant calls
static bool busy = false;
if(!busy) {
busy = true;
f->fillVertexArray(f->geomType() == GEntity::ProjectionFace);
busy = false;
}
}
Range<double> ubounds = f->parBounds(0); Range<double> ubounds = f->parBounds(0);
Range<double> vbounds = f->parBounds(1); Range<double> vbounds = f->parBounds(1);
const double uav = 0.5 * (ubounds.high() + ubounds.low()); const double uav = 0.5 * (ubounds.high() + ubounds.low());
...@@ -307,20 +318,27 @@ class drawGFace { ...@@ -307,20 +318,27 @@ class drawGFace {
} }
void _drawPlaneGFace(GFace *f) void _drawPlaneGFace(GFace *f)
{ {
if(CTX::instance()->geom.surfaceType > 0){
// avoid reentrant calls
static bool busy = false;
if(!busy) {
busy = true;
f->fillVertexArray();
busy = false;
}
}
if(!CTX::instance()->geom.surfaceType || !f->va_geom_triangles || if(!CTX::instance()->geom.surfaceType || !f->va_geom_triangles ||
CTX::instance()->geom.surfacesNum || CTX::instance()->geom.normals){ CTX::instance()->geom.surfacesNum || CTX::instance()->geom.normals){
// We create data here and the routine is not designed to be // avoid reentrant calls
// reentrant, so we must lock it to avoid race conditions when
// redraw events are fired in rapid succession
static bool busy = false; static bool busy = false;
if(f->cross.empty() && !busy) { if(!busy) {
busy = true; busy = true;
f->buildRepresentationCross(); f->buildRepresentationCross();
busy = false; busy = false;
} }
} }
//FIXME: cleanup buildGraphicsRep
if(CTX::instance()->geom.surfaces) { if(CTX::instance()->geom.surfaces) {
if(CTX::instance()->geom.surfaceType > 0 && f->va_geom_triangles){ if(CTX::instance()->geom.surfaceType > 0 && f->va_geom_triangles){
_drawVertexArray(f->va_geom_triangles, CTX::instance()->geom.light, _drawVertexArray(f->va_geom_triangles, CTX::instance()->geom.light,
......
...@@ -11,6 +11,38 @@ ...@@ -11,6 +11,38 @@
// A solver element. // A solver element.
/*
class SFunctionSpace{
public:
}
class SFunctionSpaceXFEM : public SFunctionSpace{
static simpleFunction<double> *_enrichement_s, *_enrichement_t;
// gradient of functions (possibly enriched)
void nodalFunctions ( double u, double v, double w, double s[],
simpleFunction<double> *_enrichement);
void gradNodalFunctions ( double u, double v, double w, double invjac[3][3],
double grad[][3], simpleFunction<double> *_enrichment);
public:
static void setShapeEnrichement(simpleFunction<double>*f){_enrichement_s=f;}
static void setTestEnrichement(simpleFunction<double>*f){_enrichement_t=f;}
static const simpleFunction<double>* getShapeEnrichement(){return _enrichement_s;}
static const simpleFunction<double>* getTestEnrichement(){return _enrichement_t;}
int getNumNodalShapeFunctions() const;
inline MVertex *getVertex(int i) const {return _e->getParent() ? _e->getParent()->getVertex(i) : _e->getVertex(i) ; }
int getNumNodalTestFunctions() const;
void nodalShapeFunctions ( double u, double v, double w, double s[]);
void gradNodalShapeFunctions ( double u, double v, double w, double invjac[3][3],
double grad[][3]);
void nodalTestFunctions ( double u, double v, double w, double s[]);
void gradNodalTestFunctions ( double u, double v, double w, double invjac[3][3],
double grad[][3]);
}
*/
class SElement class SElement
{ {
private: private:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment