if (geom.vmap.FindIndex(TopExp::FirstVertex (edge)) ==
geom.vmap.FindIndex(TopExp::LastVertex (edge)))
-@@ -481,13 +499,45 @@
+@@ -479,15 +497,64 @@
+ }
+ else
{
- Point<3> fp = occ2ng (BRep_Tool::Pnt (TopExp::FirstVertex (edge)));
- Point<3> lp = occ2ng (BRep_Tool::Pnt (TopExp::LastVertex (edge)));
+- Point<3> fp = occ2ng (BRep_Tool::Pnt (TopExp::FirstVertex (edge)));
+- Point<3> lp = occ2ng (BRep_Tool::Pnt (TopExp::LastVertex (edge)));
++ TopoDS_Iterator vIt( edge, false );
++ TopoDS_Vertex v1 = TopoDS::Vertex( vIt.Value() ); vIt.Next();
++ TopoDS_Vertex v2 = TopoDS::Vertex( vIt.Value() );
++ if ( v1.Orientation() == TopAbs_REVERSED )
++ std::swap( v1, v2 );
++ const bool isClosedEdge = v1.IsSame( v2 );
++
++ Point<3> fp = occ2ng (BRep_Tool::Pnt (v1));
++ Point<3> lp = occ2ng (BRep_Tool::Pnt (v2));
+ double tol2 = std::min( eps*eps, 1e-6 * Dist2( fp, lp ));
++ if ( isClosedEdge )
++ tol2 = BRep_Tool::Tolerance( v1 ) * BRep_Tool::Tolerance( v1 );
pnums[0] = -1;
pnums.Last() = -1;
+ if (Dist2 (mesh[pi], fp) < tol2) pnums[0] = pi;
+ if (Dist2 (mesh[pi], lp) < tol2) pnums.Last() = pi;
+ }
-+ if ( pnums[0] == pnums.Last() )
-+ pnums[0] = -1;
++ if (( isClosedEdge && pnums[0] != pnums.Last() ) ||
++ ( !isClosedEdge && pnums[0] == pnums.Last() ))
++ pnums[0] = pnums.Last() = -1;
+ if ( pnums[0] == -1 || pnums.Last() == -1 )
+ {
+ // take into account a possible large gap between a vertex and an edge curve
-+ // and a large vertex tolerance covering the whole edge
++ // end and a large vertex tolerance covering the whole edge
+ if ( pnums[0] == -1 )
+ {
-+ double tol = BRep_Tool::Tolerance( TopExp::FirstVertex (edge));
++ double tol = BRep_Tool::Tolerance( v1 );
+ for (PointIndex pi = 1; pi < first_ep; pi++)
+ if (pi != pnums.Last() && Dist2 (mesh[pi], fp) < 2*tol*tol)
+ pnums[0] = pi;
+
+ if ( pnums[0] == -1 )
-+ pnums[0] = geom.vmap.FindIndex (TopExp::FirstVertex (edge));
++ pnums[0] = first_ep-1- nvertices + geom.vmap.FindIndex ( v1 );
+ }
-+ if ( pnums.Last() == -1 )
++ if ( isClosedEdge )
+ {
-+ double tol = BRep_Tool::Tolerance( TopExp::LastVertex (edge));
-+ for (PointIndex pi = 1; pi < first_ep; pi++)
-+ if (pi != pnums[0] && Dist2 (mesh[pi], lp) < 2*tol*tol)
-+ pnums.Last() = pi;
-+
-+ if ( pnums.Last() == -1 )
-+ pnums.Last() = geom.vmap.FindIndex (TopExp::LastVertex (edge));
++ pnums.Last() = pnums[0];
+ }
++ else
++ {
++ if ( pnums.Last() == -1 )
++ {
++ double tol = BRep_Tool::Tolerance( v2 );
++ for (PointIndex pi = 1; pi < first_ep; pi++)
++ if (pi != pnums[0] && Dist2 (mesh[pi], lp) < 2*tol*tol)
++ pnums.Last() = pi;
+
-+ if ( Dist2( fp, mesh[PointIndex(pnums[0])]) >
-+ Dist2( lp, mesh[PointIndex(pnums.Last())]))
++ if ( pnums.Last() == -1 )
++ pnums.Last() = first_ep-1-nvertices + geom.vmap.FindIndex ( v2 );
++ }
++
++ if ( Dist2( fp, mesh[PointIndex(pnums[0])]) >
++ Dist2( lp, mesh[PointIndex(pnums.Last())]))
+ std::swap( pnums[0], pnums.Last() );
++ }
}
}
-@@ -633,7 +683,8 @@
+@@ -633,7 +700,8 @@
}
(*testout) << "mesh face " << k << endl;
geom.facemeshstatus[k-1] = -1;
-@@ -901,7 +952,8 @@
+@@ -901,7 +969,8 @@
// if (k != 36) continue;
// (*testout) << "optimize face " << k << endl;
FaceDescriptor & fd = mesh.GetFaceDescriptor(k);
-@@ -1456,3 +1508,4 @@
+@@ -1456,3 +1525,4 @@
}
#endif
_shape (aShape),
_isVolume(isVolume),
_optimize(true),
+ _fineness(NETGENPlugin_Hypothesis::GetDefaultFineness()),
_simpleHyp(NULL)
{
defaultParameters();
mparams.quad = 0;
else
mparams.quad = NETGENPlugin_Hypothesis_2D::GetDefaultQuadAllowed() ? 1 : 0;
+ _fineness = NETGENPlugin_Hypothesis::GetDefaultFineness();
}
//=============================================================================
// Initialize global NETGEN parameters:
// maximal mesh segment size
mparams.maxh = hyp->GetMaxSize();
+ // maximal mesh element linear size
+ mparams.minh = hyp->GetMinSize();
// minimal number of segments per edge
mparams.segmentsperedge = hyp->GetNbSegPerEdge();
// rate of growth of size between elements
mparams.quad = static_cast<const NETGENPlugin_Hypothesis_2D*>
(hyp)->GetQuadAllowed() ? 1 : 0;
_optimize = hyp->GetOptimize();
+ _fineness = hyp->GetFineness();
_simpleHyp = NULL;
SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen();
void updateTriangulation( const TopoDS_Shape& shape )
{
- static set< Poly_Triangulation* > updated;
-
- TopLoc_Location loc;
- TopExp_Explorer fExp( shape, TopAbs_FACE );
- for ( ; fExp.More(); fExp.Next() )
- {
- Handle(Poly_Triangulation) triangulation =
- BRep_Tool::Triangulation ( TopoDS::Face( fExp.Current() ), loc);
- if ( triangulation.IsNull() ||
- updated.insert( triangulation.operator->() ).second )
- {
- BRepTools::Clean (shape);
+ // static set< Poly_Triangulation* > updated;
+
+ // TopLoc_Location loc;
+ // TopExp_Explorer fExp( shape, TopAbs_FACE );
+ // for ( ; fExp.More(); fExp.Next() )
+ // {
+ // Handle(Poly_Triangulation) triangulation =
+ // BRep_Tool::Triangulation ( TopoDS::Face( fExp.Current() ), loc);
+ // if ( triangulation.IsNull() ||
+ // updated.insert( triangulation.operator->() ).second )
+ // {
+ // BRepTools::Clean (shape);
try {
#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
#endif
BRepMesh_IncrementalMesh e(shape, 0.01, true);
+
}
catch (Standard_Failure)
{
- updated.erase( triangulation.operator->() );
}
- }
- }
+ // updated.erase( triangulation.operator->() );
+ // triangulation = BRep_Tool::Triangulation ( TopoDS::Face( fExp.Current() ), loc);
+ // updated.insert( triangulation.operator->() );
+ // }
+ // }
}
}
Handle(Poly_Triangulation) triangulation =
BRep_Tool::Triangulation ( TopoDS::Face( fExp.Current() ), loc);
if ( triangulation.IsNull() ) continue;
+ const double fTol = BRep_Tool::Tolerance( TopoDS::Face( fExp.Current() ));
const TColgp_Array1OfPnt& points = triangulation->Nodes();
const Poly_Array1OfTriangle& trias = triangulation->Triangles();
for ( int iT = trias.Lower(); iT <= trias.Upper(); ++iT )
for ( int j = 0; j < 3; ++j )
{
double dist2 = points(*pi[j]).SquareDistance( points( *pi[j+1] ));
- if ( dist2 < minh )
+ if ( dist2 < minh && fTol*fTol < dist2 )
minh = dist2;
bb.Add( points(*pi[j]));
}
return minh;
}
+//================================================================================
+/*!
+ * \brief Restrict size of elements at a given point
+ */
+//================================================================================
+
+void NETGENPlugin_Mesher::RestrictLocalSize(netgen::Mesh& ngMesh, const gp_XYZ& p, const double size)
+{
+ if ( netgen::mparam.minh > size )
+ {
+ ngMesh.SetMinimalH( size );
+ netgen::mparam.minh = size;
+ }
+ netgen::Point3d pi(p.X(), p.Y(), p.Z());
+ ngMesh.RestrictLocalH( pi, size );
+}
+
//================================================================================
/*!
* \brief fill ngMesh with nodes and elements of computed submeshes
const list< SMESH_subMesh* > & meshedSM)
{
TNode2IdMap nodeNgIdMap;
- if ( !nodeVec.empty() )
- for ( int i = 1; i < nodeVec.size(); ++i )
- nodeNgIdMap.insert( make_pair( nodeVec[i], i ));
+ for ( int i = 1; i < nodeVec.size(); ++i )
+ nodeNgIdMap.insert( make_pair( nodeVec[i], i ));
TopTools_MapOfShape visitedShapes;
map< SMESH_subMesh*, set< int > > visitedEdgeSM2Faces;
seg.edgenr = ngMesh.GetNSeg() + 1; // segment id
ngMesh.AddSegment (seg);
- netgen::Point3d ngP1(p1.node->X(), p1.node->Y(), p1.node->Z());
- netgen::Point3d ngP2(p2.node->X(), p2.node->Y(), p2.node->Z());
- ngMesh.RestrictLocalH( netgen::Center( ngP1,ngP2), Dist(ngP1,ngP2));
+ SMESH_TNodeXYZ np1( p1.node ), np2( p2.node );
+ RestrictLocalSize( ngMesh, 0.5*(np1+np2), (np1-np2).Modulus() );
#ifdef DUMP_SEGMENTS
cout << "Segment: " << seg.edgenr << " on SMESH face " << helper.GetMeshDS()->ShapeToIndex( face ) << endl
case TopAbs_VERTEX: { // VERTEX
// --------------------------
- SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes();
- if ( nodeIt->more() )
- ngNodeId( nodeIt->next(), ngMesh, nodeNgIdMap );
+ // issue 0021405. Add node only if a VERTEX is shared by a not meshed EDGE,
+ // else netgen removes a free node and nodeVector becomes invalid
+ PShapeIteratorPtr ansIt = helper.GetAncestors( sm->GetSubShape(),
+ *sm->GetFather(),
+ TopAbs_EDGE );
+ bool toAdd = false;
+ while ( const TopoDS_Shape* e = ansIt->next() )
+ {
+ SMESH_subMesh* eSub = helper.GetMesh()->GetSubMesh( *e );
+ if (( toAdd = eSub->IsEmpty() )) break;
+ }
+ if ( toAdd )
+ {
+ SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes();
+ if ( nodeIt->more() )
+ ngNodeId( nodeIt->next(), ngMesh, nodeNgIdMap );
+ }
break;
}
default:;
TopoDS_Iterator vIt( edge );
if ( !vIt.More() ) return;
gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( vIt.Value() ));
- netgen::Point3d pi(p.X(), p.Y(), p.Z());
- mesh.RestrictLocalH(pi, size);
+ NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), size );
}
else
{
{
Standard_Real u = u1 + delta*i;
gp_Pnt p = curve->Value(u);
+ NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), size );
netgen::Point3d pi(p.X(), p.Y(), p.Z());
- mesh.RestrictLocalH(pi, size);
double resultSize = mesh.GetH(pi);
if ( resultSize - size > 0.1*size )
// netgen does restriction iff oldH/newH > 1.2 (localh.cpp:136)
- mesh.RestrictLocalH(pi, resultSize/1.201);
+ NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), resultSize/1.201 );
}
}
}
if ( mparams.maxh == 0.0 )
mparams.maxh = occgeo.boundingbox.Diam();
- if ( _simpleHyp || mparams.minh == 0.0 )
+ if ( _simpleHyp || ( mparams.minh == 0.0 && _fineness != NETGENPlugin_Hypothesis::UserDefined))
mparams.minh = GetDefaultMinSize( _shape, mparams.maxh );
#ifdef NETGEN_NEW
occgeo.face_maxh = mparams.maxh;
const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key);
const TopoDS_Vertex& v = TopoDS::Vertex(shape);
gp_Pnt p = BRep_Tool::Pnt(v);
- netgen::Point3d pi(p.X(), p.Y(), p.Z());
- ngMesh->RestrictLocalH(pi, hi);
+ NETGENPlugin_Mesher::RestrictLocalSize( *ngMesh, p.XYZ(), hi );
}
}