* Added OpenCascade XDE Support to enable importing of individual surface colours from STEP Geometry

* Extended the Clipping Planes functionality to the Geometry mode for OCC Geometry
* Added the option to specify the maximum mesh size for each individual face in an OCC Geometry
This commit is contained in:
Philippose Rajan 2009-01-30 22:17:20 +00:00
parent 34bfd4a349
commit 85867fb240
5 changed files with 2005 additions and 1796 deletions

View File

@ -564,8 +564,9 @@ namespace netgen
// Philippose - 15/01/2009
double maxh = mparam.maxh; double maxh = geom.face_maxh[k-1];
//double maxh = mparam.maxh;
mparam.checkoverlap = 0; mparam.checkoverlap = 0;
// int noldpoints = mesh->GetNP(); // int noldpoints = mesh->GetNP();
int noldsurfel = mesh.GetNSE(); int noldsurfel = mesh.GetNSE();
@ -1085,456 +1086,465 @@ namespace netgen
int OCCGenerateMesh (OCCGeometry & geom, int OCCGenerateMesh (OCCGeometry & geom,
Mesh *& mesh, Mesh *& mesh,
int perfstepsstart, int perfstepsend, int perfstepsstart, int perfstepsend,
char * optstr) char * optstr)
{ {
// int i, j; // int i, j;
multithread.percent = 0; multithread.percent = 0;
if (perfstepsstart <= MESHCONST_ANALYSE) if (perfstepsstart <= MESHCONST_ANALYSE)
{ {
delete mesh; delete mesh;
mesh = new Mesh(); mesh = new Mesh();
mesh->geomtype = Mesh::GEOM_OCC; mesh->geomtype = Mesh::GEOM_OCC;
mesh->SetGlobalH (mparam.maxh); mesh->SetGlobalH (mparam.maxh);
mesh->SetMinimalH (mparam.minh); mesh->SetMinimalH (mparam.minh);
Array<double> maxhdom; Array<double> maxhdom;
maxhdom.SetSize (geom.NrSolids()); maxhdom.SetSize (geom.NrSolids());
maxhdom = mparam.maxh; maxhdom = mparam.maxh;
mesh->SetMaxHDomain (maxhdom); mesh->SetMaxHDomain (maxhdom);
Box<3> bb = geom.GetBoundingBox(); Box<3> bb = geom.GetBoundingBox();
bb.Increase (bb.Diam()/10); bb.Increase (bb.Diam()/10);
mesh->SetLocalH (bb.PMin(), bb.PMax(), 0.5); mesh->SetLocalH (bb.PMin(), bb.PMax(), 0.5);
if (mparam.uselocalh)
{
if (mparam.uselocalh) const char * savetask = multithread.task;
{ multithread.percent = 0;
const char * savetask = multithread.task; mesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading);
multithread.percent = 0;
mesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading); int nedges = geom.emap.Extent();
int nedges = geom.emap.Extent(); double maxedgelen = 0;
double minedgelen = 1e99;
double maxedgelen = 0; multithread.task = "Setting local mesh size (elements per edge)";
double minedgelen = 1e99;
// setting elements per edge
multithread.task = "Setting local mesh size (elements per edge)"; for (int i = 1; i <= nedges && !multithread.terminate; i++)
{
TopoDS_Edge e = TopoDS::Edge (geom.emap(i));
multithread.percent = 100 * (i-1)/double(nedges);
if (BRep_Tool::Degenerated(e)) continue;
// setting elements per edge GProp_GProps system;
BRepGProp::LinearProperties(e, system);
double len = system.Mass();
for (int i = 1; i <= nedges && !multithread.terminate; i++) if (len < IGNORECURVELENGTH)
{ {
TopoDS_Edge e = TopoDS::Edge (geom.emap(i)); (*testout) << "ignored" << endl;
multithread.percent = 100 * (i-1)/double(nedges); continue;
if (BRep_Tool::Degenerated(e)) continue; }
GProp_GProps system; double localh = len/mparam.segmentsperedge;
BRepGProp::LinearProperties(e, system); double s0, s1;
double len = system.Mass();
if (len < IGNORECURVELENGTH) // Philippose - 23/01/2009
{ // Find all the parent faces of a given edge
(*testout) << "ignored" << endl; // and limit the mesh size of the edge based on the
continue; // mesh size limit of the face
} TopTools_IndexedDataMapOfShapeListOfShape edge_face_map;
edge_face_map.Clear();
TopExp::MapShapesAndAncestors(geom.shape, TopAbs_EDGE, TopAbs_FACE, edge_face_map);
const TopTools_ListOfShape& parent_faces = edge_face_map.FindFromKey(e);
double localh = len/mparam.segmentsperedge; TopTools_ListIteratorOfListOfShape parent_face_list;
double s0, s1;
Handle(Geom_Curve) c = BRep_Tool::Curve(e, s0, s1);
maxedgelen = max (maxedgelen, len); for(parent_face_list.Initialize(parent_faces); parent_face_list.More(); parent_face_list.Next())
minedgelen = min (minedgelen, len); {
TopoDS_Face parent_face = TopoDS::Face(parent_face_list.Value());
int maxj = 2 * (int) ceil (localh/len); int face_index = geom.fmap.FindIndex(parent_face);
for (int j = 0; j <= maxj; j++)
{
gp_Pnt pnt = c->Value (s0+double(j)/maxj*(s1-s0));
mesh->RestrictLocalH (Point3d(pnt.X(), pnt.Y(), pnt.Z()), localh);
}
}
if(face_index >= 1) localh = min(localh,geom.face_maxh[face_index - 1]);
}
Handle(Geom_Curve) c = BRep_Tool::Curve(e, s0, s1);
maxedgelen = max (maxedgelen, len);
minedgelen = min (minedgelen, len);
multithread.task = "Setting local mesh size (edge curvature)"; // Philippose - 23/01/2009
// Modified the calculation of maxj, because the
// method used so far always results in maxj = 2,
// which causes the localh to be set only at the
// starting, mid and end of the edge.
// Old Algorithm:
// int maxj = 2 * (int) ceil (localh/len);
int maxj = max((int) ceil(len/localh), 2);
for (int j = 0; j <= maxj; j++)
{
gp_Pnt pnt = c->Value (s0+double(j)/maxj*(s1-s0));
mesh->RestrictLocalH (Point3d(pnt.X(), pnt.Y(), pnt.Z()), localh);
}
}
// setting edge curvature multithread.task = "Setting local mesh size (edge curvature)";
int nsections = 20; // setting edge curvature
for (int i = 1; i <= nedges && !multithread.terminate; i++) int nsections = 20;
{
double maxcur = 0;
multithread.percent = 100 * (i-1)/double(nedges);
TopoDS_Edge edge = TopoDS::Edge (geom.emap(i));
if (BRep_Tool::Degenerated(edge)) continue;
double s0, s1;
Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1);
BRepAdaptor_Curve brepc(edge);
BRepLProp_CLProps prop(brepc, 2, 1e-5);
for (int j = 1; j <= nsections; j++) for (int i = 1; i <= nedges && !multithread.terminate; i++)
{ {
double s = s0 + j/(double) nsections * (s1-s0); double maxcur = 0;
prop.SetParameter (s); multithread.percent = 100 * (i-1)/double(nedges);
double curvature = prop.Curvature(); TopoDS_Edge edge = TopoDS::Edge (geom.emap(i));
if(curvature > maxcur) maxcur = curvature; if (BRep_Tool::Degenerated(edge)) continue;
double s0, s1;
if (curvature >= 1e99) Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1);
continue; BRepAdaptor_Curve brepc(edge);
BRepLProp_CLProps prop(brepc, 2, 1e-5);
gp_Pnt pnt = c->Value (s); for (int j = 1; j <= nsections; j++)
{
mesh->RestrictLocalH (Point3d(pnt.X(), pnt.Y(), pnt.Z()), double s = s0 + j/(double) nsections * (s1-s0);
ComputeH (fabs(curvature))); prop.SetParameter (s);
} double curvature = prop.Curvature();
// (*testout) << "edge " << i << " max. curvature: " << maxcur << endl; if(curvature> maxcur) maxcur = curvature;
}
if (curvature >= 1e99)
continue;
multithread.task = "Setting local mesh size (face curvature)"; gp_Pnt pnt = c->Value (s);
// setting face curvature mesh->RestrictLocalH (Point3d(pnt.X(), pnt.Y(), pnt.Z()),
ComputeH (fabs(curvature)));
int nfaces = geom.fmap.Extent(); }
// (*testout) << "edge " << i << " max. curvature: " << maxcur << endl;
for (int i = 1; i <= nfaces && !multithread.terminate; i++) }
{
multithread.percent = 100 * (i-1)/double(nfaces); multithread.task = "Setting local mesh size (face curvature)";
TopoDS_Face face = TopoDS::Face(geom.fmap(i));
TopLoc_Location loc; // setting face curvature
Handle(Geom_Surface) surf = BRep_Tool::Surface (face);
Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc); int nfaces = geom.fmap.Extent();
if (triangulation.IsNull()) continue;
for (int i = 1; i <= nfaces && !multithread.terminate; i++)
BRepAdaptor_Surface sf(face, Standard_True); {
BRepLProp_SLProps prop(sf, 2, 1e-5); multithread.percent = 100 * (i-1)/double(nfaces);
TopoDS_Face face = TopoDS::Face(geom.fmap(i));
int ntriangles = triangulation -> NbTriangles(); TopLoc_Location loc;
for (int j = 1; j <= ntriangles; j++) Handle(Geom_Surface) surf = BRep_Tool::Surface (face);
{ Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc);
gp_Pnt p[3]; if (triangulation.IsNull()) continue;
gp_Pnt2d par[3];
BRepAdaptor_Surface sf(face, Standard_True);
for (int k = 1; k <=3; k++) BRepLProp_SLProps prop(sf, 2, 1e-5);
{
int n = triangulation->Triangles()(j)(k); int ntriangles = triangulation -> NbTriangles();
p[k-1] = triangulation->Nodes()(n).Transformed(loc); for (int j = 1; j <= ntriangles; j++)
par[k-1] = triangulation->UVNodes()(n); {
} gp_Pnt p[3];
gp_Pnt2d par[3];
//double maxside = 0;
//maxside = max (maxside, p[0].Distance(p[1])); for (int k = 1; k <=3; k++)
//maxside = max (maxside, p[0].Distance(p[2])); {
//maxside = max (maxside, p[1].Distance(p[2])); int n = triangulation->Triangles()(j)(k);
//cout << "\rFace " << i << " pos11 ntriangles " << ntriangles << " maxside " << maxside << flush; p[k-1] = triangulation->Nodes()(n).Transformed(loc);
par[k-1] = triangulation->UVNodes()(n);
RestrictHTriangle (par[0], par[1], par[2], &prop, *mesh, 0); }
//cout << "\rFace " << i << " pos12 ntriangles " << ntriangles << flush;
} //double maxside = 0;
} //maxside = max (maxside, p[0].Distance(p[1]));
//maxside = max (maxside, p[0].Distance(p[2]));
//maxside = max (maxside, p[1].Distance(p[2]));
// setting close edges //cout << "\rFace " << i << " pos11 ntriangles " << ntriangles << " maxside " << maxside << flush;
if (stlparam.resthcloseedgeenable) RestrictHTriangle (par[0], par[1], par[2], &prop, *mesh, 0);
{ //cout << "\rFace " << i << " pos12 ntriangles " << ntriangles << flush;
multithread.task = "Setting local mesh size (close edges)"; }
}
int sections = 100;
// setting close edges
Array<Line> lines(sections*nedges);
if (stlparam.resthcloseedgeenable)
Box3dTree* searchtree = {
new Box3dTree (bb.PMin(), bb.PMax()); multithread.task = "Setting local mesh size (close edges)";
int nlines = 0; int sections = 100;
for (int i = 1; i <= nedges && !multithread.terminate; i++)
{ Array<Line> lines(sections*nedges);
TopoDS_Edge edge = TopoDS::Edge (geom.emap(i));
if (BRep_Tool::Degenerated(edge)) continue; Box3dTree* searchtree =
new Box3dTree (bb.PMin(), bb.PMax());
double s0, s1;
Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1); int nlines = 0;
BRepAdaptor_Curve brepc(edge); for (int i = 1; i <= nedges && !multithread.terminate; i++)
BRepLProp_CLProps prop(brepc, 1, 1e-5); {
prop.SetParameter (s0); TopoDS_Edge edge = TopoDS::Edge (geom.emap(i));
if (BRep_Tool::Degenerated(edge)) continue;
gp_Vec d0 = prop.D1().Normalized();
double s_start = s0; double s0, s1;
int count = 0; Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1);
for (int j = 1; j <= sections; j++) BRepAdaptor_Curve brepc(edge);
{ BRepLProp_CLProps prop(brepc, 1, 1e-5);
double s = s0 + (s1-s0)*(double)j/(double)sections; prop.SetParameter (s0);
prop.SetParameter (s);
gp_Vec d1 = prop.D1().Normalized(); gp_Vec d0 = prop.D1().Normalized();
double cosalpha = fabs(d0*d1); double s_start = s0;
if ((j == sections) || (cosalpha < cos(10.0/180.0*M_PI))) int count = 0;
{ for (int j = 1; j <= sections; j++)
count++; {
gp_Pnt p0 = c->Value (s_start); double s = s0 + (s1-s0)*(double)j/(double)sections;
gp_Pnt p1 = c->Value (s); prop.SetParameter (s);
lines[nlines].p0 = Point<3> (p0.X(), p0.Y(), p0.Z()); gp_Vec d1 = prop.D1().Normalized();
lines[nlines].p1 = Point<3> (p1.X(), p1.Y(), p1.Z()); double cosalpha = fabs(d0*d1);
if ((j == sections) || (cosalpha < cos(10.0/180.0*M_PI)))
Box3d box; {
box.SetPoint (Point3d(lines[nlines].p0)); count++;
box.AddPoint (Point3d(lines[nlines].p1)); gp_Pnt p0 = c->Value (s_start);
gp_Pnt p1 = c->Value (s);
searchtree->Insert (box.PMin(), box.PMax(), nlines+1); lines[nlines].p0 = Point<3> (p0.X(), p0.Y(), p0.Z());
nlines++; lines[nlines].p1 = Point<3> (p1.X(), p1.Y(), p1.Z());
s_start = s; Box3d box;
d0 = d1; box.SetPoint (Point3d(lines[nlines].p0));
} box.AddPoint (Point3d(lines[nlines].p1));
}
} searchtree->Insert (box.PMin(), box.PMax(), nlines+1);
nlines++;
Array<int> linenums;
s_start = s;
for (int i = 0; i < nlines; i++) d0 = d1;
{ }
multithread.percent = (100*i)/double(nlines); }
Line & line = lines[i]; }
Box3d box; Array<int> linenums;
box.SetPoint (Point3d(line.p0));
box.AddPoint (Point3d(line.p1)); for (int i = 0; i < nlines; i++)
double maxhline = max (mesh->GetH(box.PMin()), {
mesh->GetH(box.PMax())); multithread.percent = (100*i)/double(nlines);
box.Increase(maxhline); Line & line = lines[i];
double mindist = 1e99; Box3d box;
linenums.SetSize(0); box.SetPoint (Point3d(line.p0));
searchtree->GetIntersecting(box.PMin(),box.PMax(),linenums); box.AddPoint (Point3d(line.p1));
double maxhline = max (mesh->GetH(box.PMin()),
for (int j = 0; j < linenums.Size(); j++) mesh->GetH(box.PMax()));
{ box.Increase(maxhline);
int num = linenums[j]-1;
if (i == num) continue; double mindist = 1e99;
if ((line.p0-lines[num].p0).Length2() < 1e-15) continue; linenums.SetSize(0);
if ((line.p0-lines[num].p1).Length2() < 1e-15) continue; searchtree->GetIntersecting(box.PMin(),box.PMax(),linenums);
if ((line.p1-lines[num].p0).Length2() < 1e-15) continue;
if ((line.p1-lines[num].p1).Length2() < 1e-15) continue; for (int j = 0; j < linenums.Size(); j++)
mindist = min (mindist, line.Dist(lines[num])); {
} int num = linenums[j]-1;
if (i == num) continue;
mindist *= stlparam.resthcloseedgefac; if ((line.p0-lines[num].p0).Length2() < 1e-15) continue;
if ((line.p0-lines[num].p1).Length2() < 1e-15) continue;
if (mindist < 1e-3) if ((line.p1-lines[num].p0).Length2() < 1e-15) continue;
{ if ((line.p1-lines[num].p1).Length2() < 1e-15) continue;
(*testout) << "extremely small local h: " << mindist mindist = min (mindist, line.Dist(lines[num]));
<< " --> setting to 1e-3" << endl; }
(*testout) << "somewhere near " << line.p0 << " - " << line.p1 << endl;
mindist = 1e-3; mindist *= stlparam.resthcloseedgefac;
}
if (mindist < 1e-3)
mesh->RestrictLocalHLine(line.p0, line.p1, mindist); {
} (*testout) << "extremely small local h: " << mindist
} << " --> setting to 1e-3" << endl;
(*testout) << "somewhere near " << line.p0 << " - " << line.p1 << endl;
mindist = 1e-3;
multithread.task = savetask; }
} mesh->RestrictLocalHLine(line.p0, line.p1, mindist);
}
}
multithread.task = savetask;
}
} }
if (multithread.terminate || perfstepsend <= MESHCONST_ANALYSE)
if (multithread.terminate || perfstepsend <= MESHCONST_ANALYSE)
return TCL_OK; return TCL_OK;
if (perfstepsstart <= MESHCONST_MESHEDGES) if (perfstepsstart <= MESHCONST_MESHEDGES)
{ {
FindEdges (geom, *mesh); FindEdges (geom, *mesh);
/* /*
cout << "Removing redundant points" << endl; cout << "Removing redundant points" << endl;
int i, j; int i, j;
int np = mesh->GetNP(); int np = mesh->GetNP();
Array<int> equalto; Array<int> equalto;
equalto.SetSize (np); equalto.SetSize (np);
equalto = 0; equalto = 0;
for (i = 1; i <= np; i++) for (i = 1; i <= np; i++)
{ {
for (j = i+1; j <= np; j++) for (j = i+1; j <= np; j++)
{ {
if (!equalto[j-1] && (Dist2 (mesh->Point(i), mesh->Point(j)) < 1e-12)) if (!equalto[j-1] && (Dist2 (mesh->Point(i), mesh->Point(j)) < 1e-12))
equalto[j-1] = i; equalto[j-1] = i;
} }
} }
for (i = 1; i <= np; i++) for (i = 1; i <= np; i++)
if (equalto[i-1]) if (equalto[i-1])
{ {
cout << "Point " << i << " is equal to Point " << equalto[i-1] << endl; cout << "Point " << i << " is equal to Point " << equalto[i-1] << endl;
for (j = 1; j <= mesh->GetNSeg(); j++) for (j = 1; j <= mesh->GetNSeg(); j++)
{ {
Segment & seg = mesh->LineSegment(j); Segment & seg = mesh->LineSegment(j);
if (seg.p1 == i) seg.p1 = equalto[i-1]; if (seg.p1 == i) seg.p1 = equalto[i-1];
if (seg.p2 == i) seg.p2 = equalto[i-1]; if (seg.p2 == i) seg.p2 = equalto[i-1];
} }
} }
cout << "Removing degenerated segments" << endl; cout << "Removing degenerated segments" << endl;
for (j = 1; j <= mesh->GetNSeg(); j++) for (j = 1; j <= mesh->GetNSeg(); j++)
{ {
Segment & seg = mesh->LineSegment(j); Segment & seg = mesh->LineSegment(j);
if (seg.p1 == seg.p2) if (seg.p1 == seg.p2)
{ {
mesh->DeleteSegment(j); mesh->DeleteSegment(j);
cout << "Deleting Segment " << j << endl; cout << "Deleting Segment " << j << endl;
} }
} }
mesh->Compress();
*/
/*
for (int i = 1; i <= geom.fmap.Extent(); i++)
{
Handle(Geom_Surface) hf1 =
BRep_Tool::Surface(TopoDS::Face(geom.fmap(i)));
for (int j = i+1; j <= geom.fmap.Extent(); j++)
{
Handle(Geom_Surface) hf2 =
BRep_Tool::Surface(TopoDS::Face(geom.fmap(j)));
if (hf1 == hf2) cout << "face " << i << " and face " << j << " lie on same surface" << endl;
}
}
*/
mesh->Compress();
*/
/*
for (int i = 1; i <= geom.fmap.Extent(); i++)
{
Handle(Geom_Surface) hf1 =
BRep_Tool::Surface(TopoDS::Face(geom.fmap(i)));
for (int j = i+1; j <= geom.fmap.Extent(); j++)
{
Handle(Geom_Surface) hf2 =
BRep_Tool::Surface(TopoDS::Face(geom.fmap(j)));
if (hf1 == hf2) cout << "face " << i << " and face " << j << " lie on same surface" << endl;
}
}
*/
#ifdef LOG_STREAM #ifdef LOG_STREAM
(*logout) << "Edges meshed" << endl (*logout) << "Edges meshed" << endl
<< "time = " << GetTime() << " sec" << endl << "time = " << GetTime() << " sec" << endl
<< "points: " << mesh->GetNP() << endl; << "points: " << mesh->GetNP() << endl;
#endif #endif
} }
if (multithread.terminate || perfstepsend <= MESHCONST_MESHEDGES) if (multithread.terminate || perfstepsend <= MESHCONST_MESHEDGES)
return TCL_OK; return TCL_OK;
if (perfstepsstart <= MESHCONST_MESHSURFACE) if (perfstepsstart <= MESHCONST_MESHSURFACE)
{ {
OCCMeshSurface (geom, *mesh, perfstepsend); OCCMeshSurface (geom, *mesh, perfstepsend);
if (multithread.terminate) return TCL_OK; if (multithread.terminate) return TCL_OK;
#ifdef LOG_STREAM #ifdef LOG_STREAM
(*logout) << "Surfaces meshed" << endl (*logout) << "Surfaces meshed" << endl
<< "time = " << GetTime() << " sec" << endl << "time = " << GetTime() << " sec" << endl
<< "points: " << mesh->GetNP() << endl; << "points: " << mesh->GetNP() << endl;
#endif #endif
#ifdef STAT_STREAM #ifdef STAT_STREAM
(*statout) << mesh->GetNSeg() << " & " (*statout) << mesh->GetNSeg() << " & "
<< mesh->GetNSE() << " & - &" << mesh->GetNSE() << " & - &"
<< GetTime() << " & " << endl; << GetTime() << " & " << endl;
#endif #endif
// MeshQuality2d (*mesh); // MeshQuality2d (*mesh);
mesh->CalcSurfacesOfNode(); mesh->CalcSurfacesOfNode();
} }
if (multithread.terminate || perfstepsend <= MESHCONST_OPTSURFACE) if (multithread.terminate || perfstepsend <= MESHCONST_OPTSURFACE)
return TCL_OK; return TCL_OK;
if (perfstepsstart <= MESHCONST_MESHVOLUME)
if (perfstepsstart <= MESHCONST_MESHVOLUME)
{ {
multithread.task = "Volume meshing"; multithread.task = "Volume meshing";
MESHING3_RESULT res = MESHING3_RESULT res =
MeshVolume (mparam, *mesh); MeshVolume (mparam, *mesh);
ofstream problemfile("occmesh.rep",ios_base::app); ofstream problemfile("occmesh.rep",ios_base::app);
problemfile << "VOLUMEMESHING" << endl << endl; problemfile << "VOLUMEMESHING" << endl << endl;
if(res != MESHING3_OK) if(res != MESHING3_OK)
problemfile << "ERROR" << endl << endl; problemfile << "ERROR" << endl << endl;
else else
problemfile << "OK" << endl problemfile << "OK" << endl
<< mesh->GetNE() << " elements" << endl << endl; << mesh->GetNE() << " elements" << endl << endl;
problemfile.close(); problemfile.close();
if (res != MESHING3_OK) return TCL_ERROR; if (res != MESHING3_OK) return TCL_ERROR;
if (multithread.terminate) return TCL_OK; if (multithread.terminate) return TCL_OK;
RemoveIllegalElements (*mesh); RemoveIllegalElements (*mesh);
if (multithread.terminate) return TCL_OK; if (multithread.terminate) return TCL_OK;
MeshQuality3d (*mesh); MeshQuality3d (*mesh);
#ifdef STAT_STREAM #ifdef STAT_STREAM
(*statout) << GetTime() << " & "; (*statout) << GetTime() << " & ";
#endif #endif
#ifdef LOG_STREAM #ifdef LOG_STREAM
(*logout) << "Volume meshed" << endl (*logout) << "Volume meshed" << endl
<< "time = " << GetTime() << " sec" << endl << "time = " << GetTime() << " sec" << endl
<< "points: " << mesh->GetNP() << endl; << "points: " << mesh->GetNP() << endl;
#endif #endif
} }
if (multithread.terminate || perfstepsend <= MESHCONST_MESHVOLUME) if (multithread.terminate || perfstepsend <= MESHCONST_MESHVOLUME)
return TCL_OK; return TCL_OK;
if (perfstepsstart <= MESHCONST_OPTVOLUME)
if (perfstepsstart <= MESHCONST_OPTVOLUME)
{ {
multithread.task = "Volume optimization"; multithread.task = "Volume optimization";
OptimizeVolume (mparam, *mesh); OptimizeVolume (mparam, *mesh);
if (multithread.terminate) return TCL_OK; if (multithread.terminate) return TCL_OK;
#ifdef STAT_STREAM #ifdef STAT_STREAM
(*statout) << GetTime() << " & " (*statout) << GetTime() << " & "
<< mesh->GetNE() << " & " << mesh->GetNE() << " & "
<< mesh->GetNP() << " " << '\\' << '\\' << " \\" << "hline" << endl; << mesh->GetNP() << " " << '\\' << '\\' << " \\" << "hline" << endl;
#endif #endif
#ifdef LOG_STREAM #ifdef LOG_STREAM
(*logout) << "Volume optimized" << endl (*logout) << "Volume optimized" << endl
<< "time = " << GetTime() << " sec" << endl << "time = " << GetTime() << " sec" << endl
<< "points: " << mesh->GetNP() << endl; << "points: " << mesh->GetNP() << endl;
#endif #endif
// cout << "Optimization complete" << endl;
// cout << "Optimization complete" << endl;
} }
(*testout) << "NP: " << mesh->GetNP() << endl; (*testout) << "NP: " << mesh->GetNP() << endl;
for (int i = 1; i <= mesh->GetNP(); i++) for (int i = 1; i <= mesh->GetNP(); i++)
(*testout) << mesh->Point(i) << endl; (*testout) << mesh->Point(i) << endl;
(*testout) << endl << "NSegments: " << mesh->GetNSeg() << endl; (*testout) << endl << "NSegments: " << mesh->GetNSeg() << endl;
for (int i = 1; i <= mesh->GetNSeg(); i++) for (int i = 1; i <= mesh->GetNSeg(); i++)
(*testout) << mesh->LineSegment(i) << endl; (*testout) << mesh->LineSegment(i) << endl;
return TCL_OK;
}
return TCL_OK;
}
} }
#endif #endif

View File

@ -841,6 +841,14 @@ namespace netgen
facemeshstatus.SetSize (fmap.Extent()); facemeshstatus.SetSize (fmap.Extent());
facemeshstatus = 0; facemeshstatus = 0;
// Philippose - 15/01/2009
face_maxh.SetSize (fmap.Extent());
face_maxh = mparam.maxh;
// Philippose - 17/01/2009
face_sel_status.SetSize (fmap.Extent());
face_sel_status = 0;
fvispar.SetSize (fmap.Extent()); fvispar.SetSize (fmap.Extent());
evispar.SetSize (emap.Extent()); evispar.SetSize (emap.Extent());
vvispar.SetSize (vmap.Extent()); vvispar.SetSize (vmap.Extent());
@ -1127,59 +1135,135 @@ namespace netgen
return occgeo; return occgeo;
} }
OCCGeometry * LoadOCC_STEP (const char * filename)
{
OCCGeometry * occgeo;
occgeo = new OCCGeometry;
STEPControl_Reader reader;
Standard_Integer stat = reader.ReadFile((char*)filename); // Philippose - 29/01/2009
Standard_Integer nb = reader.NbRootsForTransfer(); /* Special STEP File load function including the ability
reader.TransferRoots (); // Tranlate STEP -> OCC to extract individual surface colours via the extended
OpenCascade XDE and XCAF Feature set.
*/
OCCGeometry * LoadOCC_STEP (const char * filename)
{
OCCGeometry * occgeo;
occgeo = new OCCGeometry;
// Initiate a dummy XCAF Application to handle the STEP XCAF Document
static Handle_XCAFApp_Application dummy_app = XCAFApp_Application::GetApplication();
// Create an XCAF Document to contain the STEP file itself
Handle_TDocStd_Document step_doc;
// Check if a STEP File is already open under this handle, if so, close it to prevent
// Segmentation Faults when trying to create a new document
if(dummy_app->NbDocuments() > 0)
{
dummy_app->GetDocument(1,step_doc);
dummy_app->Close(step_doc);
}
dummy_app->NewDocument ("STEP-XCAF",step_doc);
STEPCAFControl_Reader reader;
Standard_Integer stat = reader.ReadFile((char*)filename);
// Enable transfer of colours
reader.SetColorMode(Standard_True);
reader.Transfer(step_doc);
// Read in the shape(s) and the colours present in the STEP File
Handle_XCAFDoc_ShapeTool step_shape_contents = XCAFDoc_DocumentTool::ShapeTool(step_doc->Main());
Handle_XCAFDoc_ColorTool step_colour_contents = XCAFDoc_DocumentTool::ColorTool(step_doc->Main());
TDF_LabelSequence step_shapes;
step_shape_contents->GetShapes(step_shapes);
/*
// List out the available colours in the STEP File as Colour Names
TDF_LabelSequence allColours;
stepColourContents->GetColors(allColours);
cout << "Number of colours in STEP = " << allColours.Length() << endl;
for(int i = 1; i <= allColours.Length(); i++)
{
Quantity_Color col;
stepColourContents->GetColor(allColours.Value(i),col);
cout << "Colour [" << i << "] = " << col.StringName(col.Name()) << endl;
}
*/
occgeo->shape = step_shape_contents->GetShape(step_shapes.Value(1));
occgeo->face_colours = step_colour_contents;
occgeo->changed = 1;
occgeo->BuildFMap();
occgeo->BuildVisualizationMesh();
PrintContents (occgeo);
return occgeo;
}
occgeo->shape = reader.OneShape(); // Philippose - 29/01/2009
occgeo->changed = 1; // The LOADOCC_STEP Function has been replaced by the one
occgeo->BuildFMap(); // above, which also includes support for the OpenCascade
// // XDE Features.
//Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; //
//sfs->Init(occgeo->shape); // OCCGeometry * LoadOCC_STEP (const char * filename)
//sfs->Perform(); // {
//Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe(occgeo->shape); // OCCGeometry * occgeo;
//sfwf->FixSmallEdges(); // occgeo = new OCCGeometry;
//sfwf->FixWireGaps(); //
// STEPControl_Reader reader;
// Standard_Integer stat = reader.ReadFile((char*)filename);
// Standard_Integer nb = reader.NbRootsForTransfer();
// reader.TransferRoots (); // Tranlate STEP -> OCC
//
//
//
// occgeo->shape = reader.OneShape();
// occgeo->changed = 1;
// occgeo->BuildFMap();
// //
// //Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
// //sfs->Init(occgeo->shape);
// //sfs->Perform();
// //Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe(occgeo->shape);
// //sfwf->FixSmallEdges();
// //sfwf->FixWireGaps();
//
//
//
// /*
// // JS
// TopoDS_Compound aRes;
// BRep_Builder aBuilder;
// aBuilder.MakeCompound (aRes);
//
// for (TopExp_Explorer exp(occgeo->shape, TopAbs_SOLID); exp.More(); exp.Next())
// {
// aBuilder.Add (aRes, exp.Current());
// cout << "solid" << endl;
// }
//
// for (TopExp_Explorer exp(aRes, TopAbs_SOLID); exp.More(); exp.Next())
// {
// cout << "compound has shapes solid" << endl;
// }
// occgeo->shape = aRes;
// occgeo->changed = 1;
// occgeo->BuildFMap();
// */
//
//
// occgeo->BuildVisualizationMesh();
// PrintContents (occgeo);
//
// return occgeo;
// }
/*
// JS
TopoDS_Compound aRes;
BRep_Builder aBuilder;
aBuilder.MakeCompound (aRes);
for (TopExp_Explorer exp(occgeo->shape, TopAbs_SOLID); exp.More(); exp.Next())
{
aBuilder.Add (aRes, exp.Current());
cout << "solid" << endl;
}
for (TopExp_Explorer exp(aRes, TopAbs_SOLID); exp.More(); exp.Next())
{
cout << "compound has shapes solid" << endl;
}
occgeo->shape = aRes;
occgeo->changed = 1;
occgeo->BuildFMap();
*/
//
occgeo->BuildVisualizationMesh();
PrintContents (occgeo);
return occgeo;
}
OCCGeometry * LoadOCC_BREP (const char * filename) OCCGeometry * LoadOCC_BREP (const char * filename)
{ {

View File

@ -11,9 +11,9 @@
#include <meshing.hpp> #include <meshing.hpp>
#include <BRep_Tool.hxx> #include "BRep_Tool.hxx"
#include <Geom_Curve.hxx> #include "Geom_Curve.hxx"
#include <Geom2d_Curve.hxx> #include "Geom2d_Curve.hxx"
#include "Geom_Surface.hxx" #include "Geom_Surface.hxx"
#include "GeomAPI_ProjectPointOnSurf.hxx" #include "GeomAPI_ProjectPointOnSurf.hxx"
#include "GeomAPI_ProjectPointOnCurve.hxx" #include "GeomAPI_ProjectPointOnCurve.hxx"
@ -37,6 +37,7 @@
#include "TopoDS.hxx" #include "TopoDS.hxx"
#include "TopoDS_Solid.hxx" #include "TopoDS_Solid.hxx"
#include "TopExp_Explorer.hxx" #include "TopExp_Explorer.hxx"
#include "TopTools_ListIteratorOfListOfShape.hxx"
#include "BRep_Tool.hxx" #include "BRep_Tool.hxx"
#include "Geom_Curve.hxx" #include "Geom_Curve.hxx"
#include "Geom2d_Curve.hxx" #include "Geom2d_Curve.hxx"
@ -62,8 +63,6 @@
#include "Poly_Triangle.hxx" #include "Poly_Triangle.hxx"
#include "GProp_GProps.hxx" #include "GProp_GProps.hxx"
#include "BRepGProp.hxx" #include "BRepGProp.hxx"
#include "IGESControl_Reader.hxx"
#include "STEPControl_Reader.hxx"
#include "TopoDS_Shape.hxx" #include "TopoDS_Shape.hxx"
#include "TopoDS_Face.hxx" #include "TopoDS_Face.hxx"
#include "IGESToBRep_Reader.hxx" #include "IGESToBRep_Reader.hxx"
@ -80,8 +79,33 @@
#include "Bnd_Box.hxx" #include "Bnd_Box.hxx"
#include "ShapeAnalysis.hxx" #include "ShapeAnalysis.hxx"
#include "ShapeBuild_ReShape.hxx" #include "ShapeBuild_ReShape.hxx"
// Philippose - 29/01/2009
// OpenCascade XDE Support
// Include support for OpenCascade XDE Features
#include "TDocStd_Document.hxx"
#include "Quantity_Color.hxx"
#include "XCAFApp_Application.hxx"
#include "XCAFDoc_ShapeTool.hxx"
#include "XCAFDoc_Color.hxx"
#include "XCAFDoc_ColorTool.hxx"
#include "XCAFDoc_ColorType.hxx"
#include "XCAFDoc_LayerTool.hxx"
#include "XCAFDoc_DimTolTool.hxx"
#include "XCAFDoc_MaterialTool.hxx"
#include "XCAFDoc_DocumentTool.hxx"
#include "TDF_Label.hxx"
#include "TDF_LabelSequence.hxx"
#include "STEPCAFControl_Reader.hxx"
#include "STEPCAFControl_Writer.hxx"
#include "IGESCAFControl_Reader.hxx"
#include "IGESCAFControl_Writer.hxx"
#include "IGESControl_Reader.hxx"
#include "STEPControl_Reader.hxx"
#include "IGESControl_Writer.hxx" #include "IGESControl_Writer.hxx"
#include "STEPControl_Writer.hxx" #include "STEPControl_Writer.hxx"
#include "StlAPI_Writer.hxx" #include "StlAPI_Writer.hxx"
#include "STEPControl_StepModelType.hxx" #include "STEPControl_StepModelType.hxx"
@ -89,175 +113,241 @@ namespace netgen
{ {
#include "../visualization/vispar.hpp" #include "../visualization/vispar.hpp"
// class VisualizationParameters; // class VisualizationParameters;
// extern VisualizationParameters vispar; // extern VisualizationParameters vispar;
#include "occmeshsurf.hpp" #include "occmeshsurf.hpp"
#define PROJECTION_TOLERANCE 1e-10 #define PROJECTION_TOLERANCE 1e-10
#define ENTITYISVISIBLE 1 #define ENTITYISVISIBLE 1
#define ENTITYISHIGHLIGHTED 2 #define ENTITYISHIGHLIGHTED 2
#define ENTITYISDRAWABLE 4 #define ENTITYISDRAWABLE 4
class EntityVisualizationCode class EntityVisualizationCode
{ {
int code; int code;
public: public:
EntityVisualizationCode() EntityVisualizationCode()
{ code = ENTITYISVISIBLE + !ENTITYISHIGHLIGHTED + ENTITYISDRAWABLE; } { code = ENTITYISVISIBLE + !ENTITYISHIGHLIGHTED + ENTITYISDRAWABLE;}
int IsVisible () int IsVisible ()
{ return code & ENTITYISVISIBLE; } { return code & ENTITYISVISIBLE;}
int IsHighlighted () int IsHighlighted ()
{ return code & ENTITYISHIGHLIGHTED; } { return code & ENTITYISHIGHLIGHTED;}
int IsDrawable () int IsDrawable ()
{ return code & ENTITYISDRAWABLE; } { return code & ENTITYISDRAWABLE;}
void Show () void Show ()
{ code |= ENTITYISVISIBLE; } { code |= ENTITYISVISIBLE;}
void Hide () void Hide ()
{ code &= ~ENTITYISVISIBLE; } { code &= ~ENTITYISVISIBLE;}
void Highlight () void Highlight ()
{ code |= ENTITYISHIGHLIGHTED; } { code |= ENTITYISHIGHLIGHTED;}
void Lowlight () void Lowlight ()
{ code &= ~ENTITYISHIGHLIGHTED; } { code &= ~ENTITYISHIGHLIGHTED;}
void SetDrawable () void SetDrawable ()
{ code |= ENTITYISDRAWABLE; } { code |= ENTITYISDRAWABLE;}
void SetNotDrawable ()
{ code &= ~ENTITYISDRAWABLE; }
};
inline double Det3 (double a00, double a01, double a02,
double a10, double a11, double a12,
double a20, double a21, double a22)
{
return a00*a11*a22 + a01*a12*a20 + a10*a21*a02 - a20*a11*a02 - a10*a01*a22 - a21*a12*a00;
}
void SetNotDrawable ()
{ code &= ~ENTITYISDRAWABLE;}
};
inline double Det3 (double a00, double a01, double a02,
double a10, double a11, double a12,
double a20, double a21, double a22)
{
return a00*a11*a22 + a01*a12*a20 + a10*a21*a02 - a20*a11*a02 - a10*a01*a22 - a21*a12*a00;
}
#define OCCGEOMETRYVISUALIZATIONNOCHANGE 0 #define OCCGEOMETRYVISUALIZATIONNOCHANGE 0
#define OCCGEOMETRYVISUALIZATIONFULLCHANGE 1 #define OCCGEOMETRYVISUALIZATIONFULLCHANGE 1
// == compute transformation matrices and redraw // == compute transformation matrices and redraw
#define OCCGEOMETRYVISUALIZATIONHALFCHANGE 2 #define OCCGEOMETRYVISUALIZATIONHALFCHANGE 2
// == redraw // == redraw
class OCCGeometry class OCCGeometry
{ {
Point<3> center; Point<3> center;
public: public:
TopoDS_Shape shape; TopoDS_Shape shape;
TopTools_IndexedMapOfShape fmap, emap, vmap, somap, shmap, wmap; TopTools_IndexedMapOfShape fmap, emap, vmap, somap, shmap, wmap;
Array<bool> fsingular, esingular, vsingular; Array<bool> fsingular, esingular, vsingular;
Box<3> boundingbox; Box<3> boundingbox;
int changed; // Philippose - 29/01/2009
Array<int> facemeshstatus; // OpenCascade XDE Support
// XCAF Handle to make the face colours available to the rest of
// the system
Handle_XCAFDoc_ColorTool face_colours;
Array<EntityVisualizationCode> fvispar, evispar, vvispar; int changed;
Array<int> facemeshstatus;
double tolerance; // Philippose - 15/01/2009
bool fixsmalledges; // Maximum mesh size for a given face
bool fixspotstripfaces; // (Used to explicitly define mesh size limits on individual faces)
bool sewfaces; Array<double> face_maxh;
bool makesolids;
bool splitpartitions;
// Philippose - 15/01/2009
// Indicates which faces have been selected by the user in geometry mode
// (Currently handles only selection of one face at a time, but an array would
// help to extend this to multiple faces)
Array<bool> face_sel_status;
OCCGeometry() Array<EntityVisualizationCode> fvispar, evispar, vvispar;
{
somap.Clear();
shmap.Clear();
fmap.Clear();
wmap.Clear();
emap.Clear();
vmap.Clear();
}
double tolerance;
bool fixsmalledges;
bool fixspotstripfaces;
bool sewfaces;
bool makesolids;
bool splitpartitions;
void BuildFMap(); OCCGeometry()
{
somap.Clear();
shmap.Clear();
fmap.Clear();
wmap.Clear();
emap.Clear();
vmap.Clear();
}
Box<3> GetBoundingBox() void BuildFMap();
{ return boundingbox; }
int NrSolids() Box<3> GetBoundingBox()
{ return somap.Extent(); } { return boundingbox;}
void SetCenter() int NrSolids()
{ center = boundingbox.Center(); } { return somap.Extent();}
Point<3> Center() // Philippose - 17/01/2009
{ return center; } // Total number of faces in the geometry
int NrFaces()
{ return fmap.Extent();}
void Project (int surfi, Point<3> & p) const; void SetCenter()
bool FastProject (int surfi, Point<3> & ap, double& u, double& v) const; { center = boundingbox.Center();}
Point<3> Center()
{ return center;}
OCCSurface GetSurface (int surfi) void Project (int surfi, Point<3> & p) const;
{ bool FastProject (int surfi, Point<3> & ap, double& u, double& v) const;
cout << "OCCGeometry::GetSurface using PLANESPACE" << endl;
return OCCSurface (TopoDS::Face(fmap(surfi)), PLANESPACE);
}
OCCSurface GetSurface (int surfi)
{
cout << "OCCGeometry::GetSurface using PLANESPACE" << endl;
return OCCSurface (TopoDS::Face(fmap(surfi)), PLANESPACE);
}
void BuildVisualizationMesh (); void BuildVisualizationMesh ();
void RecursiveTopologyTree (const TopoDS_Shape & sh, void RecursiveTopologyTree (const TopoDS_Shape & sh,
stringstream & str, stringstream & str,
TopAbs_ShapeEnum l, TopAbs_ShapeEnum l,
bool free, bool free,
const char * lname); const char * lname);
void GetTopologyTree (stringstream & str); void GetTopologyTree (stringstream & str);
void PrintNrShapes (); void PrintNrShapes ();
void CheckIrregularEntities (stringstream & str); void CheckIrregularEntities (stringstream & str);
void SewFaces(); void SewFaces();
void MakeSolid(); void MakeSolid();
void HealGeometry(); void HealGeometry();
void LowLightAll() // Philippose - 15/01/2009
{ // Sets the maximum mesh size for a given face
for (int i = 1; i <= fmap.Extent(); i++) // (Note: Local mesh size limited by the global max mesh size)
fvispar[i-1].Lowlight(); void SetFaceMaxH(int facenr, double faceh)
for (int i = 1; i <= emap.Extent(); i++) {
evispar[i-1].Lowlight(); if((facenr> 0) && (facenr <= fmap.Extent()))
for (int i = 1; i <= vmap.Extent(); i++) {
vvispar[i-1].Lowlight(); face_maxh[facenr-1] = min(mparam.maxh,faceh);
} }
}
void GetUnmeshedFaceInfo (stringstream & str); // Philippose - 15/01/2009
void GetNotDrawableFaces (stringstream & str); // Returns the local mesh size of a given face
bool ErrorInSurfaceMeshing (); double GetFaceMaxH(int facenr)
{
if((facenr> 0) && (facenr <= fmap.Extent()))
{
return face_maxh[facenr-1];
}
else
{
return 0.0;
}
}
void WriteOCC_STL(char * filename); // Philippose - 17/01/2009
}; // Returns the index of the currently selected face
int SelectedFace()
{
int i;
for(i = 1; i <= fmap.Extent(); i++)
{
if(face_sel_status[i-1])
{
return i;
}
}
void PrintContents (OCCGeometry * geom); return 0;
}
OCCGeometry * LoadOCC_IGES (const char * filename); // Philippose - 17/01/2009
OCCGeometry * LoadOCC_STEP (const char * filename); // Sets the currently selected face
OCCGeometry * LoadOCC_BREP (const char * filename); void SetSelectedFace(int facenr)
{
face_sel_status = 0;
if((facenr >= 1) && (facenr <= fmap.Extent()))
{
face_sel_status[facenr-1] = 1;
}
}
void LowLightAll()
{
for (int i = 1; i <= fmap.Extent(); i++)
fvispar[i-1].Lowlight();
for (int i = 1; i <= emap.Extent(); i++)
evispar[i-1].Lowlight();
for (int i = 1; i <= vmap.Extent(); i++)
vvispar[i-1].Lowlight();
}
void GetUnmeshedFaceInfo (stringstream & str);
void GetNotDrawableFaces (stringstream & str);
bool ErrorInSurfaceMeshing ();
void WriteOCC_STL(char * filename);
};
void PrintContents (OCCGeometry * geom);
OCCGeometry * LoadOCC_IGES (const char * filename);
OCCGeometry * LoadOCC_STEP (const char * filename);
OCCGeometry * LoadOCC_BREP (const char * filename);
} }

View File

@ -9,18 +9,25 @@
#include <csg.hpp> #include <csg.hpp>
#include <stlgeom.hpp> #include <stlgeom.hpp>
#include <visual.hpp>
// #include <parallel.hpp> // #include <parallel.hpp>
#ifdef OCCGEOMETRY
// Philippose - 30/01/2009
// Required for OpenCascade XDE Support
#include <occgeom.hpp>
#endif
#include <visual.hpp>
namespace netgen namespace netgen
{ {
#ifdef OCCGEOMETRY
// Philippose - 30/01/2009
// Required for OpenCascade XDE Support
extern OCCGeometry * occgeometry;
#endif
extern AutoPtr<Mesh> mesh; extern AutoPtr<Mesh> mesh;
@ -1025,6 +1032,23 @@ namespace netgen
} }
#endif #endif
#ifdef OCCGEOMETRY
// Philippose - 30/01/2009
// OpenCascade XDE Support
// Update the colour of each face based on the STEP File Data
// if the advanced OpenCascade XDE Support has been enabled
if((col == 1) && (occgeometry))
{
TopoDS_Face face = TopoDS::Face(occgeometry->fmap(el.GetIndex()));
Quantity_Color face_colour;
occgeometry->face_colours->GetColor(face,XCAFDoc_ColorSurf,face_colour);
matcol[0] = face_colour.Red();
matcol[1] = face_colour.Green();
matcol[2] = face_colour.Blue();
matcol[3] = 1.0;
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, matcol);
}
#endif
bool drawel = !el.IsDeleted(); bool drawel = !el.IsDeleted();

File diff suppressed because it is too large Load Diff