netgen/libsrc/occ/vsocc.cpp
2021-08-31 01:00:33 +02:00

781 lines
20 KiB
C++

#ifndef NOTCL
#ifdef OCCGEOMETRY
#include <mystdlib.h>
#include <myadt.hpp>
#include <meshing.hpp>
#include <occgeom.hpp>
#include "TopoDS_Shape.hxx"
#include "TopoDS_Vertex.hxx"
#include "TopExp_Explorer.hxx"
#include "BRep_Tool.hxx"
#include "TopoDS.hxx"
#include "gp_Pnt.hxx"
#include "Geom_Curve.hxx"
#include "Poly_Triangulation.hxx"
#include "Poly_Array1OfTriangle.hxx"
#include "TColgp_Array1OfPnt2d.hxx"
#include "Poly_Triangle.hxx"
#include "Poly_Polygon3D.hxx"
#include "Poly_PolygonOnTriangulation.hxx"
#include <visual.hpp>
#include "vsocc.hpp"
namespace netgen
{
// extern OCCGeometry * occgeometry;
/* *********************** Draw OCC Geometry **************** */
VisualSceneOCCGeometry :: VisualSceneOCCGeometry ()
: VisualScene()
{
trilists.SetSize(0);
linelists.SetSize(1);
}
VisualSceneOCCGeometry :: ~VisualSceneOCCGeometry ()
{
;
}
void VisualSceneOCCGeometry :: DrawScene ()
{
if ( occgeometry->changed )
{
BuildScene();
occgeometry -> changed = 0;
}
glClearColor(backcolor, backcolor, backcolor, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SetLight();
glPushMatrix();
glMultMatrixd (transformationmat);
glShadeModel (GL_SMOOTH);
glDisable (GL_COLOR_MATERIAL);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// glEnable (GL_LIGHTING);
double shine = vispar.shininess;
// double transp = vispar.transp;
glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, shine);
glLogicOp (GL_COPY);
glEnable (GL_NORMALIZE);
float mat_col[] = { 0.2f, 0.2f, 0.8f, 1.0f};
glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col);
glPolygonOffset (1, 1);
glEnable (GL_POLYGON_OFFSET_FILL);
// Philippose - 30/01/2009
// Added clipping planes to Geometry view
SetClippingPlane();
GLfloat matcoledge[] = { 0, 0, 1, 1};
GLfloat matcolhiedge[] = { 1, 0, 0, 1};
glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcoledge);
glLineWidth (1.0f);
if (vispar.occshowedges) glCallList (linelists.Get(1));
if (vispar.occshowsurfaces) glCallList (trilists.Get(1));
glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcolhiedge);
glLineWidth (5.0f);
if (vispar.occshowedges) glCallList (linelists.Get(2));
for (int i = 1; i <= occgeometry->vmap.Extent(); i++)
if (occgeometry->vvispar[i-1].IsHighlighted())
{
glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcolhiedge);
glLineWidth (5.0f);
glBegin (GL_LINES);
gp_Pnt p = BRep_Tool::Pnt(TopoDS::Vertex(occgeometry->vmap(i)));
double d = rad/100;
glVertex3f (p.X()-d, p.Y(), p.Z());
glVertex3f (p.X()+d, p.Y(), p.Z());
glVertex3f (p.X(), p.Y()-d, p.Z());
glVertex3f (p.X(), p.Y()+d, p.Z());
glVertex3f (p.X(), p.Y(), p.Z()-d);
glVertex3f (p.X(), p.Y(), p.Z()+d);
glEnd();
}
glDisable (GL_POLYGON_OFFSET_FILL);
glPopMatrix();
// DrawCoordinateCross ();
// DrawNetgenLogo ();
glFinish();
glDisable (GL_POLYGON_OFFSET_FILL);
}
/*
void VisualSceneOCCGeometry :: BuildScene (int zoomall)
{
int i = 0, j, k;
TopExp_Explorer ex, ex_edge;
if (vispar.occvisproblemfaces || (occgeometry -> changed != 2))
{
Box<3> bb = occgeometry -> GetBoundingBox();
center = bb.Center();
rad = bb.Diam() / 2;
if (vispar.occvisproblemfaces)
{
for (i = 1; i <= occgeometry->fmap.Extent(); i++)
if (occgeometry->facemeshstatus[i-1] == -1)
{
GProp_GProps system;
BRepGProp::LinearProperties(occgeometry->fmap(i), system);
gp_Pnt pnt = system.CentreOfMass();
center = Point<3> (pnt.X(), pnt.Y(), pnt.Z());
cout << "Setting center to mid of face " << i << " = " << center << endl;
}
}
CalcTransformationMatrices();
}
for (i = 1; i <= linelists.Size(); i++)
glDeleteLists (linelists.Elem(i), 1);
linelists.SetSize(0);
linelists.Append (glGenLists (1));
glNewList (linelists.Last(), GL_COMPILE);
i = 0;
for (ex_edge.Init(occgeometry -> shape, TopAbs_EDGE);
ex_edge.More(); ex_edge.Next())
{
if (BRep_Tool::Degenerated(TopoDS::Edge(ex_edge.Current()))) continue;
i++;
TopoDS_Edge edge = TopoDS::Edge(ex_edge.Current());
Handle(Poly_PolygonOnTriangulation) aEdgePoly;
Handle(Poly_Triangulation) T;
TopLoc_Location aEdgeLoc;
BRep_Tool::PolygonOnTriangulation(edge, aEdgePoly, T, aEdgeLoc);
if(aEdgePoly.IsNull())
{
cout << "cannot visualize edge " << i << endl;
continue;
}
glBegin (GL_LINE_STRIP);
int nbnodes = aEdgePoly -> NbNodes();
for (j = 1; j <= nbnodes; j++)
{
gp_Pnt p = (T -> Nodes())(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc);
glVertex3f (p.X(), p.Y(), p.Z());
}
glEnd ();
}
glEndList ();
for (i = 1; i <= trilists.Size(); i++)
glDeleteLists (trilists.Elem(i), 1);
trilists.SetSize(0);
trilists.Append (glGenLists (1));
glNewList (trilists.Last(), GL_COMPILE);
i = 0;
TopExp_Explorer exp0, exp1, exp2, exp3;
int shapenr = 0;
for (exp0.Init(occgeometry -> shape, TopAbs_SOLID); exp0.More(); exp0.Next())
{
shapenr++;
if (vispar.occshowvolumenr != 0 &&
vispar.occshowvolumenr != shapenr) continue;
float mat_col[4];
mat_col[3] = 1;
switch (shapenr)
{
case 1:
mat_col[0] = 0.2;
mat_col[1] = 0.2;
mat_col[2] = 0.8;
break;
case 2:
mat_col[0] = 0.8;
mat_col[1] = 0.2;
mat_col[2] = 0.8;
break;
case 3:
mat_col[0] = 0.2;
mat_col[1] = 0.8;
mat_col[2] = 0.8;
break;
case 4:
mat_col[0] = 0.8;
mat_col[1] = 0.2;
mat_col[2] = 0.2;
break;
case 5:
mat_col[0] = 0.8;
mat_col[1] = 0.8;
mat_col[2] = 0.8;
break;
case 6:
mat_col[0] = 0.6;
mat_col[1] = 0.6;
mat_col[2] = 0.6;
break;
case 7:
mat_col[0] = 0.2;
mat_col[1] = 0.8;
mat_col[2] = 0.2;
break;
case 8:
mat_col[0] = 0.8;
mat_col[1] = 0.8;
mat_col[2] = 0.2;
break;
default:
// mat_col[0] = 1-(1.0/double(shapenr));
// mat_col[1] = 0.5;
mat_col[0] = 0.5+double((shapenr*shapenr*shapenr*shapenr) % 10)/20.0;
mat_col[1] = 0.5+double(int(shapenr*shapenr*shapenr*shapenr*sin(double(shapenr))) % 10)/20.0;
mat_col[2] = 0.5+double((shapenr*shapenr*shapenr) % 10)/20.0;
}
glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col);
for (exp1.Init(exp0.Current(), TopAbs_SHELL); exp1.More(); exp1.Next())
for (exp2.Init(exp1.Current().Composed(exp0.Current().Orientation()), TopAbs_FACE); exp2.More(); exp2.Next())
{
TopoDS_Face face = TopoDS::Face (exp2.Current().Composed(exp1.Current().Orientation()));
i = occgeometry->fmap.FindIndex(face);
TopLoc_Location loc;
Handle(Geom_Surface) surf = BRep_Tool::Surface (face);
BRepAdaptor_Surface sf(face, Standard_False);
BRepLProp_SLProps prop(sf, 1, 1e-5);
Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc);
if (triangulation.IsNull())
{
cout << "cannot visualize face " << i << endl;
continue;
}
if (vispar.occvisproblemfaces)
{
switch (occgeometry->facemeshstatus[i-1])
{
case 0:
mat_col[0] = 0.2;
mat_col[1] = 0.2;
mat_col[2] = 0.8;
break;
case 1:
mat_col[0] = 0.2;
mat_col[1] = 0.8;
mat_col[2] = 0.2;
break;
case -1:
mat_col[0] = 0.8;
mat_col[1] = 0.2;
mat_col[2] = 0.2;
break;
}
glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col);
}
glBegin (GL_TRIANGLES);
int ntriangles = triangulation -> NbTriangles();
for (j = 1; j <= ntriangles; j++)
{
Poly_Triangle triangle = (triangulation -> Triangles())(j);
for (k = 1; k <= 3; k++)
{
gp_Pnt2d uv = (triangulation -> UVNodes())(triangle(k));
gp_Pnt pnt;
gp_Vec du, dv;
prop.SetParameters (uv.X(), uv.Y());
surf->D0 (uv.X(), uv.Y(), pnt);
gp_Vec n;
if (prop.IsNormalDefined())
n = prop.Normal();
else
n = gp_Vec (0,0,0);
if (face.Orientation() == TopAbs_REVERSED) n *= -1;
glNormal3f (n.X(), n.Y(), n.Z());
glVertex3f (pnt.X(), pnt.Y(), pnt.Z());
}
}
glEnd ();
}
}
glEndList ();
}
*/
void VisualSceneOCCGeometry :: BuildScene (int zoomall)
{
if (occgeometry -> changed == OCCGEOMETRYVISUALIZATIONFULLCHANGE)
{
occgeometry -> BuildVisualizationMesh (vispar.occdeflection);
center = occgeometry -> Center();
rad = occgeometry -> GetBoundingBox().Diam() / 2;
if (vispar.occzoomtohighlightedentity)
{
bool hilite = false;
bool hiliteonepoint = false;
Bnd_Box bb;
for (int i = 1; i <= occgeometry->fmap.Extent(); i++)
if (occgeometry->fvispar[i-1].IsHighlighted())
{
hilite = true;
BRepBndLib::Add (occgeometry->fmap(i), bb);
}
for (int i = 1; i <= occgeometry->emap.Extent(); i++)
if (occgeometry->evispar[i-1].IsHighlighted())
{
hilite = true;
BRepBndLib::Add (occgeometry->emap(i), bb);
}
for (int i = 1; i <= occgeometry->vmap.Extent(); i++)
if (occgeometry->vvispar[i-1].IsHighlighted())
{
hiliteonepoint = true;
BRepBndLib::Add (occgeometry->vmap(i), bb);
}
if (hilite || hiliteonepoint)
{
double x1,y1,z1,x2,y2,z2;
bb.Get (x1,y1,z1,x2,y2,z2);
Point<3> p1 = Point<3> (x1,y1,z1);
Point<3> p2 = Point<3> (x2,y2,z2);
Box<3> boundingbox(p1,p2);
center = boundingbox.Center();
if (hiliteonepoint)
rad = occgeometry -> GetBoundingBox().Diam() / 100;
else
rad = boundingbox.Diam() / 2;
}
}
CalcTransformationMatrices();
}
// Clear lists
for (int i = 1; i <= linelists.Size(); i++)
glDeleteLists (linelists.Elem(i), 1);
linelists.SetSize(0);
for (int i = 1; i <= trilists.Size(); i++)
glDeleteLists (trilists.Elem(i), 1);
trilists.SetSize(0);
// Total wireframe
linelists.Append (glGenLists (1));
glNewList (linelists.Last(), GL_COMPILE);
for (int i = 1; i <= occgeometry->emap.Extent(); i++)
{
TopoDS_Edge edge = TopoDS::Edge(occgeometry->emap(i));
if (BRep_Tool::Degenerated(edge)) continue;
if (occgeometry->evispar[i-1].IsHighlighted()) continue;
Handle(Poly_PolygonOnTriangulation) aEdgePoly;
Handle(Poly_Triangulation) T;
TopLoc_Location aEdgeLoc;
BRep_Tool::PolygonOnTriangulation(edge, aEdgePoly, T, aEdgeLoc);
if(aEdgePoly.IsNull())
{
(*testout) << "visualizing edge " << occgeometry->emap.FindIndex (edge)
<< " without using the occ visualization triangulation" << endl;
double s0, s1;
Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1);
glBegin (GL_LINE_STRIP);
for (int i = 0; i<=50; i++)
{
gp_Pnt p = c->Value (s0 + i*(s1-s0)/50.0);
glVertex3f (p.X(),p.Y(),p.Z());
}
glEnd ();
continue;
}
int nbnodes = aEdgePoly -> NbNodes();
glBegin (GL_LINE_STRIP);
for (int j = 1; j <= nbnodes; j++)
{
#if OCC_VERSION_MAJOR>=7 && OCC_VERSION_MINOR>=5
gp_Pnt p = T -> Node(aEdgePoly->Node(j)).Transformed(aEdgeLoc);
#else
gp_Pnt p = T -> Nodes()(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc);
#endif
glVertex3f (p.X(), p.Y(), p.Z());
}
glEnd ();
}
glEndList ();
// Highlighted edge list
linelists.Append (glGenLists (1));
glNewList (linelists.Last(), GL_COMPILE);
for (int i = 1; i <= occgeometry->emap.Extent(); i++)
if (occgeometry->evispar[i-1].IsHighlighted())
{
TopoDS_Edge edge = TopoDS::Edge(occgeometry->emap(i));
if (BRep_Tool::Degenerated(edge)) continue;
Handle(Poly_PolygonOnTriangulation) aEdgePoly;
Handle(Poly_Triangulation) T;
TopLoc_Location aEdgeLoc;
BRep_Tool::PolygonOnTriangulation(edge, aEdgePoly, T, aEdgeLoc);
if(aEdgePoly.IsNull())
{
(*testout) << "visualizing edge " << occgeometry->emap.FindIndex (edge)
<< " without using the occ visualization triangulation" << endl;
double s0, s1;
Handle(Geom_Curve) c = BRep_Tool::Curve(edge, s0, s1);
glBegin (GL_LINE_STRIP);
for (int i = 0; i<=50; i++)
{
gp_Pnt p = c->Value (s0 + i*(s1-s0)/50.0);
glVertex3f (p.X(),p.Y(),p.Z());
}
glEnd ();
continue;
}
int nbnodes = aEdgePoly -> NbNodes();
glBegin (GL_LINE_STRIP);
for (int j = 1; j <= nbnodes; j++)
{
#if OCC_VERSION_MAJOR>=7 && OCC_VERSION_MINOR>=5
gp_Pnt p = T -> Node(aEdgePoly->Node(j)).Transformed(aEdgeLoc);
#else
gp_Pnt p = (T -> Nodes())(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc);
#endif
glVertex3f (p.X(), p.Y(), p.Z());
}
glEnd ();
}
glEndList ();
// display faces
trilists.Append (glGenLists (1));
glNewList (trilists.Last(), GL_COMPILE);
for (int i = 1; i <= occgeometry->fmap.Extent(); i++)
{
if (!occgeometry->fvispar[i-1].IsVisible()) continue;
glLoadName (i);
float mat_col[4];
mat_col[3] = 1;
TopoDS_Face face = TopoDS::Face(occgeometry->fmap(i));
if (!occgeometry->fvispar[i-1].IsHighlighted())
{
// Philippose - 30/01/2009
// OpenCascade XDE Support
Quantity_Color face_colour;
// Philippose - 23/02/2009
// Check to see if colours have been extracted first!!
// Forum bug-fox (Jean-Yves - 23/02/2009)
if(!(occgeometry->face_colours.IsNull())
&& (occgeometry->face_colours->GetColor(face,XCAFDoc_ColorSurf,face_colour)))
{
mat_col[0] = face_colour.Red();
mat_col[1] = face_colour.Green();
mat_col[2] = face_colour.Blue();
}
else
{
mat_col[0] = 0.0;
mat_col[1] = 1.0;
mat_col[2] = 0.0;
}
}
else
{
mat_col[0] = 0.8;
mat_col[1] = 0.2;
mat_col[2] = 0.2;
}
glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_col);
TopLoc_Location loc;
Handle(Geom_Surface) surf = BRep_Tool::Surface (face);
BRepAdaptor_Surface sf(face, Standard_False);
BRepLProp_SLProps prop(sf, 1, 1e-5);
Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation (face, loc);
if (triangulation.IsNull())
{
cout << "cannot visualize face " << i << endl;
occgeometry->fvispar[i-1].SetNotDrawable();
continue;
}
gp_Pnt2d uv;
gp_Pnt pnt;
gp_Vec n;
glBegin (GL_TRIANGLES);
int ntriangles = triangulation -> NbTriangles();
for (int j = 1; j <= ntriangles; j++)
{
#if OCC_VERSION_MAJOR>=7 && OCC_VERSION_MINOR>=5
Poly_Triangle triangle = triangulation -> Triangle(j);
#else
Poly_Triangle triangle = triangulation -> Triangles()(j);
#endif
gp_Pnt p[3];
for (int k = 1; k <= 3; k++)
p[k-1] = (triangulation -> Node(triangle(k))).Transformed(loc);
for (int k = 1; k <= 3; k++)
{
#if OCC_VERSION_MAJOR>=7 && OCC_VERSION_MINOR>=5
uv = triangulation -> UVNode(triangle(k));
#else
uv = triangulation -> UVNodes()(triangle(k);
#endif
prop.SetParameters (uv.X(), uv.Y());
// surf->D0 (uv.X(), uv.Y(), pnt);
if (prop.IsNormalDefined())
n = prop.Normal();
else
{
(*testout) << "Visualization of face " << i
<< ": Normal vector not defined" << endl;
// n = gp_Vec (0,0,0);
gp_Vec a(p[0],p[1]);
gp_Vec b(p[0],p[2]);
n = b^a;
}
if (face.Orientation() == TopAbs_REVERSED) n *= -1;
glNormal3f (n.X(), n.Y(), n.Z());
glVertex3f (p[k-1].X(), p[k-1].Y(), p[k-1].Z());
}
}
glEnd ();
}
glEndList ();
}
void SelectFaceInOCCDialogTree (int facenr);
void VisualSceneOCCGeometry :: MouseDblClick (int px, int py)
{
int hits;
// select surface triangle by mouse click
GLuint selbuf[10000];
glSelectBuffer (10000, selbuf);
glRenderMode (GL_SELECT);
GLint viewport[4];
glGetIntegerv (GL_VIEWPORT, viewport);
glMatrixMode (GL_PROJECTION);
glPushMatrix();
GLdouble projmat[16];
glGetDoublev (GL_PROJECTION_MATRIX, projmat);
glLoadIdentity();
gluPickMatrix (px, viewport[3] - py, 1, 1, viewport);
glMultMatrixd (projmat);
glClearColor(backcolor, backcolor, backcolor, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode (GL_MODELVIEW);
glPushMatrix();
glMultMatrixd (transformationmat);
glInitNames();
glPushName (1);
glPolygonOffset (1, 1);
glEnable (GL_POLYGON_OFFSET_FILL);
glDisable(GL_CLIP_PLANE0);
// Philippose - 30/01/2009
// Enable clipping planes for Selection mode in OCC Geometry
if (vispar.clipping.enable)
{
Vec<3> n(clipplane[0], clipplane[1], clipplane[2]);
double len = Abs(n);
double mu = -clipplane[3] / (len*len);
Point<3> p (mu * n);
n /= len;
Vec<3> t1 = n.GetNormal ();
Vec<3> t2 = Cross (n, t1);
double xi1mid = (center - p) * t1;
double xi2mid = (center - p) * t2;
glLoadName (0);
glBegin (GL_QUADS);
glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid-rad) * t2);
glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid-rad) * t2);
glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid+rad) * t2);
glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid+rad) * t2);
glEnd ();
}
glCallList (trilists.Get(1));
glDisable (GL_POLYGON_OFFSET_FILL);
glPopName();
glMatrixMode (GL_PROJECTION);
glPopMatrix();
glMatrixMode (GL_MODELVIEW);
glPopMatrix();
glFlush();
hits = glRenderMode (GL_RENDER);
int minname = 0;
GLuint mindepth = 0;
// find clippingplane
GLuint clipdepth = 0; // GLuint(-1);
for (int i = 0; i < hits; i++)
{
int curname = selbuf[4*i+3];
if (!curname) clipdepth = selbuf[4*i+1];
}
for (int i = 0; i < hits; i++)
{
int curname = selbuf[4*i+3];
GLuint curdepth = selbuf[4*i+1];
if (curname && (curdepth> clipdepth) &&
(curdepth < mindepth || !minname))
{
mindepth = curdepth;
minname = curname;
}
}
occgeometry->LowLightAll();
if (minname)
{
occgeometry->fvispar[minname-1].Highlight();
if (vispar.occzoomtohighlightedentity)
occgeometry->changed = OCCGEOMETRYVISUALIZATIONFULLCHANGE;
else
occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE;
cout << "Selected face: " << minname << endl;
}
else
{
occgeometry->changed = OCCGEOMETRYVISUALIZATIONHALFCHANGE;
}
glDisable(GL_CLIP_PLANE0);
SelectFaceInOCCDialogTree (minname);
// Philippose - 30/01/2009
// Set the currently selected face in the array
// for local face mesh size definition
occgeometry->SetSelectedFace(minname);
// selecttimestamp = NextTimeStamp();
}
}
#endif
#endif // NOTCL