//解析TopoDS_Edge,生成OSG节点
osg::Node* BuildPolylineMesh(const TopoDS_Edge& edge, double deflection = 0.1)
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
osg::ref_ptr<osg::Geometry> linesGeom = new osg::Geometry();
osg::ref_ptr<osg::Vec3Array> pointsVec = new osg::Vec3Array();
TopLoc_Location location;
//BRepMesh::Mesh(edge, deflection);
BRepMesh_IncrementalMesh(edge, deflection);
Handle_Poly_Polygon3D polyline = BRep_Tool::Polygon3D(edge, location);
for (int i = 1; i < polyline->NbNodes(); i++)
{
gp_Pnt point = polyline->Nodes().Value(i);
pointsVec->push_back(osg::Vec3(point.X(), point.Y(), point.Z()));
}
// Set the color of the polyline.
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 0.0f));
linesGeom->setColorArray(colors.get());
linesGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
// Set vertex array.
linesGeom->setVertexArray(pointsVec);
linesGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, 0, pointsVec->size()));
geode->addDrawable(linesGeom.get());
return geode.release();
}
//解析Geom_Surface,生成OSG节点
osg::Node* buildSurfaceMesh(const Geom_Surface& surface)
{
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
gp_Pnt point;
Standard_Real uFirst = 0.0;
Standard_Real vFirst = 0.0;
Standard_Real uLast = 0.0;
Standard_Real vLast = 0.0;
surface.Bounds(uFirst, uLast, vFirst, vLast);
Precision::IsNegativeInfinite(uFirst) ? uFirst = -1.0 : uFirst;
Precision::IsInfinite(uLast) ? uLast = 1.0 : uLast;
Precision::IsNegativeInfinite(vFirst) ? vFirst = -1.0 : vFirst;
Precision::IsInfinite(vLast) ? vLast = 1.0 : vLast;
// Approximation in v direction.
for (Standard_Real u = uFirst; u <= uLast; u += APPROXIMATION_DELTA)
{
osg::ref_ptr<osg::Geometry> linesGeom = new osg::Geometry();
osg::ref_ptr<osg::Vec3Array> pointsVec = new osg::Vec3Array();
for (Standard_Real v = vFirst; v <= vLast; v += APPROXIMATION_DELTA)
{
point = surface.Value(u, v);
pointsVec->push_back(osg::Vec3(point.X(), point.Y(), point.Z()));
}
// Set the colors.
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 0.0f));
linesGeom->setColorArray(colors.get());
linesGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
// Set the normal in the same way of color.
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
linesGeom->setNormalArray(normals.get());
linesGeom->setNormalBinding(osg::Geometry::BIND_OVERALL);
// Set vertex array.
linesGeom->setVertexArray(pointsVec);
linesGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, pointsVec->size()));
geode->addDrawable(linesGeom.get());
}
// Approximation in u direction.
// osg::ref_ptr<osg::Geometry> linesGeom = new osg::Geometry();
//osg::ref_ptr<osg::Vec3Array> pointsVec = new osg::Vec3Array();
for (Standard_Real v = vFirst; v <= vLast; v += APPROXIMATION_DELTA)
{
osg::ref_ptr<osg::Geometry> linesGeom = new osg::Geometry();
osg::ref_ptr<osg::Vec3Array> pointsVec = new osg::Vec3Array();
for (Standard_Real u = vFirst; u <= uLast; u += APPROXIMATION_DELTA)
{
point = surface.Value(u, v);
pointsVec->push_back(osg::Vec3(point.X(), point.Y(), point.Z()));
}
// Set the colors.
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 0.0f));
linesGeom->setColorArray(colors.get());
linesGeom->setColorBinding(osg::Geometry::BIND_OVERALL);
// Set the normal in the same way of color.
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array;
normals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));
linesGeom->setNormalArray(normals.get());
linesGeom->setNormalBinding(osg::Geometry::BIND_OVERALL);
// Set vertex array.
linesGeom->setVertexArray(pointsVec);
linesGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, pointsVec->size()));
geode->addDrawable(linesGeom.get());
}
return geode.release();
}
//解析TopoDS_Shape,生成OSG节点
osg::Node* BuildShapeMesh(const TopoDS_Shape& aShape)
{
osg::ref_ptr<osg::Group> root = new osg::Group();
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
//1几何体//
osg::ref_ptr<osg::Geometry> triGeom = new osg::Geometry();
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array();
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
osg::ref_ptr<osg::UIntArray> arrayIndexs2 = new osg::UIntArray;//创建三角形顶点索引数据
osg::ref_ptr<osg::DrawElementsUInt> arrayIndexs = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
//2法线///
osg::ref_ptr<osg::Geometry> lineGeom = new osg::Geometry();
osg::ref_ptr<osg::Vec3Array> vertices2 = new osg::Vec3Array();
osg::ref_ptr<osg::Vec4Array> colors2 = new osg::Vec4Array;
//3关键点//
osg::ref_ptr<osg::Geometry> keyPointGeom = new osg::Geometry();
osg::ref_ptr<osg::Vec3Array> vertices3 = new osg::Vec3Array();
osg::ref_ptr<osg::Vec4Array> colors3 = new osg::Vec4Array;
BRepMesh_IncrementalMesh(aShape, 10);
//BRepMesh::Mesh(aShape, 3);//6.8.0后删除了
cout << std::endl;
gp_Pnt vertex1;
gp_Pnt vertex2;
gp_Pnt vertex3;
Standard_Integer nVertexIndex1 = 0;
Standard_Integer nVertexIndex2 = 0;
Standard_Integer nVertexIndex3 = 0;
TopExp_Explorer faceExplorer;
for (faceExplorer.Init(aShape, TopAbs_FACE); faceExplorer.More(); faceExplorer.Next())
{
TopLoc_Location loc;
TopoDS_Face aFace = TopoDS::Face(faceExplorer.Current());
Handle_Poly_Triangulation triFace = BRep_Tool::Triangulation(aFace, loc);
if (triFace.IsNull())
{
continue;
}
Standard_Boolean hasNormal = triFace->HasNormals();
Standard_Boolean hasuvNormal = triFace->HasUVNodes();
Standard_Integer l = triFace->Nodes().Length();
Standard_Integer nTriangles = triFace->NbTriangles();
TColgp_Array1OfPnt nodes(1, triFace->NbNodes());
Poly_Array1OfTriangle triangles(1, triFace->NbTriangles());
nodes = triFace->Nodes();
triangles = triFace->Triangles();
for (Standard_Integer i = 1; i <= nTriangles; i++)
{
vertex1.SetCoord(0.0, 0.0, 0.0);
vertex2.SetCoord(0.0, 0.0, 0.0);
vertex3.SetCoord(0.0, 0.0, 0.0);
nVertexIndex1 = 0;
nVertexIndex2 = 0;
nVertexIndex3 = 0;
Poly_Triangle aTriangle = triangles.Value(i);
aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3);
cout << "\tnVertexIndex1 = " << nVertexIndex1 << "\tnVertexIndex2 = " << nVertexIndex2 << "\tnVertexIndex3 = " << nVertexIndex3 << std::endl;
//顶点
//vertex1 = nodes.Value(nVertexIndex1).Transformed(loc.Transformation());
//vertex1 = nodes.Value(nVertexIndex2).Transformed(loc.Transformation());
//vertex1 = nodes.Value(nVertexIndex3).Transformed(loc.Transformation());
vertex1 = nodes.Value(nVertexIndex1);
//vertex1.SetCoord(vertex1.X() + 10.0, vertex1.Y() + 10.0, vertex1.Z() + 10.0);
vertex2 = nodes.Value(nVertexIndex2);
//vertex2.SetCoord(vertex2.X() + 10.0, vertex2.Y() + 10.0, vertex2.Z() + 10.0);
vertex3 = nodes.Value(nVertexIndex3);
//vertex3.SetCoord(vertex3.X() + 10.0, vertex3.Y() + 10.0, vertex3.Z() + 10.0);
cout << "******" << "\tvertex1 = " << vertex1.X() << "," << vertex1.Y() << "," << vertex1.Z()
<< "\tvertex2 = " << vertex2.X() << "," << vertex2.Y() << "," << vertex2.Z()
<< "\tvertex3 = " << vertex3.X() << "," << vertex3.Y() << "," << vertex3.Z() << std::endl;
cout << std::endl;
//gp_Dir dir(0.0,1.0,0.0);
//gp_Dir dir = triFace->Normal(i);
//1几何体//
{
vertices->push_back(osg::Vec3(vertex1.X(), vertex1.Y(), vertex1.Z()));
vertices->push_back(osg::Vec3(vertex2.X(), vertex2.Y(), vertex2.Z()));
vertices->push_back(osg::Vec3(vertex3.X(), vertex3.Y(), vertex3.Z()));
colors->push_back(osg::Vec4(1.0, 1.0, 0.0, 1.0));
//arrayIndexs->push_back(nVertexIndex1);
//arrayIndexs->push_back(nVertexIndex2);
//arrayIndexs->push_back(nVertexIndex3);
}
///2法线//
double ratio = 0.5;
{
gp_XYZ vector12(vertex2.XYZ() - vertex1.XYZ());
gp_XYZ vector13(vertex3.XYZ() - vertex1.XYZ());
gp_XYZ normal123 = vector13.Crossed(vector12);
Standard_Real rModulus = normal123.Modulus();
if (rModulus > gp::Resolution())
{
normal123.Normalize();
}
else {
normal123.SetCoord(0., 0., 0.);
}
if (aFace.Orientation() != TopAbs_REVERSED)
{
normal123.Reverse();
}
//第1个顶点
{
gp_XYZ vector12(vertex2.XYZ() - vertex1.XYZ());
gp_XYZ vector13(vertex3.XYZ() - vertex1.XYZ());
gp_XYZ normal10 = vector13.Crossed(vector12);
Standard_Real rModulus = normal10.Modulus();
if (rModulus > gp::Resolution())
{
normal10.Normalize();
}
else {
normal10.SetCoord(0., 0., 0.);
}
if (aFace.Orientation() != TopAbs_REVERSED)
{
normal10.Reverse();
}
//normals->push_back(osg::Vec3(dir.X(), dir.Y(), dir.Z()));
normals->push_back(osg::Vec3(normal123.X(), normal123.Y(), normal123.Z()));
vertices2->push_back(osg::Vec3(vertex1.X(), vertex1.Y(), vertex1.Z()));
vertices2->push_back(osg::Vec3(vertex1.X(), vertex1.Y(), vertex1.Z()) + osg::Vec3(ratio * normal10.X(), ratio * normal10.Y(), ratio * normal10.Z()));
colors2->push_back(osg::Vec4(1.0, 0.0, 0.0, 1.0));
colors2->push_back(osg::Vec4(1.0, 0.0, 0.0, 1.0));
}
//第2个顶点
{
gp_XYZ vector21(vertex1.XYZ() - vertex2.XYZ());
gp_XYZ vector23(vertex3.XYZ() - vertex2.XYZ());
gp_XYZ normal20 = vector21.Crossed(vector23);
Standard_Real rModulus = normal20.Modulus();
if (rModulus > gp::Resolution())
{
normal20.Normalize();
}
else {
normal20.SetCoord(0., 0., 0.);
}
if (aFace.Orientation() != TopAbs_REVERSED)
{
normal20.Reverse();
}
//normals->push_back(osg::Vec3(dir.X(), dir.Y(), dir.Z()));
normals->push_back(osg::Vec3(normal123.X(), normal123.Y(), normal123.Z()));
vertices2->push_back(osg::Vec3(vertex2.X(), vertex2.Y(), vertex2.Z()));
vertices2->push_back(osg::Vec3(vertex2.X(), vertex2.Y(), vertex2.Z()) + osg::Vec3(ratio * normal20.X(), ratio * normal20.Y(), ratio * normal20.Z()));
colors2->push_back(osg::Vec4(0.0, 1.0, 0.0, 1.0));
colors2->push_back(osg::Vec4(0.0, 1.0, 0.0, 1.0));
}
//第3个顶点
{
gp_XYZ vector31(vertex1.XYZ() - vertex3.XYZ());
gp_XYZ vector32(vertex2.XYZ() - vertex3.XYZ());
gp_XYZ normal30 = vector32.Crossed(vector31);
Standard_Real rModulus = normal30.Modulus();
if (rModulus > gp::Resolution())
{
normal30.Normalize();
}
else {
normal30.SetCoord(0., 0., 0.);
}
if (aFace.Orientation() != TopAbs_REVERSED)
{
normal30.Reverse();
}
//normals->push_back(osg::Vec3(dir.X(), dir.Y(), dir.Z()));
normals->push_back(osg::Vec3(normal123.X(), normal123.Y(), normal123.Z()));
vertices2->push_back(osg::Vec3(vertex3.X(), vertex3.Y(), vertex3.Z()));
vertices2->push_back(osg::Vec3(vertex3.X(), vertex3.Y(), vertex3.Z()) + osg::Vec3(ratio * normal30.X(), ratio * normal30.Y(), ratio * normal30.Z()));
colors2->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0));
colors2->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0));
}
}
3关键点//
{
vertices3->push_back(osg::Vec3(vertex1.X(), vertex1.Y(), vertex1.Z()));
vertices3->push_back(osg::Vec3(vertex2.X(), vertex2.Y(), vertex2.Z()));
vertices3->push_back(osg::Vec3(vertex3.X(), vertex3.Y(), vertex3.Z()));
colors3->push_back(osg::Vec4(1.0, 1.0, 1.0, 1.0));
}
}
}
//1三角面片(几何体)//
if (vertices->size() > 0)
{
//triGeom->setUseDisplayList(false);
triGeom->setVertexArray(vertices.get());
triGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertices->size()));
//triGeom->addPrimitiveSet(arrayIndexs);
std::cout << vertices->size() << "\t" << arrayIndexs->size() << std::endl;
#if 1
triGeom->setNormalArray(normals);
triGeom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
#else
//自动生成法线,效果不好
//NodePrimitiveSetNormalVisitor mv;
//triGeom->accept(mv);
#endif
triGeom->setColorArray(colors, osg::Array::BIND_OVERALL);
//triGeom->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
//triGeom->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
//triGeom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
geode->addDrawable(triGeom);
}
//2法线//
if (vertices2->size())
{
lineGeom->setVertexArray(vertices2.get());
lineGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, vertices2->size()));
lineGeom->setColorArray(colors2, osg::Array::BIND_PER_VERTEX);
lineGeom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);
geode->addDrawable(lineGeom);
}
//3点//
if (vertices3->size() > 0)
{
keyPointGeom->setVertexArray(vertices3.get());
keyPointGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, vertices3->size()));
keyPointGeom->setColorArray(colors3, osg::Array::BIND_OVERALL);
osg::ref_ptr<osg::Point> pointSize = new osg::Point;
pointSize->setSize(7.5);
keyPointGeom->getOrCreateStateSet()->setAttribute(pointSize);
keyPointGeom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED);
geode->addDrawable(keyPointGeom);
//osg::ref_ptr<osgFX::Outline> outline = new osgFX::Outline;
//outline->setWidth(8);
//outline->setColor(osg::Vec4(1, 0, 0, 1));
//outline->addChild(triGeom.get());
//root->addChild(outline.get());
//osg::PolygonMode* pm = new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, /*osg::PolygonMode::FILL | */osg::PolygonMode::LINE);
//triGeom->getOrCreateStateSet()->setAttributeAndModes(pm, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
//triGeom->getOrCreateStateSet()->setAttributeAndModes(new osg::CullFace(osg::CullFace::BACK), osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
}
Use SmoothingVisitor to find the vertex average normals.
//osgUtil::SmoothingVisitor sv;
//sv.apply(*geode);
root->addChild(geode);
return root.release();
}