Skip to content
Snippets Groups Projects
Commit 0f14b50c authored by Jean-François Remacle's avatar Jean-François Remacle
Browse files

*** empty log message ***

parent 61302378
No related branches found
No related tags found
Loading
......@@ -93,6 +93,9 @@ class GEdge : public GEntity {
// Returns a type-specific additional information string
virtual std::string getAdditionalInfoString();
// tells if the edge is a 3D edge (in opposition with a trimmed curve on a surface)
virtual bool is3D () const {return true;}
struct {
char Method;
double coeffTransfinite;
......
#include "GEdgeLoop.h"
#include "Message.h"
void GEdgeSigned::print() const
{
Msg(INFO,"GEdgeSigned : Edge %d sign %d Ordered Vertices %d,%d",ge->tag(),_sign,getBeginVertex()->tag(),getEndVertex()->tag());
}
int countInList ( std::list<GEdge*> &wire , GEdge *ge)
{
std::list<GEdge*>::iterator it = wire.begin();
std::list<GEdge*>::iterator ite = wire.end();
int count = 0;
while (it != ite)
{
if (*it == ge) count++;
++it;
}
return count;
}
GEdgeSigned nextOne ( GEdgeSigned *thisOne, std::list<GEdge*> &wire)
{
if (!thisOne)
{
GEdge *ge = *(wire.begin());
wire.erase(wire.begin());
return GEdgeSigned ( 1 , ge );
}
GVertex *gv = thisOne->getEndVertex();
std::list<GEdge*> possibleChoices;
std::list<GEdge*>::iterator it = wire.begin();
std::list<GEdge*>::iterator ite = wire.end();
while (it != ite)
{
GEdge *ge = *it;
GVertex *v1 = ge->getBeginVertex();
GVertex *v2 = ge->getEndVertex();
if (v1 == gv || v2 == gv)possibleChoices.push_back(ge);
++it;
}
it = possibleChoices.begin();
ite = possibleChoices.end();
while (it != ite)
{
GEdge *ge = *it;
if (countInList (possibleChoices , ge) == 2)
{
wire.erase(std::remove_if(wire.begin(),wire.end() , std::bind2nd(std::equal_to<GEdge*>(), ge)) ,
wire.end());
wire.push_back(ge);
GVertex *v1 = ge->getBeginVertex();
GVertex *v2 = ge->getEndVertex();
if (v1 == gv)return GEdgeSigned ( 1 , ge );
if (v2 == gv)return GEdgeSigned ( -1 , ge );
throw;
}
++it;
}
it = possibleChoices.begin();
ite = possibleChoices.end();
while (it != ite)
{
GEdge *ge = *it;
if (ge != thisOne->ge)
{
wire.erase(std::remove_if(wire.begin(),wire.end() , std::bind2nd(std::equal_to<GEdge*>(), ge)) ,
wire.end());
GVertex *v1 = ge->getBeginVertex();
GVertex *v2 = ge->getEndVertex();
if (v1 == gv)return GEdgeSigned ( 1 , ge );
if (v2 == gv)return GEdgeSigned ( -1 , ge );
throw;
}
++it;
}
}
int GEdgeLoop::count (GEdge* ge) const
{
GEdgeLoop::citer it = begin();
GEdgeLoop::citer ite = end();
int count = 0;
while (it != ite)
{
if (it->ge == ge) count++;
++it;
}
return count;
}
GEdgeLoop::GEdgeLoop ( const std::list<GEdge*> & cwire )
{
std::list<GEdge*> wire (cwire);
GEdgeSigned *prevOne = 0;
Msg(INFO,"Building a wire");
GEdgeSigned ges(0,0);
while (wire.size())
{
ges = nextOne ( prevOne , wire );
prevOne = &ges;
ges.print();
loop.push_back(ges);
}
}
#ifndef _GEDGELOOP_H_
#define _GEDGELOOP_H_
// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to <gmsh@geuz.org>.
#include "GEdge.h"
#include <list>
struct GEdgeSigned
{
int _sign;
GEdge *ge;
GEdgeSigned ( int i, GEdge*g )
: _sign(i) , ge(g)
{}
GVertex * getBeginVertex() const
{
return (_sign==1)?ge->getBeginVertex():ge->getEndVertex();
}
GVertex * getEndVertex() const
{
return (_sign!=1)?ge->getBeginVertex():ge->getEndVertex();
}
void print() const;
};
class GEdgeLoop
{
public:
typedef std::list<GEdgeSigned>::iterator iter;
typedef std::list<GEdgeSigned>::const_iterator citer;
GEdgeLoop ( const std::list<GEdge*> &);
inline iter begin () {return loop.begin();}
inline iter end () {return loop.end();}
inline citer begin () const {return loop.begin();}
inline citer end () const {return loop.end();}
int count (GEdge*) const;
private:
std::list< GEdgeSigned > loop ;
};
#endif
// $Id: GFace.cpp,v 1.19 2006-11-15 20:46:46 remacle Exp $
// $Id: GFace.cpp,v 1.20 2006-11-16 18:32:41 remacle Exp $
//
// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
//
......@@ -388,13 +388,6 @@ double GFace::curvature (const SPoint2 &param) const
return c;
}
// edges are given, compute their orientation
// i.e. two following edges should
void GFace :: computeDirs ()
{
throw;
}
void GFace::XYZtoUV(const double X, const double Y, const double Z,
double &U, double &V,
const double relax) const
......
......@@ -22,13 +22,13 @@
#include "GPoint.h"
#include "GEntity.h"
#include "GEdgeLoop.h"
#include "MElement.h"
#include "SPoint2.h"
#include "SVector3.h"
#include "Pair.h"
#include "ExtrudeParams.h"
#include <set>
struct mean_plane
{
......@@ -43,10 +43,8 @@ class GRegion;
class GFace : public GEntity
{
protected:
// in a manifold representation, edges can
// be taken twice in the topology in order
// to represent the periodicity of the surface
std::set<GEdge *> edges_taken_twice;
// edge loops, will replace what follows
std::list<GEdgeLoop> edgeLoops;
// list of al the edges of the face
std::list<GEdge *> l_edges;
std::list<int> l_dirs;
......@@ -54,7 +52,11 @@ class GFace : public GEntity
mean_plane meanPlane;
std::list<GEdge *> embedded_edges;
std::list<GVertex *> embedded_vertices;
void computeDirs ();
// given a list of GEdges, the function builds a
// list of wires, i.e. closed edge loops.
// the first wire is the one that is the
// outer contour of the face.
void resolveWires ();
public:
GFace(GModel *model, int tag);
......
// $Id: GModelIO_OCC.cpp,v 1.5 2006-11-16 01:56:52 geuzaine Exp $
// $Id: GModelIO_OCC.cpp,v 1.6 2006-11-16 18:32:41 remacle Exp $
//
// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
//
......@@ -29,10 +29,23 @@
#include "OCCFace.h"
#include "OCCRegion.h"
#include "ShapeAnalysis_ShapeTolerance.hxx"
#include "ShapeAnalysis_ShapeContents.hxx"
#include "ShapeAnalysis_CheckSmallFace.hxx"
#include "ShapeAnalysis_DataMapOfShapeListOfReal.hxx"
#include "BRepAlgoAPI_Fuse.hxx"
#include "BRepCheck_Analyzer.hxx"
#include "BRepLib.hxx"
#include "ShapeBuild_ReShape.hxx"
#include "ShapeFix.hxx"
#include "ShapeFix_FixSmallFace.hxx"
class OCC_Internals
{
TopoDS_Shape shape;
TopTools_IndexedMapOfShape fmap, emap, vmap, somap, shmap, wmap;
double tolerance;
public:
OCC_Internals ()
{
......@@ -42,7 +55,9 @@ public:
wmap.Clear();
emap.Clear();
vmap.Clear();
tolerance = 1.e-5;
}
void HealGeometry (bool fixsmalledges = true, bool fixspotstripfaces = true, bool sewfaces = false, bool makesolids = false);
void loadSTEP(const char *);
void loadIGES(const char *);
void loadBREP(const char *);
......@@ -263,10 +278,216 @@ void OCC_Internals :: buildLists ()
}
void OCC_Internals :: HealGeometry (bool fixsmalledges , bool fixspotstripfaces, bool sewfaces, bool makesolids)
{
int nrc = 0, nrcs = 0,
nrso = somap.Extent(),
nrsh = shmap.Extent(),
nrf = fmap.Extent(),
nrw = wmap.Extent(),
nre = emap.Extent(),
nrv = vmap.Extent();
TopExp_Explorer e;
for (e.Init(shape, TopAbs_COMPOUND); e.More(); e.Next()) nrc++;
for (e.Init(shape, TopAbs_COMPSOLID); e.More(); e.Next()) nrcs++;
double surfacecont = 0;
for (int i = 1; i <= fmap.Extent(); i++)
{
GProp_GProps system;
BRepGProp::LinearProperties(fmap(i), system);
surfacecont += system.Mass();
}
cout << "Starting geometry healing procedure (tolerance: " << tolerance << ")" << endl
<< "-----------------------------------" << endl;
if (fixsmalledges)
{
cout << endl << "- fixing small edges" << endl;
Handle(ShapeFix_Wire) sfw;
Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
rebuild->Apply(shape);
for (int i = 1; i <= fmap.Extent(); i++)
{
TopExp_Explorer exp1;
for (exp1.Init (fmap(i), TopAbs_WIRE); exp1.More(); exp1.Next())
{
TopoDS_Wire oldwire = TopoDS::Wire(exp1.Current());
sfw = new ShapeFix_Wire (oldwire, TopoDS::Face(fmap(i)),tolerance);
sfw->ModifyTopologyMode() = Standard_True;
if (sfw->FixSmall (false, tolerance))
{
cout << "Fixed small edge in wire " << wmap.FindIndex (oldwire) << endl;
TopoDS_Wire newwire = sfw->Wire();
rebuild->Replace(oldwire, newwire, Standard_False);
}
if ((sfw->StatusSmall(ShapeExtend_FAIL1)) ||
(sfw->StatusSmall(ShapeExtend_FAIL2)) ||
(sfw->StatusSmall(ShapeExtend_FAIL3)))
cout << "Failed to fix small edge in wire " << wmap.FindIndex (oldwire) << endl;
}
}
shape = rebuild->Apply(shape);
{
Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
rebuild->Apply(shape);
TopExp_Explorer exp1;
for (exp1.Init (shape, TopAbs_EDGE); exp1.More(); exp1.Next())
{
TopoDS_Edge edge = TopoDS::Edge(exp1.Current());
if (vmap.FindIndex(TopExp::FirstVertex (edge)) ==
vmap.FindIndex(TopExp::LastVertex (edge)))
{
GProp_GProps system;
BRepGProp::LinearProperties(edge, system);
if (system.Mass() < tolerance)
{
cout << "removing degenerated edge " << emap.FindIndex(edge) << endl;
rebuild->Remove(edge, false);
}
}
}
shape = rebuild->Apply(shape);
}
Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe;
sfwf->SetPrecision(tolerance);
sfwf->Load (shape);
if (sfwf->FixSmallEdges())
{
cout << endl << "- fixing wire frames" << endl;
if (sfwf->StatusSmallEdges(ShapeExtend_OK)) cout << "no small edges found" << endl;
if (sfwf->StatusSmallEdges(ShapeExtend_DONE1)) cout << "some small edges fixed" << endl;
if (sfwf->StatusSmallEdges(ShapeExtend_FAIL1)) cout << "failed to fix some small edges" << endl;
}
if (sfwf->FixWireGaps())
{
cout << endl << "- fixing wire gaps" << endl;
if (sfwf->StatusWireGaps(ShapeExtend_OK)) cout << "no gaps found" << endl;
if (sfwf->StatusWireGaps(ShapeExtend_DONE1)) cout << "some 2D gaps fixed" << endl;
if (sfwf->StatusWireGaps(ShapeExtend_DONE2)) cout << "some 3D gaps fixed" << endl;
if (sfwf->StatusWireGaps(ShapeExtend_FAIL1)) cout << "failed to fix some 2D gaps" << endl;
if (sfwf->StatusWireGaps(ShapeExtend_FAIL2)) cout << "failed to fix some 3D gaps" << endl;
}
shape = sfwf->Shape();
}
if (fixspotstripfaces)
{
cout << endl << "- fixing spot and strip faces" << endl;
Handle(ShapeFix_FixSmallFace) sffsm = new ShapeFix_FixSmallFace();
sffsm -> Init (shape);
sffsm -> SetPrecision (tolerance);
sffsm -> Perform();
shape = sffsm -> FixShape();
}
if (sewfaces)
{
cout << endl << "- sewing faces" << endl;
TopExp_Explorer exp0;
BRepOffsetAPI_Sewing sewedObj(tolerance);
for (exp0.Init (shape, TopAbs_FACE); exp0.More(); exp0.Next())
{
TopoDS_Face face = TopoDS::Face (exp0.Current());
sewedObj.Add (face);
}
sewedObj.Perform();
if (!sewedObj.SewedShape().IsNull())
shape = sewedObj.SewedShape();
else
cout << " not possible";
}
if (makesolids)
{
cout << endl << "- making solids" << endl;
TopExp_Explorer exp0;
BRepBuilderAPI_MakeSolid ms;
int count = 0;
for (exp0.Init(shape, TopAbs_SHELL); exp0.More(); exp0.Next())
{
count++;
ms.Add (TopoDS::Shell(exp0.Current()));
}
if (!count)
{
cout << " not possible (no shells)" << endl;
}
else
{
BRepCheck_Analyzer ba(ms);
if (ba.IsValid ())
{
Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
sfs->Init (ms);
sfs->SetPrecision(tolerance);
sfs->SetMaxTolerance(tolerance);
sfs->Perform();
shape = sfs->Shape();
for (exp0.Init(shape, TopAbs_SOLID); exp0.More(); exp0.Next())
{
TopoDS_Solid solid = TopoDS::Solid(exp0.Current());
TopoDS_Solid newsolid = solid;
BRepLib::OrientClosedSolid (newsolid);
Handle_ShapeBuild_ReShape rebuild = new ShapeBuild_ReShape;
// rebuild->Apply(shape);
rebuild->Replace(solid, newsolid, Standard_False);
TopoDS_Shape newshape = rebuild->Apply(shape, TopAbs_COMPSOLID, 1);
// TopoDS_Shape newshape = rebuild->Apply(shape);
shape = newshape;
}
}
else
cout << " not possible" << endl;
}
}
buildLists();
}
void OCC_Internals :: loadBREP (const char *fn)
{
BRep_Builder aBuilder;
Standard_Boolean result = BRepTools::Read( shape, (char*)fn, aBuilder );
BRepTools::Clean (shape);
buildLists();
// HealGeometry();
BRepTools::Clean (shape);
}
void OCC_Internals :: loadSTEP (const char *fn)
......@@ -276,6 +497,7 @@ void OCC_Internals :: loadSTEP (const char *fn)
Standard_Integer nb = reader.NbRootsForTransfer();
reader.TransferRoots ();
shape = reader.OneShape();
BRepTools::Clean (shape);
}
void OCC_Internals :: loadIGES (const char *fn)
......@@ -285,6 +507,7 @@ void OCC_Internals :: loadIGES (const char *fn)
Standard_Integer nb = reader.NbRootsForTransfer();
reader.TransferRoots ();
shape = reader.OneShape();
BRepTools::Clean (shape);
}
void OCC_Internals :: buildGModel (GModel *model)
......@@ -348,6 +571,7 @@ int GModel::readOCCBREP(const std::string &fn)
occ_internals = new OCC_Internals;
occ_internals->loadBREP (fn.c_str());
occ_internals->buildLists ();
// occ_internals->HealGeometry();
occ_internals->buildGModel (this);
return 1;
}
......
This diff is collapsed.
// $Id: OCCEdge.cpp,v 1.4 2006-11-15 20:46:46 remacle Exp $
// $Id: OCCEdge.cpp,v 1.5 2006-11-16 18:32:41 remacle Exp $
//
// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
//
......@@ -21,12 +21,17 @@
#if defined(HAVE_OCC)
#include "GModel.h"
#include "Message.h"
#include "OCCEdge.h"
OCCEdge::OCCEdge(GModel *model, TopoDS_Edge edge, int num, GVertex *v1, GVertex *v2)
: GEdge(model, num, v1, v2), c(edge)
{
curve = BRep_Tool::Curve(edge, s0, s1);
curve = BRep_Tool::Curve(c, s0, s1);
if (curve.IsNull())
{
Msg(WARNING,"OCC Curve %d is not a 3D curve",tag());
}
}
Range<double> OCCEdge::parBounds(int i) const
......@@ -38,8 +43,16 @@ Range<double> OCCEdge::parBounds(int i) const
GPoint OCCEdge::point(double par) const
{
gp_Pnt pnt = curve->Value (par);
return GPoint(pnt.X(),pnt.Y(),pnt.Z());
double s0,s1;
if (!curve.IsNull())
{
gp_Pnt pnt = curve->Value (par);
return GPoint(pnt.X(),pnt.Y(),pnt.Z());
}
else
{
return GPoint(0,0,0);
}
}
GPoint OCCEdge::closestPoint(const SPoint3 & qp)
......@@ -54,8 +67,7 @@ int OCCEdge::containsParam(double pt) const
}
SVector3 OCCEdge::firstDer(double par) const
{
{
BRepAdaptor_Curve brepc(c);
BRepLProp_CLProps prop(brepc, 1, 1e-5);
prop.SetParameter (par);
......
......@@ -28,8 +28,9 @@
class OCCEdge : public GEdge {
protected:
TopoDS_Edge c;
Handle(Geom_Curve) curve;
double s0,s1;
Handle(Geom_Curve) curve;
Handle(Geom2d_Curve) curve2d;
public:
OCCEdge(GModel *model, TopoDS_Edge _e, int num, GVertex *v1, GVertex *v2);
......@@ -52,6 +53,7 @@ class OCCEdge : public GEdge {
virtual double parFromPoint(const SPoint3 &pt) const;
virtual int minimumMeshSegments () const;
virtual int minimumDrawSegments () const;
bool is3D() const {return !curve.IsNull();}
};
#endif
// $Id: OCCFace.cpp,v 1.5 2006-11-15 20:46:46 remacle Exp $
// $Id: OCCFace.cpp,v 1.6 2006-11-16 18:32:41 remacle Exp $
//
// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
//
......@@ -17,10 +17,11 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to <OCC@geuz.org>.
// Please report all bugs and problems to <gmsh@geuz.org>.
#if defined(HAVE_OCC)
#include "GModel.h"
#include "GEdgeLoop.h"
#include "OCCVertex.h"
#include "OCCEdge.h"
#include "OCCFace.h"
......@@ -35,64 +36,27 @@ OCCFace::OCCFace(GModel *m, TopoDS_Face _s, int num, TopTools_IndexedMapOfShape
TopoDS_Shape wire = exp2.Current();
Msg(INFO,"OCC Face %d - New Wire",num);
std::list<GEdge*> l_wire;
std::set<GEdge*> testPeriodic;
for (exp3.Init (wire, TopAbs_EDGE); exp3.More(); exp3.Next())
{
TopoDS_Edge edge = TopoDS::Edge (exp3.Current());
int index = emap.FindIndex(edge);
GEdge *e = m->edgeByTag(index);
if(!e) throw;
if (testPeriodic.find(e) !=testPeriodic.end()){
_periodic = true;
edges_taken_twice.insert(e);
}
else testPeriodic.insert(e);
l_edges.push_back(e);
l_wire.push_back(e);
e->addFace(this);
}
if (l_wire.size() == 1)l_dirs.push_back(1);
else if (!_periodic)
GEdgeLoop el (l_wire);
for (GEdgeLoop::citer it = el.begin() ; it != el.end() ; ++it)
{
GVertex *last;
std::list<GEdge*>::iterator it = l_wire.begin();
GEdge *e1 = *it;
++it;
GEdge *e2 = *it;
if (e1->getEndVertex() == e2->getEndVertex() ||e1->getEndVertex() == e2->getBeginVertex())
{
last = e1->getEndVertex();
l_dirs.push_back(1);
Msg(INFO,"OCC Face %d - Edge %d (%d,%d) dir 1",num,e1->tag(),e1->getBeginVertex()->tag(),e1->getEndVertex()->tag());
}
else if (e1->getBeginVertex() == e2->getEndVertex() ||e1->getBeginVertex() == e2->getBeginVertex())
{
last = e1->getBeginVertex();
l_dirs.push_back(-1);
Msg(INFO,"OCC Face %d - Edge %d (%d,%d) dir -1",num,e1->tag(),e1->getBeginVertex()->tag(),e1->getEndVertex()->tag());
}
for ( ; it != l_wire.end() ; ++it)
{
GEdge *e = *it;
if ( last == e->getBeginVertex())
{
l_dirs.push_back(1);
last = e->getEndVertex();
Msg(INFO,"OCC Face %d - Edge %d (%d,%d) dir 1",num,e->tag(),e->getBeginVertex()->tag(),e->getEndVertex()->tag());
}
else if (last == e->getEndVertex())
{
l_dirs.push_back(-1);
last = e->getBeginVertex();
Msg(INFO,"OCC Face %d - Edge %d (%d,%d) dir -1",num,e->tag(),e->getBeginVertex()->tag(),e->getEndVertex()->tag());
}
else
{
Msg(GERROR,"Incoherent surface %d Edge %d (%d,%d) ",num,e->tag(),e->getBeginVertex()->tag(),e->getEndVertex()->tag());
}
}
}
if(!it->ge->is3D())_periodic = true;
if (el.count (it->ge) > 1)_periodic = true;
l_edges.push_back(it->ge);
l_dirs.push_back(it->_sign);
}
edgeLoops.push_back(el);
}
Msg(INFO,"OCC Face %d with %d edges",num,l_edges.size());
......
// $Id: meshGEdge.cpp,v 1.15 2006-11-15 20:46:46 remacle Exp $
// $Id: meshGEdge.cpp,v 1.16 2006-11-16 18:32:41 remacle Exp $
//
// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
//
......@@ -139,6 +139,7 @@ void deMeshGEdge :: operator() (GEdge *ge)
void meshGEdge :: operator() (GEdge *ge)
{
if(ge->geomType() == GEntity::DiscreteCurve) return;
if(!ge->is3D()) return;
// Send a messsage to the GMSH environment
Msg(INFO, "Meshing curve %d", ge->tag());
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment