osg::Node* RhinoReader::BuildWireFrameFace(const ON_BrepFace* theFace) { osg::ref_ptr<osg::Geode> aGeode = new osg::Geode(); ON_NurbsSurface aSurface; if (theFace->GetNurbForm(aSurface) == 0) { return NULL; } double u0 = aSurface.Domain(0).Min(); double u1 = aSurface.Domain(0).Max(); double v0 = aSurface.Domain(1).Min(); double v1 = aSurface.Domain(1).Max(); double d0 = 0.0; double d1 = 0.0; d0 = (u1 - u0) / 10.0; d1 = (v1 - v0) / 10.0; for (double u = u0; (u - u1) < TOLERANCE_FACE; u += d0) { osg::ref_ptr<osg::Geometry> aGeometry = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> aVertices = new osg::Vec3Array(); for (double v = v0; (v - v1) < TOLERANCE_FACE; v += d1) { ON_3dPoint aPoint = aSurface.PointAt(u, v); aVertices->push_back(osg::Vec3(aPoint.x, aPoint.y, aPoint.z)); } aGeometry->setVertexArray(aVertices); aGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, aVertices->size())); aGeode->addDrawable(aGeometry); } for (double v = v0; (v - v1) < TOLERANCE_FACE; v += d1) { osg::ref_ptr<osg::Geometry> aGeometry = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> aVertices = new osg::Vec3Array(); for (double u = u0; (u - u1) < TOLERANCE_FACE; u += d0) { ON_3dPoint aPoint = aSurface.PointAt(u, v); aVertices->push_back(osg::Vec3(aPoint.x, aPoint.y, aPoint.z)); } aGeometry->setVertexArray(aVertices); aGeometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, aVertices->size())); aGeode->addDrawable(aGeometry); } return aGeode.release(); }
osg::Node* RhinoReader::BuildShadedFace(const ON_BrepFace* theFace) { osg::ref_ptr<osg::Geode> aGeode = new osg::Geode(); ON_NurbsSurface aSurface; if (theFace->GetNurbForm(aSurface) == 0) { return NULL; } osg::ref_ptr<osg::Geometry> aGeometry = new osg::Geometry(); osg::ref_ptr<osg::Vec3Array> aUVPoints = new osg::Vec3Array(); osg::ref_ptr<osg::Vec3Array> aPoints = new osg::Vec3Array(); osg::ref_ptr<osg::Vec3Array> aBounds = new osg::Vec3Array(); osg::ref_ptr<osgUtil::DelaunayTriangulator> dt = new osgUtil::DelaunayTriangulator(); osg::ref_ptr<osgUtil::DelaunayConstraint> dc = new osgUtil::DelaunayConstraint(); // add loop for the face. for (int i = 0; i < theFace->LoopCount(); ++i) { ON_BrepLoop* aLoop = theFace->Loop(i); if (aLoop->m_type == ON_BrepLoop::outer) { for (int j = 0; j < aLoop->TrimCount(); ++j) { ON_BrepTrim* aTrim = aLoop->Trim(j); const ON_Curve* aPCurve = aTrim->TrimCurveOf(); if (aPCurve) { ON_3dPoint aStartPoint = aPCurve->PointAtStart(); ON_3dPoint aEndPoint = aPCurve->PointAtEnd(); aUVPoints->push_back(osg::Vec3(aStartPoint.x, aStartPoint.y, 0.0)); aUVPoints->push_back(osg::Vec3(aEndPoint.x, aEndPoint.y, 0.0)); } } } else if (aLoop->m_type == ON_BrepLoop::inner) { for (int j = 0; j < aLoop->TrimCount(); ++j) { } } } dc->setVertexArray(aBounds); dc->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, 0, aBounds->size())); // triangulate the parametric space. //dt->addInputConstraint(dc); dt->setInputPointArray(aUVPoints); dt->triangulate(); //dt->removeInternalTriangles(dc); for (osg::Vec3Array::const_iterator j = aUVPoints->begin(); j != aUVPoints->end(); ++j) { // evaluate the point on the surface ON_3dPoint aPoint = aSurface.PointAt((*j).x(), (*j).y()); aPoints->push_back(osg::Vec3(aPoint.x, aPoint.y, aPoint.z)); } //aGeometry->setVertexArray(aUVPoints); aGeometry->setVertexArray(aPoints); aGeometry->addPrimitiveSet(dt->getTriangles()); aGeode->addDrawable(aGeometry); // use smoothing visitor to set the average normals //osgUtil::SmoothingVisitor sv; //sv.apply(*aGeode); return aGeode.release(); }