gp_Vec normalToFaceAtUV(const TopoDS_Face& face, double u, double v) { BRepLProp_SLProps localSurfaceProps(1, 1e-6); localSurfaceProps.SetSurface(BRepAdaptor_Surface(face)); localSurfaceProps.SetParameters(u, v); if (localSurfaceProps.IsNormalDefined()) { const gp_Dir& nc = localSurfaceProps.Normal(); if (face.Orientation() == TopAbs_REVERSED) return gp_Vec(-nc.X(), -nc.Y(), -nc.Z()); else return gp_Vec(nc.X(), nc.Y(), nc.Z()); } return gp_Vec(0., 0., 1.); //return normalToSurfaceAtUV(BRep_Tool::Surface(face), u, v); }
int convert_to_ifc(const TopoDS_Face& f, IfcSchema::IfcFace*& face, bool advanced) { Handle_Geom_Surface surf = BRep_Tool::Surface(f); TopExp_Explorer exp(f, TopAbs_WIRE); IfcSchema::IfcFaceBound::list::ptr bounds(new IfcSchema::IfcFaceBound::list); int index = 0; for (; exp.More(); exp.Next(), ++index) { IfcSchema::IfcLoop* loop; if (!convert_to_ifc(TopoDS::Wire(exp.Current()), loop, advanced)) { return 0; } IfcSchema::IfcFaceBound* bnd; if (index == 0) { bnd = new IfcSchema::IfcFaceOuterBound(loop, true); } else { bnd = new IfcSchema::IfcFaceBound(loop, true); } bounds->push(bnd); } const bool is_planar = surf->DynamicType() == STANDARD_TYPE(Geom_Plane); if (!is_planar && !advanced) { return 0; } if (is_planar && !advanced) { face = new IfcSchema::IfcFace(bounds); return 1; } else { #ifdef USE_IFC4 IfcSchema::IfcSurface* surface; if (!convert_to_ifc(surf, surface, advanced)) { return 0; } face = new IfcSchema::IfcAdvancedFace(bounds, surface, f.Orientation() == TopAbs_FORWARD); return 1; #else // No IfcAdvancedFace in Ifc2x3 return 0; #endif } }
bool SMESH_Algo::IsReversedSubMesh (const TopoDS_Face& theFace, SMESHDS_Mesh* theMeshDS) { if ( theFace.IsNull() || !theMeshDS ) return false; // find out orientation of a meshed face int faceID = theMeshDS->ShapeToIndex( theFace ); TopoDS_Shape aMeshedFace = theMeshDS->IndexToShape( faceID ); bool isReversed = ( theFace.Orientation() != aMeshedFace.Orientation() ); const SMESHDS_SubMesh * aSubMeshDSFace = theMeshDS->MeshElements( faceID ); if ( !aSubMeshDSFace ) return isReversed; // find element with node located on face and get its normal const SMDS_FacePosition* facePos = 0; int vertexID = 0; gp_Pnt nPnt[3]; gp_Vec Ne; bool normalOK = false; SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); while ( iteratorElem->more() ) // loop on elements on theFace { const SMDS_MeshElement* elem = iteratorElem->next(); if ( elem && elem->NbNodes() > 2 ) { SMDS_ElemIteratorPtr nodesIt = elem->nodesIterator(); const SMDS_FacePosition* fPos = 0; int i = 0, vID = 0; while ( nodesIt->more() ) { // loop on nodes const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode *>(nodesIt->next()); if ( i == 3 ) i = 2; nPnt[ i++ ].SetCoord( node->X(), node->Y(), node->Z() ); // check position const SMDS_PositionPtr& pos = node->GetPosition(); if ( !pos ) continue; if ( pos->GetTypeOfPosition() == SMDS_TOP_FACE ) { fPos = dynamic_cast< const SMDS_FacePosition* >( pos.get() ); } else if ( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) { vID = pos->GetShapeId(); } } if ( fPos || ( !normalOK && vID )) { // compute normal gp_Vec v01( nPnt[0], nPnt[1] ), v02( nPnt[0], nPnt[2] ); if ( v01.SquareMagnitude() > RealSmall() && v02.SquareMagnitude() > RealSmall() ) { Ne = v01 ^ v02; normalOK = ( Ne.SquareMagnitude() > RealSmall() ); } // we need position on theFace or at least on vertex if ( normalOK ) { vertexID = vID; if ((facePos = fPos)) break; } } } } if ( !normalOK ) return isReversed; // node position on face double u,v; if ( facePos ) { u = facePos->GetUParameter(); v = facePos->GetVParameter(); } else if ( vertexID ) { TopoDS_Shape V = theMeshDS->IndexToShape( vertexID ); if ( V.IsNull() || V.ShapeType() != TopAbs_VERTEX ) return isReversed; gp_Pnt2d uv = BRep_Tool::Parameters( TopoDS::Vertex( V ), theFace ); u = uv.X(); v = uv.Y(); } else { return isReversed; } // face normal at node position TopLoc_Location loc; Handle(Geom_Surface) surf = BRep_Tool::Surface( theFace, loc ); if ( surf.IsNull() || surf->Continuity() < GeomAbs_C1 ) return isReversed; gp_Vec d1u, d1v; surf->D1( u, v, nPnt[0], d1u, d1v ); gp_Vec Nf = (d1u ^ d1v).Transformed( loc ); if ( theFace.Orientation() == TopAbs_REVERSED ) Nf.Reverse(); return Ne * Nf < 0.; }
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++) { gp_Pnt p = (T -> Nodes())(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc); 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++) { gp_Pnt p = (T -> Nodes())(aEdgePoly->Nodes()(j)).Transformed(aEdgeLoc); 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++) { Poly_Triangle triangle = (triangulation -> Triangles())(j); gp_Pnt p[3]; for (int k = 1; k <= 3; k++) p[k-1] = (triangulation -> Nodes())(triangle(k)).Transformed(loc); for (int k = 1; k <= 3; k++) { uv = (triangulation -> UVNodes())(triangle(k)); 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 ShapeGeometryBuilder::faceConstruct(const TopoDS_Face &faceIn) { TopLoc_Location location; Handle(Poly_Triangulation) triangulation; triangulation = BRep_Tool::Triangulation(faceIn, location); if (triangulation.IsNull()) throw std::runtime_error("null triangulation in face construction"); bool signalOrientation(false); if (faceIn.Orientation() == TopAbs_FORWARD) signalOrientation = true; gp_Trsf transformation; bool identity = true; if(!location.IsIdentity()) { identity = false; transformation = location.Transformation(); } //vertices. const TColgp_Array1OfPnt& nodes = triangulation->Nodes(); osg::Vec3Array *vertices = dynamic_cast<osg::Vec3Array *>(faceGeometry->getVertexArray()); osg::Vec3Array *normals = dynamic_cast<osg::Vec3Array *>(faceGeometry->getNormalArray()); osg::Vec4Array *colors = dynamic_cast<osg::Vec4Array *>(faceGeometry->getColorArray()); std::size_t offset = vertices->size(); for (int index(nodes.Lower()); index < nodes.Upper() + 1; ++index) { gp_Pnt point = nodes.Value(index); if(!identity) point.Transform(transformation); vertices->push_back(osg::Vec3(point.X(), point.Y(), point.Z())); normals->push_back(osg::Vec3(0.0, 0.0, 0.0)); colors->push_back(faceGeometry->getColor()); } const Poly_Array1OfTriangle& triangles = triangulation->Triangles(); osg::ref_ptr<osg::DrawElementsUInt> indices = new osg::DrawElementsUInt (GL_TRIANGLES, triangulation->NbTriangles() * 3); for (int index(triangles.Lower()); index < triangles.Upper() + 1; ++index) { int N1, N2, N3; triangles(index).Get(N1, N2, N3); int factor = (index - 1) * 3; if (!signalOrientation) { (*indices)[factor] = N3 - 1 + offset; (*indices)[factor + 1] = N2 - 1 + offset; (*indices)[factor + 2] = N1 - 1 + offset; } else { (*indices)[factor] = N1 - 1 + offset; (*indices)[factor + 1] = N2 - 1 + offset; (*indices)[factor + 2] = N3 - 1 + offset; } //store primitiveset index and vertex indes into map. PSetVertexRecord record; record.primitiveSetIndex = faceGeometry->getNumPrimitiveSets(); record.vertexIndex = (*indices)[factor]; pSetTriangleWrapper->pSetVertexContainer.insert(record); record.vertexIndex = (*indices)[factor + 1]; pSetTriangleWrapper->pSetVertexContainer.insert(record); record.vertexIndex = (*indices)[factor + 2]; pSetTriangleWrapper->pSetVertexContainer.insert(record); //now that we are combining faces into one geometry, osgUtil SmoothingVisitor //wants to 'average' out normals across faces. so we go back to manual calculation //of surface normals. osg::Vec3 pointOne(vertices->at((*indices)[factor])); osg::Vec3 pointTwo(vertices->at((*indices)[factor + 1])); osg::Vec3 pointThree(vertices->at((*indices)[factor + 2])); osg::Vec3 axisOne(pointTwo - pointOne); osg::Vec3 axisTwo(pointThree - pointOne); osg::Vec3 currentNormal(axisOne ^ axisTwo); if (currentNormal.isNaN()) continue; currentNormal.normalize(); osg::Vec3 tempNormal; tempNormal = (*normals)[(*indices)[factor]]; tempNormal += currentNormal; tempNormal.normalize(); (*normals)[(*indices)[factor]] = tempNormal; tempNormal = (*normals)[(*indices)[factor + 1]]; tempNormal += currentNormal; tempNormal.normalize(); (*normals)[(*indices)[factor + 1]] = tempNormal; tempNormal = (*normals)[(*indices)[factor + 2]]; tempNormal += currentNormal; tempNormal.normalize(); (*normals)[(*indices)[factor + 2]] = tempNormal; } faceGeometry->addPrimitiveSet(indices.get()); boost::uuids::uuid id = seerShape->findShapeIdRecord(faceIn).id; std::size_t lastPrimitiveIndex = faceGeometry->getNumPrimitiveSets() - 1; if (!idPSetWrapperFace->hasId(id)) { IdPSetRecord record; record.id = id; record.primitiveSetIndex = lastPrimitiveIndex; idPSetWrapperFace->idPSetContainer.insert(record); } else //ensure that the faces have the same primitive index between lod calls. assert(lastPrimitiveIndex == idPSetWrapperFace->findPSetFromId(id)); }
//======================================================================= // function: BuildSplitFaces // purpose: //======================================================================= void GEOMAlgo_Builder::BuildSplitFaces() { const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS(); NMTTools_PaveFiller* pPF=myPaveFiller; NMTDS_InterfPool* pIP=pPF->IP(); BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences(); const Handle(IntTools_Context)& aCtx= pPF->Context(); // Standard_Boolean bToReverse, bIsClosed, bIsDegenerated; Standard_Integer i, aNb, aNbF, nF; TopTools_MapOfShape aMFence; TColStd_IndexedMapOfInteger aMFP; TopExp_Explorer anExp; TopoDS_Face aFF; TopoDS_Edge aSp, aEE; TopTools_ListIteratorOfListOfShape aIt; TopAbs_Orientation anOriF, anOriE; // mySplitFaces.Clear(); // // 1. Select Faces to process (MFP) aNb=aDS.NumberOfShapesOfTheObject(); for (i=1; i<=aNb; ++i) { const TopoDS_Shape& aF=aDS.Shape(i); if (aF.ShapeType()!=TopAbs_FACE) { continue; } if (!aMFence.Add(aF)) { continue; } // if (myInParts.Contains(aF)) { aMFP.Add(i); continue; } // anExp.Init(aF, TopAbs_EDGE); for (; anExp.More(); anExp.Next()) { const TopoDS_Shape& aE=anExp.Current(); if (myImages.HasImage(aE)) { aMFP.Add(i); break; } } // //=== { Standard_Integer aNbFFs, aNbSE, j, n1, n2; // aNbFFs=aFFs.Extent(); for (j=1; j<=aNbFFs; ++j) { BOPTools_SSInterference& aFFj=aFFs(j); aFFj.Indices(n1, n2); if (!(n1==i || n2==i)) { continue; } // const TColStd_ListOfInteger& aLSE=aFFj.SharedEdges(); aNbSE=aLSE.Extent(); if (aNbSE) { aMFP.Add(i); break; } } } //=== // }// for (i=1; i<=aNb; ++i) // // 2. ProcessFaces aNbF=aMFP.Extent(); for (i=1; i<=aNbF; ++i) { nF=aMFP(i); const TopoDS_Face& aF=TopoDS::Face(aDS.Shape(nF)); anOriF=aF.Orientation(); aFF=aF; aFF.Orientation(TopAbs_FORWARD); // aMFence.Clear(); // // 2.1. Fill WES GEOMAlgo_WireEdgeSet aWES; aWES.SetFace(aFF); // // 2.1.1. Add Split parts anExp.Init(aFF, TopAbs_EDGE); for (; anExp.More(); anExp.Next()) { const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current()); anOriE=aE.Orientation(); // if (!myImages.HasImage(aE)) { if (anOriE==TopAbs_INTERNAL) { aEE=aE; aEE.Orientation(TopAbs_FORWARD); aWES.AddStartElement(aEE); aEE.Orientation(TopAbs_REVERSED); aWES.AddStartElement(aEE); } else { aWES.AddStartElement(aE); } continue; } // bIsDegenerated=BRep_Tool::Degenerated(aE); //modified by NIZNHY-PKV Wed Mar 07 07:46:09 2012f bIsClosed=IsClosed(aE, aF); //bIsClosed=BRep_Tool::IsClosed(aE, aF); //modified by NIZNHY-PKV Wed Mar 07 07:46:13 2012t // const TopTools_ListOfShape& aLIE=myImages.Image(aE); aIt.Initialize(aLIE); for (; aIt.More(); aIt.Next()) { aSp=TopoDS::Edge(aIt.Value()); // if (bIsDegenerated) { aSp.Orientation(anOriE); aWES.AddStartElement(aSp); continue; } // if (anOriE==TopAbs_INTERNAL) { aSp.Orientation(TopAbs_FORWARD); aWES.AddStartElement(aSp); aSp.Orientation(TopAbs_REVERSED); aWES.AddStartElement(aSp); continue; } // if (bIsClosed){ if (aMFence.Add(aSp)) { // if (!BRep_Tool::IsClosed(aSp, aF)){ BOPTools_Tools3D::DoSplitSEAMOnFace(aSp, aF); } // aSp.Orientation(TopAbs_FORWARD); aWES.AddStartElement(aSp); aSp.Orientation(TopAbs_REVERSED); aWES.AddStartElement(aSp); } continue; }// if (aMFence.Add(aSp)) // aSp.Orientation(anOriE); bToReverse=BOPTools_Tools3D::IsSplitToReverse1(aSp, aE, aCtx); if (bToReverse) { aSp.Reverse(); } aWES.AddStartElement(aSp); }// for (; aIt.More(); aIt.Next()) { }// for (; anExp.More(); anExp.Next()) { // // 2.1.2. Add In2D Parts if (myInParts.Contains(aF)) { const TopTools_ListOfShape& aLE=myInParts.FindFromKey(aF); aIt.Initialize(aLE); for (; aIt.More(); aIt.Next()) { aSp=TopoDS::Edge(aIt.Value()); // aSp.Orientation(TopAbs_FORWARD); aWES.AddStartElement(aSp); // aSp.Orientation(TopAbs_REVERSED); aWES.AddStartElement(aSp); } } // // 2.2. Build images Faces TopTools_ListOfShape aLFR; GEOMAlgo_ShapeSet aS1, aS2; // const TopTools_ListOfShape& aSE=aWES.StartElements(); aS1.Add(aSE); aS2.Add(aFF, TopAbs_EDGE); if (aS1.IsEqual(aS2)) { aLFR.Append(aF); } else { GEOMAlgo_BuilderFace aBF; // aBF.SetFace(aFF); aBF.SetContext(aCtx); aBF.SetShapes(aSE); // <-DEB aBF.Perform(); // const TopTools_ListOfShape& aLF=aBF.Areas(); aIt.Initialize(aLF); for (; aIt.More(); aIt.Next()) { TopoDS_Shape& aFR=aIt.Value(); if (anOriF==TopAbs_REVERSED) { aFR.Orientation(TopAbs_REVERSED); } aLFR.Append(aFR); } } // // 2.3. Collect draft images Faces mySplitFaces.Bind(aF, aLFR); }//for (i=1; i<=aNbF; ++i) }
void PovTools::transferToArray(const TopoDS_Face& aFace,gp_Vec** vertices,gp_Vec** vertexnormals, long** cons,int &nbNodesInFace,int &nbTriInFace ) { TopLoc_Location aLoc; // doing the meshing and checking the result //BRepMesh_IncrementalMesh MESH(aFace,fDeflection); Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc); if (aPoly.IsNull()) { Base::Console().Log("Empty face trianglutaion\n"); nbNodesInFace =0; nbTriInFace = 0; vertices = 0l; cons = 0l; return; } // getting the transformation of the shape/face gp_Trsf myTransf; Standard_Boolean identity = true; if (!aLoc.IsIdentity()) { identity = false; myTransf = aLoc.Transformation(); } Standard_Integer i; // getting size and create the array nbNodesInFace = aPoly->NbNodes(); nbTriInFace = aPoly->NbTriangles(); *vertices = new gp_Vec[nbNodesInFace]; *vertexnormals = new gp_Vec[nbNodesInFace]; for (i=0; i < nbNodesInFace; i++) { (*vertexnormals)[i]= gp_Vec(0.0,0.0,0.0); } *cons = new long[3*(nbTriInFace)+1]; // check orientation TopAbs_Orientation orient = aFace.Orientation(); // cycling through the poly mesh const Poly_Array1OfTriangle& Triangles = aPoly->Triangles(); const TColgp_Array1OfPnt& Nodes = aPoly->Nodes(); for (i=1; i<=nbTriInFace; i++) { // Get the triangle Standard_Integer N1,N2,N3; Triangles(i).Get(N1,N2,N3); // change orientation of the triangles if ( orient != TopAbs_FORWARD ) { Standard_Integer tmp = N1; N1 = N2; N2 = tmp; } gp_Pnt V1 = Nodes(N1); gp_Pnt V2 = Nodes(N2); gp_Pnt V3 = Nodes(N3); // transform the vertices to the place of the face if (!identity) { V1.Transform(myTransf); V2.Transform(myTransf); V3.Transform(myTransf); } // Calculate triangle normal gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z()); gp_Vec Normal = (v2-v1)^(v3-v1); //Standard_Real Area = 0.5 * Normal.Magnitude(); // add the triangle normal to the vertex normal for all points of this triangle (*vertexnormals)[N1-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z()); (*vertexnormals)[N2-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z()); (*vertexnormals)[N3-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z()); (*vertices)[N1-1].SetX((float)(V1.X())); (*vertices)[N1-1].SetY((float)(V1.Y())); (*vertices)[N1-1].SetZ((float)(V1.Z())); (*vertices)[N2-1].SetX((float)(V2.X())); (*vertices)[N2-1].SetY((float)(V2.Y())); (*vertices)[N2-1].SetZ((float)(V2.Z())); (*vertices)[N3-1].SetX((float)(V3.X())); (*vertices)[N3-1].SetY((float)(V3.Y())); (*vertices)[N3-1].SetZ((float)(V3.Z())); int j = i - 1; N1--; N2--; N3--; (*cons)[3*j] = N1; (*cons)[3*j+1] = N2; (*cons)[3*j+2] = N3; } // normalize all vertex normals for (i=0; i < nbNodesInFace; i++) { gp_Dir clNormal; try { Handle(Geom_Surface) Surface = BRep_Tool::Surface(aFace); gp_Pnt vertex((*vertices)[i].XYZ()); // gp_Pnt vertex((*vertices)[i][0], (*vertices)[i][1], (*vertices)[i][2]); GeomAPI_ProjectPointOnSurf ProPntSrf(vertex, Surface); Standard_Real fU, fV; ProPntSrf.Parameters(1, fU, fV); GeomLProp_SLProps clPropOfFace(Surface, fU, fV, 2, gp::Resolution()); clNormal = clPropOfFace.Normal(); gp_Vec temp = clNormal; //Base::Console().Log("unterschied:%.2f",temp.dot((*vertexnormals)[i])); if ( temp * (*vertexnormals)[i] < 0 ) temp = -temp; (*vertexnormals)[i] = temp; } catch (...) { } (*vertexnormals)[i].Normalize(); } }
void BuildMesh(osg::Geode *geode, const TopoDS_Face &face, const osg::Vec4 &color, double deflection) { osg::ref_ptr<deprecated_osg::Geometry> triGeom = new deprecated_osg::Geometry(); osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array(); osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array(); TopLoc_Location location; BRepMesh::Mesh(face, deflection); const Handle_Poly_Triangulation &triFace = BRep_Tool::Triangulation(face, location); Standard_Integer nTriangles = triFace->NbTriangles(); gp_Pnt vertex1; gp_Pnt vertex2; gp_Pnt vertex3; Standard_Integer nVertexIndex1 = 0; Standard_Integer nVertexIndex2 = 0; Standard_Integer nVertexIndex3 = 0; const TColgp_Array1OfPnt &nodes = triFace->Nodes(); const Poly_Array1OfTriangle &triangles = triFace->Triangles(); for (Standard_Integer i = 1; i <= nTriangles; i++) { const Poly_Triangle &aTriangle = triangles.Value(i); aTriangle.Get(nVertexIndex1, nVertexIndex2, nVertexIndex3); vertex1 = nodes.Value(nVertexIndex1).Transformed(location.Transformation()); vertex2 = nodes.Value(nVertexIndex2).Transformed(location.Transformation()); vertex3 = nodes.Value(nVertexIndex3).Transformed(location.Transformation()); gp_XYZ vector12(vertex2.XYZ() - vertex1.XYZ()); gp_XYZ vector13(vertex3.XYZ() - vertex1.XYZ()); gp_XYZ normal = vector12.Crossed(vector13); Standard_Real rModulus = normal.Modulus(); if (rModulus > gp::Resolution()) { normal.Normalize(); } else { normal.SetCoord(0., 0., 0.); } if (face.Orientation() != TopAbs_FORWARD) { normal.Reverse(); } 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())); normals->push_back(osg::Vec3(normal.X(), normal.Y(), normal.Z())); } triGeom->setVertexArray(vertices); triGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, vertices->size())); triGeom->setNormalArray(normals); triGeom->setNormalBinding(deprecated_osg::Geometry::BIND_PER_PRIMITIVE); osg::ref_ptr<osg::Vec4Array> colArr = new osg::Vec4Array(); colArr->push_back(color); triGeom->setColorArray(colArr, osg::Array::BIND_OVERALL); geode->addDrawable(triGeom); }
void BuildShapeMesh(osg::Geode *geode, const TopoDS_Shape &shape, const osg::Vec4 &color, double deflection) { bool bSetNormal = true; osg::ref_ptr<deprecated_osg::Geometry> triGeom = new deprecated_osg::Geometry(); osg::ref_ptr<osg::Vec3Array> theVertices = new osg::Vec3Array(); osg::ref_ptr<osg::Vec3Array> theNormals = new osg::Vec3Array(); BRepMesh::Mesh(shape, deflection); TopExp_Explorer faceExplorer; for (faceExplorer.Init(shape, TopAbs_FACE); faceExplorer.More(); faceExplorer.Next()) { TopLoc_Location theLocation; TopoDS_Face theFace = TopoDS::Face(faceExplorer.Current()); if (theFace.IsNull()) continue; const Handle_Poly_Triangulation &theTriangulation = BRep_Tool::Triangulation(theFace, theLocation); BRepLProp_SLProps theProp(BRepAdaptor_Surface(theFace), 1, Precision::Confusion()); Standard_Integer nTriangles = theTriangulation->NbTriangles(); for (Standard_Integer i = 1; i <= nTriangles; i++) { const Poly_Triangle& theTriangle = theTriangulation->Triangles().Value(i); gp_Pnt theVertex1 = theTriangulation->Nodes().Value(theTriangle(1)); gp_Pnt theVertex2 = theTriangulation->Nodes().Value(theTriangle(2)); gp_Pnt theVertex3 = theTriangulation->Nodes().Value(theTriangle(3)); const gp_Pnt2d &theUV1 = theTriangulation->UVNodes().Value(theTriangle(1)); const gp_Pnt2d &theUV2 = theTriangulation->UVNodes().Value(theTriangle(2)); const gp_Pnt2d &theUV3 = theTriangulation->UVNodes().Value(theTriangle(3)); theVertex1.Transform(theLocation.Transformation()); theVertex2.Transform(theLocation.Transformation()); theVertex3.Transform(theLocation.Transformation()); // find the normal for the triangle mesh. gp_Vec V12(theVertex1, theVertex2); gp_Vec V13(theVertex1, theVertex3); gp_Vec theNormal = V12 ^ V13; gp_Vec theNormal1 = theNormal; gp_Vec theNormal2 = theNormal; gp_Vec theNormal3 = theNormal; if (theNormal.Magnitude() > Precision::Confusion()) { theNormal.Normalize(); theNormal1.Normalize(); theNormal2.Normalize(); theNormal3.Normalize(); } theProp.SetParameters(theUV1.X(), theUV1.Y()); if (theProp.IsNormalDefined()) { theNormal1 = theProp.Normal(); } theProp.SetParameters(theUV2.X(), theUV2.Y()); if (theProp.IsNormalDefined()) { theNormal2 = theProp.Normal(); } theProp.SetParameters(theUV3.X(), theUV3.Y()); if (theProp.IsNormalDefined()) { theNormal3 = theProp.Normal(); } if (theFace.Orientation() == TopAbs_REVERSED) { theNormal.Reverse(); theNormal1.Reverse(); theNormal2.Reverse(); theNormal3.Reverse(); } theVertices->push_back(osg::Vec3(theVertex1.X(), theVertex1.Y(), theVertex1.Z())); theVertices->push_back(osg::Vec3(theVertex2.X(), theVertex2.Y(), theVertex2.Z())); theVertices->push_back(osg::Vec3(theVertex3.X(), theVertex3.Y(), theVertex3.Z())); if (bSetNormal) { theNormals->push_back(osg::Vec3(theNormal1.X(), theNormal1.Y(), theNormal1.Z())); theNormals->push_back(osg::Vec3(theNormal2.X(), theNormal2.Y(), theNormal2.Z())); theNormals->push_back(osg::Vec3(theNormal3.X(), theNormal3.Y(), theNormal3.Z())); } else { theNormals->push_back(osg::Vec3(theNormal.X(), theNormal.Y(), theNormal.Z())); theNormals->push_back(osg::Vec3(theNormal.X(), theNormal.Y(), theNormal.Z())); theNormals->push_back(osg::Vec3(theNormal.X(), theNormal.Y(), theNormal.Z())); } } } triGeom->setVertexArray(theVertices.get()); triGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, theVertices->size())); triGeom->setNormalArray(theNormals); triGeom->setNormalBinding(deprecated_osg::Geometry::BIND_PER_VERTEX); osg::ref_ptr<osg::Vec4Array> colArr = new osg::Vec4Array(); colArr->push_back(color); triGeom->setColorArray(colArr, osg::Array::BIND_OVERALL); geode->addDrawable(triGeom); }
bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { netgen::multithread.terminate = 0; //netgen::multithread.task = "Surface meshing"; SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); SMESH_MesherHelper helper(aMesh); helper.SetElementsOnShape( true ); NETGENPlugin_NetgenLibWrapper ngLib; ngLib._isComputeOk = false; netgen::Mesh ngMeshNoLocSize; #if NETGEN_VERSION < 6 netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh, & ngMeshNoLocSize }; #else netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh.get(), & ngMeshNoLocSize }; #endif netgen::OCCGeometry occgeoComm; // min / max sizes are set as follows: // if ( _hypParameters ) // min and max are defined by the user // else if ( _hypLengthFromEdges ) // min = aMesher.GetDefaultMinSize() // max = average segment len of a FACE // else if ( _hypMaxElementArea ) // min = aMesher.GetDefaultMinSize() // max = f( _hypMaxElementArea ) // else // min = aMesher.GetDefaultMinSize() // max = max segment len of a FACE NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false); aMesher.SetParameters( _hypParameters ); // _hypParameters -> netgen::mparam const bool toOptimize = _hypParameters ? _hypParameters->GetOptimize() : true; if ( _hypMaxElementArea ) { netgen::mparam.maxh = sqrt( 2. * _hypMaxElementArea->GetMaxArea() / sqrt(3.0) ); } if ( _hypQuadranglePreference ) netgen::mparam.quad = true; // local size is common for all FACEs in aShape? const bool isCommonLocalSize = ( !_hypLengthFromEdges && !_hypMaxElementArea && netgen::mparam.uselocalh ); const bool isDefaultHyp = ( !_hypLengthFromEdges && !_hypMaxElementArea && !_hypParameters ); if ( isCommonLocalSize ) // compute common local size in ngMeshes[0] { //list< SMESH_subMesh* > meshedSM[4]; --> all sub-shapes are added to occgeoComm aMesher.PrepareOCCgeometry( occgeoComm, aShape, aMesh );//, meshedSM ); // local size set at MESHCONST_ANALYSE step depends on // minh, face_maxh, grading and curvaturesafety; find minh if not set by the user if ( !_hypParameters || netgen::mparam.minh < DBL_MIN ) { if ( !_hypParameters ) netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam() / 3.; netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh ); } // set local size depending on curvature and NOT closeness of EDGEs netgen::occparam.resthcloseedgeenable = false; //netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading; occgeoComm.face_maxh = netgen::mparam.maxh; netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] ); occgeoComm.emap.Clear(); occgeoComm.vmap.Clear(); // set local size according to size of existing segments const double factor = netgen::occparam.resthcloseedgefac; TopTools_IndexedMapOfShape edgeMap; TopExp::MapShapes( aMesh.GetShapeToMesh(), TopAbs_EDGE, edgeMap ); for ( int iE = 1; iE <= edgeMap.Extent(); ++iE ) { const TopoDS_Shape& edge = edgeMap( iE ); if ( SMESH_Algo::isDegenerated( TopoDS::Edge( edge ))/* || helper.IsSubShape( edge, aShape )*/) continue; SMESHDS_SubMesh* smDS = meshDS->MeshElements( edge ); if ( !smDS ) continue; SMDS_ElemIteratorPtr segIt = smDS->GetElements(); while ( segIt->more() ) { const SMDS_MeshElement* seg = segIt->next(); SMESH_TNodeXYZ n1 = seg->GetNode(0); SMESH_TNodeXYZ n2 = seg->GetNode(1); gp_XYZ p = 0.5 * ( n1 + n2 ); netgen::Point3d pi(p.X(), p.Y(), p.Z()); ngMeshes[0]->RestrictLocalH( pi, factor * ( n1 - n2 ).Modulus() ); } } } netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization // ================== // Loop on all FACEs // ================== vector< const SMDS_MeshNode* > nodeVec; TopExp_Explorer fExp( aShape, TopAbs_FACE ); for ( int iF = 0; fExp.More(); fExp.Next(), ++iF ) { TopoDS_Face F = TopoDS::Face( fExp.Current() /*.Oriented( TopAbs_FORWARD )*/); int faceID = meshDS->ShapeToIndex( F ); SMESH_ComputeErrorPtr& faceErr = aMesh.GetSubMesh( F )->GetComputeError(); _quadraticMesh = helper.IsQuadraticSubMesh( F ); const bool ignoreMediumNodes = _quadraticMesh; // build viscous layers if required if ( F.Orientation() != TopAbs_FORWARD && F.Orientation() != TopAbs_REVERSED ) F.Orientation( TopAbs_FORWARD ); // avoid pb with TopAbs_INTERNAL SMESH_ProxyMesh::Ptr proxyMesh = StdMeshers_ViscousLayers2D::Compute( aMesh, F ); if ( !proxyMesh ) continue; // ------------------------ // get all EDGEs of a FACE // ------------------------ TSideVector wires = StdMeshers_FaceSide::GetFaceWires( F, aMesh, ignoreMediumNodes, faceErr, proxyMesh ); if ( faceErr && !faceErr->IsOK() ) continue; int nbWires = wires.size(); if ( nbWires == 0 ) { faceErr.reset ( new SMESH_ComputeError ( COMPERR_ALGO_FAILED, "Problem in StdMeshers_FaceSide::GetFaceWires()" )); continue; } if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments { faceErr.reset ( new SMESH_ComputeError ( COMPERR_BAD_INPUT_MESH, SMESH_Comment("Too few segments: ")<<wires[0]->NbSegments()) ); continue; } // ---------------------- // compute maxh of a FACE // ---------------------- if ( !_hypParameters ) { double edgeLength = 0; if (_hypLengthFromEdges ) { // compute edgeLength as an average segment length int nbSegments = 0; for ( int iW = 0; iW < nbWires; ++iW ) { edgeLength += wires[ iW ]->Length(); nbSegments += wires[ iW ]->NbSegments(); } if ( nbSegments ) edgeLength /= nbSegments; netgen::mparam.maxh = edgeLength; } else if ( isDefaultHyp ) { // set edgeLength by a longest segment double maxSeg2 = 0; for ( int iW = 0; iW < nbWires; ++iW ) { const UVPtStructVec& points = wires[ iW ]->GetUVPtStruct(); if ( points.empty() ) return error( COMPERR_BAD_INPUT_MESH ); gp_Pnt pPrev = SMESH_TNodeXYZ( points[0].node ); for ( size_t i = 1; i < points.size(); ++i ) { gp_Pnt p = SMESH_TNodeXYZ( points[i].node ); maxSeg2 = Max( maxSeg2, p.SquareDistance( pPrev )); pPrev = p; } } edgeLength = sqrt( maxSeg2 ) * 1.05; netgen::mparam.maxh = edgeLength; } if ( netgen::mparam.maxh < DBL_MIN ) netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam(); if ( !isCommonLocalSize ) { netgen::mparam.minh = aMesher.GetDefaultMinSize( F, netgen::mparam.maxh ); } } // prepare occgeom netgen::OCCGeometry occgeom; occgeom.shape = F; occgeom.fmap.Add( F ); occgeom.CalcBoundingBox(); occgeom.facemeshstatus.SetSize(1); occgeom.facemeshstatus = 0; occgeom.face_maxh_modified.SetSize(1); occgeom.face_maxh_modified = 0; occgeom.face_maxh.SetSize(1); occgeom.face_maxh = netgen::mparam.maxh; // ------------------------- // Fill netgen mesh // ------------------------- // MESHCONST_ANALYSE step may lead to a failure, so we make an attempt // w/o MESHCONST_ANALYSE at the second loop int err = 0; enum { LOC_SIZE, NO_LOC_SIZE }; int iLoop = isCommonLocalSize ? 0 : 1; for ( ; iLoop < 2; iLoop++ ) { //bool isMESHCONST_ANALYSE = false; InitComputeError(); netgen::Mesh * ngMesh = ngMeshes[ iLoop ]; ngMesh->DeleteMesh(); if ( iLoop == NO_LOC_SIZE ) { ngMesh->SetGlobalH ( mparam.maxh ); ngMesh->SetMinimalH( mparam.minh ); Box<3> bb = occgeom.GetBoundingBox(); bb.Increase (bb.Diam()/10); ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading); } nodeVec.clear(); faceErr = aMesher.AddSegmentsToMesh( *ngMesh, occgeom, wires, helper, nodeVec, /*overrideMinH=*/!_hypParameters); if ( faceErr && !faceErr->IsOK() ) break; //if ( !isCommonLocalSize ) //limitSize( ngMesh, mparam.maxh * 0.8); // ------------------------- // Generate surface mesh // ------------------------- const int startWith = MESHCONST_MESHSURFACE; const int endWith = toOptimize ? MESHCONST_OPTSURFACE : MESHCONST_MESHSURFACE; SMESH_Comment str; try { OCC_CATCH_SIGNALS; #if NETGEN_VERSION >=6 std::shared_ptr<netgen::Mesh> mesh_ptr(ngMesh, [](netgen::Mesh*) {}); err = netgen::OCCGenerateMesh(occgeom, mesh_ptr, netgen::mparam, startWith, endWith); #elif NETGEN_VERSION > 4 err = netgen::OCCGenerateMesh(occgeom, ngMesh, netgen::mparam, startWith, endWith); #else char *optstr = 0; err = netgen::OCCGenerateMesh(occgeom, ngMesh, startWith, endWith, optstr); #endif if ( netgen::multithread.terminate ) return false; if ( err ) str << "Error in netgen::OCCGenerateMesh() at " << netgen::multithread.task; } catch (Standard_Failure& ex) { err = 1; str << "Exception in netgen::OCCGenerateMesh()" << " at " << netgen::multithread.task << ": " << ex.DynamicType()->Name(); if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) str << ": " << ex.GetMessageString(); } catch (...) { err = 1; str << "Exception in netgen::OCCGenerateMesh()" << " at " << netgen::multithread.task; } if ( err ) { if ( aMesher.FixFaceMesh( occgeom, *ngMesh, 1 )) break; if ( iLoop == LOC_SIZE ) { netgen::mparam.minh = netgen::mparam.maxh; netgen::mparam.maxh = 0; for ( int iW = 0; iW < wires.size(); ++iW ) { StdMeshers_FaceSidePtr wire = wires[ iW ]; const vector<UVPtStruct>& uvPtVec = wire->GetUVPtStruct(); for ( size_t iP = 1; iP < uvPtVec.size(); ++iP ) { SMESH_TNodeXYZ p( uvPtVec[ iP ].node ); netgen::Point3d np( p.X(),p.Y(),p.Z()); double segLen = p.Distance( uvPtVec[ iP-1 ].node ); double size = ngMesh->GetH( np ); netgen::mparam.minh = Min( netgen::mparam.minh, size ); netgen::mparam.maxh = Max( netgen::mparam.maxh, segLen ); } } //cerr << "min " << netgen::mparam.minh << " max " << netgen::mparam.maxh << endl; netgen::mparam.minh *= 0.9; netgen::mparam.maxh *= 1.1; continue; } else { faceErr.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED, str )); } } // ---------------------------------------------------- // Fill the SMESHDS with the generated nodes and faces // ---------------------------------------------------- int nbNodes = ngMesh->GetNP(); int nbFaces = ngMesh->GetNSE(); int nbInputNodes = nodeVec.size()-1; nodeVec.resize( nbNodes+1, 0 ); // add nodes for ( int ngID = nbInputNodes + 1; ngID <= nbNodes; ++ngID ) { const MeshPoint& ngPoint = ngMesh->Point( ngID ); SMDS_MeshNode * node = meshDS->AddNode(ngPoint(0), ngPoint(1), ngPoint(2)); nodeVec[ ngID ] = node; } // create faces int i,j; vector<const SMDS_MeshNode*> nodes; for ( i = 1; i <= nbFaces ; ++i ) { const Element2d& elem = ngMesh->SurfaceElement(i); nodes.resize( elem.GetNP() ); for (j=1; j <= elem.GetNP(); ++j) { int pind = elem.PNum(j); if ( pind < 1 ) break; nodes[ j-1 ] = nodeVec[ pind ]; if ( nodes[ j-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_3DSPACE ) { const PointGeomInfo& pgi = elem.GeomInfoPi(j); meshDS->SetNodeOnFace( nodes[ j-1 ], faceID, pgi.u, pgi.v); } } if ( j > elem.GetNP() ) { SMDS_MeshFace* face = 0; if ( elem.GetType() == TRIG ) face = helper.AddFace(nodes[0],nodes[1],nodes[2]); else face = helper.AddFace(nodes[0],nodes[1],nodes[2],nodes[3]); } } break; } // two attempts } // loop on FACEs return true; }
//======================================================================= //function :IsSplitToReverse //purpose : //======================================================================= Standard_Boolean GEOMAlgo_Tools3D::IsSplitToReverse(const TopoDS_Face& theFSp, const TopoDS_Face& theFSr, IntTools_Context& theContext) { Standard_Boolean bRet, bFound, bInFace; Standard_Real aT1, aT2, aT, aU, aV, aScPr; gp_Pnt aPFSp, aPFSr; gp_Dir aDNFSp; gp_Vec aD1U, aD1V; Handle(Geom_Surface) aSr, aSp; TopAbs_Orientation aOrSr, aOrSp; TopExp_Explorer anExp; TopoDS_Edge aESp; // bRet=Standard_False; // aSr=BRep_Tool::Surface(theFSr); aSp=BRep_Tool::Surface(theFSp); if (aSr==aSp) { aOrSr=theFSr.Orientation(); aOrSp=theFSp.Orientation(); bRet=(aOrSr!=aOrSp); return bRet; } // bFound=Standard_False; anExp.Init(theFSp, TopAbs_EDGE); for (; anExp.More(); anExp.Next()) { aESp=TopoDS::Edge(anExp.Current()); if (!BRep_Tool::Degenerated(aESp)) { if (!BRep_Tool::IsClosed(aESp, theFSp)) { bFound=!bFound; break; } } } if (!bFound) { return bRet; } // BRep_Tool::Range(aESp, aT1, aT2); aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2); BOPTools_Tools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, aPFSp, aDNFSp); // // Parts of theContext.ComputeVS(..) GeomAPI_ProjectPointOnSurf& aProjector=theContext.ProjPS(theFSr); aProjector.Perform(aPFSp); if (!aProjector.IsDone()) { return bRet; } // aProjector.LowerDistanceParameters(aU, aV); gp_Pnt2d aP2D(aU, aV); bInFace=theContext.IsPointInFace (theFSr, aP2D); if (!bInFace) { return bRet; } // aSr->D1(aU, aV, aPFSr, aD1U, aD1V); gp_Dir aDD1U(aD1U); gp_Dir aDD1V(aD1V); gp_Dir aDNFSr=aDD1U^aDD1V; if (theFSr.Orientation()==TopAbs_REVERSED){ aDNFSr.Reverse(); } // aScPr=aDNFSp*aDNFSr; bRet=(aScPr<0.); // return bRet; }
//======================================================================= //function : GetApproxNormalToFaceOnEdge //purpose : //======================================================================= void GetApproxNormalToFaceOnEdge (const TopoDS_Edge& aEx, const TopoDS_Face& aFx, Standard_Real aT, gp_Pnt& aPF, gp_Dir& aDNF, IntTools_Context& aCtx) { Standard_Boolean bReverse; Standard_Real aT1, aT2, dT, aU, aV; gp_Dir aDTT, aDNFT, aDBT; gp_Pnt aPFT, aPFx; Handle(Geom_Curve) aC3D; Handle(Geom_Surface) aS; GeomAdaptor_Surface aGAS; GeomAbs_SurfaceType aTS; TopoDS_Face aF; TopoDS_Edge aE; // bReverse=Standard_False; aF=aFx; aE=aEx; if (aF.Orientation()==TopAbs_REVERSED){ bReverse=!bReverse; aE.Reverse(); // aF.Orientation(TopAbs_FORWARD); } // // Point at aT aC3D =BRep_Tool::Curve(aE, aT1, aT2); aC3D->D0(aT, aPFT); // // Normal at aT BOPTools_Tools3D::GetNormalToFaceOnEdge (aE, aF, aT, aDNFT); // Tangent at aT BOPTools_Tools3D::GetTangentToEdge(aE, aT, aDTT); // // Binormal at aT aDBT=aDNFT^aDTT; // dT=BOPTools_Tools3D::MinStepIn2d();//~1.e-5; dT=10.*dT; //---------------------------------------------- { aS=BRep_Tool::Surface(aF); aGAS.Load(aS); aTS=aGAS.GetType(); if (aTS==GeomAbs_BSplineSurface || aTS==GeomAbs_BezierSurface || aTS==GeomAbs_Plane) { Standard_Real aTolEx, aTolFx, aTol, dUR, dVR, dR; // aTolEx=BRep_Tool::Tolerance(aEx); aTolFx=BRep_Tool::Tolerance(aFx); aTol=2.*aTolEx+aTolFx; dUR=aGAS.UResolution(aTol); dVR=aGAS.VResolution(aTol); dR=(dUR>dVR)? dUR : dVR; if (dR>dT) { dT=dR; } } //modified by NIZNHY-PKV Thu Dec 02 10:39:09 2010f else if (GeomAbs_Torus || aTS==GeomAbs_Cylinder){ Standard_Real aTolEx, aTolFx, aTol; // aTolEx=BRep_Tool::Tolerance(aEx); aTolFx=BRep_Tool::Tolerance(aFx); aTol=2.*aTolEx+aTolFx; if (aTol>dT) { dT=aTol; } } //modified by NIZNHY-PKV Thu Dec 02 10:39:13 2010t } //---------------------------------------------- // aPFx.SetXYZ(aPFT.XYZ()+dT*aDBT.XYZ()); // aPF=aPFx; aDNF=aDNFT; if (bReverse) { aDNF.Reverse(); } // GeomAPI_ProjectPointOnSurf& aProjector=aCtx.ProjPS(aF); // aProjector.Perform(aPFx); if(aProjector.IsDone()) { aProjector.LowerDistanceParameters (aU, aV); aS->D0(aU, aV, aPF); BOPTools_Tools3D::GetNormalToSurface (aS, aU, aV, aDNF); if (bReverse){ aDNF.Reverse(); } } }
//======================================================================= //function : Execute //purpose : //======================================================================= Standard_Integer GEOMImpl_MeasureDriver::Execute(TFunction_Logbook& log) const { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); GEOMImpl_IMeasure aCI (aFunction); Standard_Integer aType = aFunction->GetType(); TopoDS_Shape aShape; if (aType == CDG_MEASURE) { Handle(GEOM_Function) aRefBase = aCI.GetBase(); TopoDS_Shape aShapeBase = aRefBase->GetValue(); if (aShapeBase.IsNull()) { Standard_NullObject::Raise("Shape for centre of mass calculation is null"); } gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aShapeBase); gp_Pnt aCenterMass = aPos.Location(); aShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape(); } else if (aType == VERTEX_BY_INDEX) { Handle(GEOM_Function) aRefBase = aCI.GetBase(); TopoDS_Shape aShapeBase = aRefBase->GetValue(); if (aShapeBase.IsNull()) { Standard_NullObject::Raise("Shape for centre of mass calculation is null"); } int index = aCI.GetIndex(); gp_Pnt aVertex; if (aShapeBase.ShapeType() == TopAbs_VERTEX) { if ( index != 1 ) Standard_NullObject::Raise("Vertex index is out of range"); else aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aShapeBase)); } else if (aShapeBase.ShapeType() == TopAbs_EDGE) { TopoDS_Vertex aV1, aV2; TopoDS_Edge anEdgeE = TopoDS::Edge(aShapeBase); TopExp::Vertices(anEdgeE, aV1, aV2); gp_Pnt aP1 = BRep_Tool::Pnt(aV1); gp_Pnt aP2 = BRep_Tool::Pnt(aV2); if (index < 0 || index > 1) Standard_NullObject::Raise("Vertex index is out of range"); if ( ( anEdgeE.Orientation() == TopAbs_FORWARD && index == 0 ) || ( anEdgeE.Orientation() == TopAbs_REVERSED && index == 1 ) ) aVertex = aP1; else aVertex = aP2; } else if (aShapeBase.ShapeType() == TopAbs_WIRE) { TopTools_IndexedMapOfShape anEdgeShapes; TopTools_IndexedMapOfShape aVertexShapes; TopoDS_Vertex aV1, aV2; TopoDS_Wire aWire = TopoDS::Wire(aShapeBase); TopExp_Explorer exp (aWire, TopAbs_EDGE); for (; exp.More(); exp.Next()) { anEdgeShapes.Add(exp.Current()); TopoDS_Edge E = TopoDS::Edge(exp.Current()); TopExp::Vertices(E, aV1, aV2); if ( aVertexShapes.Extent() == 0) aVertexShapes.Add(aV1); if ( !aV1.IsSame( aVertexShapes(aVertexShapes.Extent()) ) ) aVertexShapes.Add(aV1); if ( !aV2.IsSame( aVertexShapes(aVertexShapes.Extent()) ) ) aVertexShapes.Add(aV2); } if (index < 0 || index > aVertexShapes.Extent()) Standard_NullObject::Raise("Vertex index is out of range"); if (aWire.Orientation() == TopAbs_FORWARD) aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aVertexShapes(index+1))); else aVertex = BRep_Tool::Pnt(TopoDS::Vertex(aVertexShapes(aVertexShapes.Extent() - index))); } else { Standard_NullObject::Raise("Shape for vertex calculation is not an edge or wire"); } aShape = BRepBuilderAPI_MakeVertex(aVertex).Shape(); } else if (aType == VECTOR_FACE_NORMALE) { // Face Handle(GEOM_Function) aRefBase = aCI.GetBase(); TopoDS_Shape aShapeBase = aRefBase->GetValue(); if (aShapeBase.IsNull()) { Standard_NullObject::Raise("Face for normale calculation is null"); } if (aShapeBase.ShapeType() != TopAbs_FACE) { Standard_NullObject::Raise("Shape for normale calculation is not a face"); } TopoDS_Face aFace = TopoDS::Face(aShapeBase); // Point gp_Pnt p1 (0,0,0); Handle(GEOM_Function) aPntFunc = aCI.GetPoint(); if (!aPntFunc.IsNull()) { TopoDS_Shape anOptPnt = aPntFunc->GetValue(); if (anOptPnt.IsNull()) Standard_NullObject::Raise("Invalid shape given for point argument"); p1 = BRep_Tool::Pnt(TopoDS::Vertex(anOptPnt)); } else { gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(aFace); p1 = aPos.Location(); } // Point parameters on surface Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); Handle(ShapeAnalysis_Surface) aSurfAna = new ShapeAnalysis_Surface (aSurf); gp_Pnt2d pUV = aSurfAna->ValueOfUV(p1, Precision::Confusion()); // Normal direction gp_Vec Vec1,Vec2; BRepAdaptor_Surface SF (aFace); SF.D1(pUV.X(), pUV.Y(), p1, Vec1, Vec2); if (Vec1.Magnitude() < Precision::Confusion()) { gp_Vec tmpV; gp_Pnt tmpP; SF.D1(pUV.X(), pUV.Y()-0.1, tmpP, Vec1, tmpV); } else if (Vec2.Magnitude() < Precision::Confusion()) { gp_Vec tmpV; gp_Pnt tmpP; SF.D1(pUV.X()-0.1, pUV.Y(), tmpP, tmpV, Vec2); } gp_Vec V = Vec1.Crossed(Vec2); Standard_Real mod = V.Magnitude(); if (mod < Precision::Confusion()) Standard_NullObject::Raise("Normal vector of a face has null magnitude"); // Set length of normal vector to average radius of curvature Standard_Real radius = 0.0; GeomLProp_SLProps aProperties (aSurf, pUV.X(), pUV.Y(), 2, Precision::Confusion()); if (aProperties.IsCurvatureDefined()) { Standard_Real radius1 = Abs(aProperties.MinCurvature()); Standard_Real radius2 = Abs(aProperties.MaxCurvature()); if (Abs(radius1) > Precision::Confusion()) { radius = 1.0 / radius1; if (Abs(radius2) > Precision::Confusion()) { radius = (radius + 1.0 / radius2) / 2.0; } } else { if (Abs(radius2) > Precision::Confusion()) { radius = 1.0 / radius2; } } } // Set length of normal vector to average dimension of the face // (only if average radius of curvature is not appropriate) if (radius < Precision::Confusion()) { Bnd_Box B; Standard_Real Xmin, Xmax, Ymin, Ymax, Zmin, Zmax; BRepBndLib::Add(aFace, B); B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); radius = ((Xmax - Xmin) + (Ymax - Ymin) + (Zmax - Zmin)) / 3.0; } if (radius < Precision::Confusion()) radius = 1.0; V *= radius / mod; // consider the face orientation if (aFace.Orientation() == TopAbs_REVERSED || aFace.Orientation() == TopAbs_INTERNAL) { V = - V; } // Edge gp_Pnt p2 = p1.Translated(V); BRepBuilderAPI_MakeEdge aBuilder (p1, p2); if (!aBuilder.IsDone()) Standard_NullObject::Raise("Vector construction failed"); aShape = aBuilder.Shape(); } else { } if (aShape.IsNull()) return 0; aFunction->SetValue(aShape); log.SetTouched(Label()); return 1; }
//======================================================================= //function : SelectEdge //purpose : Find the edge <NE> connected <CE> by the vertex <CV> in the list <LE>. // <NE> Is erased of the list. If <CE> is too in the list <LE> // with the same orientation, it's erased of the list //======================================================================= static Standard_Boolean SelectEdge(const TopoDS_Face& F, const TopoDS_Edge& CE, const TopoDS_Vertex& CV, TopoDS_Edge& NE, TopTools_ListOfShape& LE) { TopTools_ListIteratorOfListOfShape itl; NE.Nullify(); for ( itl.Initialize(LE); itl.More(); itl.Next()) { if (itl.Value().IsEqual(CE)) { LE.Remove(itl); break; } } if (LE.Extent() > 1) { //-------------------------------------------------------------- // Several possible edges. // - Test the edges differents of CE //-------------------------------------------------------------- Standard_Real cf, cl, f, l; TopoDS_Face FForward = F; Handle(Geom2d_Curve) Cc, C; FForward.Orientation(TopAbs_FORWARD); Cc = BRep_Tool::CurveOnSurface(CE,FForward,cf,cl); Standard_Real dist,distmin = 100*BRep_Tool::Tolerance(CV); Standard_Real uc,u; if (CE.Orientation () == TopAbs_FORWARD) uc = cl; else uc = cf; gp_Pnt2d P2,PV = Cc->Value(uc); Standard_Real delta = FindDelta(LE,FForward); for ( itl.Initialize(LE); itl.More(); itl.Next()) { const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); if (!E.IsSame(CE)) { C = BRep_Tool::CurveOnSurface(E,FForward,f,l); if (E.Orientation () == TopAbs_FORWARD) u = f; else u = l; P2 = C->Value(u); dist = PV.Distance(P2); if (dist <= distmin){ distmin = dist; } } } Standard_Real anglemax = - PI; TopoDS_Edge SelectedEdge; for ( itl.Initialize(LE); itl.More(); itl.Next()) { const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); if (!E.IsSame(CE)) { C = BRep_Tool::CurveOnSurface(E,FForward,f,l); if (E.Orientation () == TopAbs_FORWARD) u = f; else u = l; P2 = C->Value(u); dist = PV.Distance(P2); if (dist <= distmin + (1./3)*delta){ gp_Pnt2d PC, P; gp_Vec2d CTg1, CTg2, Tg1, Tg2; Cc->D2(uc, PC, CTg1, CTg2); C->D2(u, P, Tg1, Tg2); Standard_Real angle; if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_FORWARD) { angle = CTg1.Angle(Tg1.Reversed()); } else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_REVERSED) { angle = (CTg1.Reversed()).Angle(Tg1); } else if (CE.Orientation () == TopAbs_REVERSED && E.Orientation () == TopAbs_REVERSED) { angle = CTg1.Angle(Tg1); } else if (CE.Orientation () == TopAbs_FORWARD && E.Orientation () == TopAbs_FORWARD) { angle = (CTg1.Reversed()).Angle(Tg1.Reversed()); } if (angle >= anglemax) { anglemax = angle ; SelectedEdge = E; } } } } for ( itl.Initialize(LE); itl.More(); itl.Next()) { const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); if (E.IsEqual(SelectedEdge)) { NE = TopoDS::Edge(E); LE.Remove(itl); break; } } } else if (LE.Extent() == 1) { NE = TopoDS::Edge(LE.First()); LE.RemoveFirst(); } else { return Standard_False; } return Standard_True; }
void DrawFace(TopoDS_Face face,void(*callbackfunc)(const double* x, const double* n), bool just_one_average_normal) { double x[9], n[9]; StdPrs_ToolShadedShape SST; // Get triangulation TopLoc_Location L; Handle_Poly_Triangulation facing = BRep_Tool::Triangulation(face,L); gp_Trsf tr = L; if(facing.IsNull()){ #if 0 BRepAdaptor_Surface surface(face, Standard_True); double u0 = surface.FirstUParameter(); double u1 = surface.LastUParameter(); double v0 = surface.FirstVParameter(); double v1 = surface.LastVParameter(); const int numi = 10; const int numj = 10; for(int i = 0; i<numi; i++) { for(int j = 0; j<numj; j++) { double uA = -1.2 + 2.5 *(double)i / numi; double uB = -1.2 + 2.5 *(double)(i+1) / numi; double vA = 10* (double)j / numj; double vB = 10*(double)(j+1) / numj; gp_Pnt p0, p1, p2, p3; gp_Dir n0 = GetFaceNormalAtUV(face, uA, vA, &p0); gp_Dir n1 = GetFaceNormalAtUV(face, uB, vA, &p1); gp_Dir n2 = GetFaceNormalAtUV(face, uB, vB, &p2); gp_Dir n3 = GetFaceNormalAtUV(face, uA, vB, &p3); x[0] = p0.X(); x[1] = p0.Y(); x[2] = p0.Z(); x[3] = p1.X(); x[4] = p1.Y(); x[5] = p1.Z(); x[6] = p2.X(); x[7] = p2.Y(); x[8] = p2.Z(); n[0] = n0.X(); n[1] = n0.Y(); n[2] = n0.Z(); n[3] = n1.X(); n[4] = n1.Y(); n[5] = n1.Z(); n[6] = n2.X(); n[7] = n2.Y(); n[8] = n2.Z(); (*callbackfunc)(x, n); x[0] = p0.X(); x[1] = p0.Y(); x[2] = p0.Z(); x[3] = p2.X(); x[4] = p2.Y(); x[5] = p2.Z(); x[6] = p3.X(); x[7] = p3.Y(); x[8] = p3.Z(); n[0] = n0.X(); n[1] = n0.Y(); n[2] = n0.Z(); n[3] = n2.X(); n[4] = n2.Y(); n[5] = n2.Z(); n[6] = n3.X(); n[7] = n3.Y(); n[8] = n3.Z(); (*callbackfunc)(x, n); } } #endif } else { Poly_Connect pc(facing); const TColgp_Array1OfPnt& Nodes = facing->Nodes(); const Poly_Array1OfTriangle& triangles = facing->Triangles(); TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper()); SST.Normal(face, pc, myNormal); Standard_Integer nnn = facing->NbTriangles(); // nnn : nombre de triangles Standard_Integer nt, n1, n2, n3 = 0; // nt : triangle courant // ni : sommet i du triangle courant for (nt = 1; nt <= nnn; nt++) { if (face.Orientation() == TopAbs_REVERSED) // si la face est "reversed" triangles(nt).Get(n1,n3,n2); // le triangle est n1,n3,n2 else triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3 if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) ) { gp_Pnt v1 = Nodes(n1).Transformed(tr); gp_Pnt v2 = Nodes(n2).Transformed(tr); gp_Pnt v3 = Nodes(n3).Transformed(tr); x[0] = v1.X(); x[1] = v1.Y(); x[2] = v1.Z(); x[3] = v2.X(); x[4] = v2.Y(); x[5] = v2.Z(); x[6] = v3.X(); x[7] = v3.Y(); x[8] = v3.Z(); if(just_one_average_normal) { gp_Vec V1(v1, v2); gp_Vec V2(v1, v3); extract((V1 ^ V2).Normalized(), n); } else { n[0] = myNormal(n1).X(); n[1] = myNormal(n1).Y(); n[2] = myNormal(n1).Z(); n[3] = myNormal(n2).X(); n[4] = myNormal(n2).Y(); n[5] = myNormal(n2).Z(); n[6] = myNormal(n3).X(); n[7] = myNormal(n3).Y(); n[8] = myNormal(n3).Z(); } (*callbackfunc)(x, n); } } } }