+/**
+ * @brief Part of Compute: Setting the netgen parameters from the Hypothesis
+ *
+ * @param aMesh Global mesh
+ * @param ngLib Wrapper on netgen lib
+ * @param occgeo Mapping between nodes mesh id and netgen structure id
+ * @param helper helper assocaited to the mesh
+ * @param endWith end step of netgen
+ * @return true if there was some error
+ */
+bool NETGENPlugin_NETGEN_3D::computePrepareParam(
+ SMESH_Mesh& aMesh,
+ NETGENPlugin_NetgenLibWrapper &ngLib,
+ netgen::OCCGeometry &occgeo,
+ SMESH_MesherHelper &helper,
+ int &endWith)
+
+{
+ netgen::multithread.terminate = 0;
+
+ netgen::Mesh* ngMesh = ngLib._ngMesh;
+
+ NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true );
+
+
+ if ( _hypParameters )
+ {
+ aMesher.SetParameters( _hypParameters );
+
+ if ( !_hypParameters->GetLocalSizesAndEntries().empty() ||
+ !_hypParameters->GetMeshSizeFile().empty() )
+ {
+ if ( ! &ngMesh->LocalHFunction() )
+ {
+ netgen::Point3d pmin, pmax;
+ ngMesh->GetBox( pmin, pmax, 0 );
+ ngMesh->SetLocalH( pmin, pmax, _hypParameters->GetGrowthRate() );
+ }
+ aMesher.SetLocalSize( occgeo, *ngMesh );
+
+ try {
+ ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename );
+ } catch (netgen::NgException & ex) {
+ return error( COMPERR_BAD_PARMETERS, ex.What() );
+ }
+ }
+ if ( !_hypParameters->GetOptimize() )
+ endWith = netgen::MESHCONST_MESHVOLUME;
+ }
+ else if ( _hypMaxElementVolume )
+ {
+ netgen::mparam.maxh = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. );
+ // limitVolumeSize( ngMesh, mparam.maxh ); // result is unpredictable
+ }
+ else if ( aMesh.HasShapeToMesh() )
+ {
+ aMesher.PrepareOCCgeometry( occgeo, helper.GetSubShape(), aMesh );
+ netgen::mparam.maxh = occgeo.GetBoundingBox().Diam()/2;
+ }
+ else
+ {
+ netgen::Point3d pmin, pmax;
+ ngMesh->GetBox (pmin, pmax);
+ netgen::mparam.maxh = Dist(pmin, pmax)/2;
+ }
+
+ if ( !_hypParameters && aMesh.HasShapeToMesh() )
+ {
+ netgen::mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), netgen::mparam.maxh );
+ }
+ return false;
+}
+
+/**
+ * @brief Part of Compute: call to the netgen mesher
+ *
+ * @param occgeo netgen geometry structure
+ * @param nodeVec Mapping between nodes mesh id and netgen structure id
+ * @param ngMesh netgen mesh structure
+ * @param ngLib Wrapper on netgen lib
+ * @param startWith starting step of netgen
+ * @param endWith end step of netgen
+ * @return true if there was some error
+ */
+bool NETGENPlugin_NETGEN_3D::computeRunMesher(
+ netgen::OCCGeometry &occgeo,
+ vector< const SMDS_MeshNode* > &nodeVec,
+ netgen::Mesh* ngMesh,
+ NETGENPlugin_NetgenLibWrapper &ngLib,
+ int &startWith, int &endWith)
+{
+ int err = 1;
+
+ try
+ {
+ OCC_CATCH_SIGNALS;
+
+ ngLib.CalcLocalH(ngMesh);
+ err = ngLib.GenerateMesh(occgeo, startWith, endWith);
+
+ if(netgen::multithread.terminate)
+ return false;
+ if ( err ){
+ error(SMESH_Comment("Error in netgen::OCCGenerateMesh() at ") << netgen::multithread.task);
+ }
+ }
+ catch (Standard_Failure& ex)
+ {
+ SMESH_Comment str("Exception in netgen::OCCGenerateMesh()");
+ str << " at " << netgen::multithread.task
+ << ": " << ex.DynamicType()->Name();
+ if ( ex.GetMessageString() && strlen( ex.GetMessageString() ))
+ str << ": " << ex.GetMessageString();
+ error(str);
+ }
+ catch (netgen::NgException& exc)
+ {
+ SMESH_Comment str("NgException");
+ if ( strlen( netgen::multithread.task ) > 0 )
+ str << " at " << netgen::multithread.task;
+ str << ": " << exc.What();
+ error(str);
+ }
+ catch (...)
+ {
+ SMESH_Comment str("Exception in netgen::OCCGenerateMesh()");
+ if ( strlen( netgen::multithread.task ) > 0 )
+ str << " at " << netgen::multithread.task;
+ error(str);
+ }
+
+ if ( err )
+ {
+ SMESH_ComputeErrorPtr ce = NETGENPlugin_Mesher::ReadErrors(nodeVec);
+ if ( ce && ce->HasBadElems() ){
+ error( ce );
+ }
+ }
+
+ return false;
+}
+
+/**
+ * @brief Part of Compute: Adding new element created by mesher to SMESH_Mesh
+ *
+ * @param nodeVec Mapping between nodes mesh id and netgen structure id
+ * @param ngLib Wrapper on netgen lib
+ * @param helper tool associated to the mesh to add element
+ * @param Netgen_NbOfNodes Number of nodes in netgen structure
+ * @return true if there was some error
+ */
+bool NETGENPlugin_NETGEN_3D::computeFillMesh(
+ vector< const SMDS_MeshNode* > &nodeVec,
+ NETGENPlugin_NetgenLibWrapper &ngLib,
+ SMESH_MesherHelper &helper,
+ int &Netgen_NbOfNodes
+ )
+{
+ Ng_Mesh* Netgen_mesh = ngLib.ngMesh();
+
+ int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh);
+ int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh);
+
+ bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built
+ if ( isOK )
+ {
+ double Netgen_point[3];
+ int Netgen_tetrahedron[4];
+
+ // create and insert new nodes into nodeVec
+ nodeVec.resize( Netgen_NbOfNodesNew + 1, 0 );
+ int nodeIndex = Netgen_NbOfNodes + 1;
+ for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex )
+ {
+ Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point );
+ nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], Netgen_point[1], Netgen_point[2]);
+ }
+
+ // create tetrahedrons
+ for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex )
+ {
+ Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron);
+ try
+ {
+ helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ),
+ nodeVec.at( Netgen_tetrahedron[1] ),
+ nodeVec.at( Netgen_tetrahedron[2] ),
+ nodeVec.at( Netgen_tetrahedron[3] ));
+ }
+ catch (...)
+ {
+ }
+ }
+ }
+ return false;
+}
+
+
+/**
+ * @brief Compute mesh associate to shape
+ *
+ * @param aMesh The mesh
+ * @param aShape The shape
+ * @return true fi there are some error
+ */
+bool NETGENPlugin_NETGEN_3D::Compute(
+ SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape)
+{
+ // vector of nodes in which node index == netgen ID
+ vector< const SMDS_MeshNode* > nodeVec;
+ NETGENPlugin_NetgenLibWrapper ngLib;
+ SMESH_MesherHelper helper(aMesh);
+ int startWith = netgen::MESHCONST_MESHVOLUME;
+ int endWith = netgen::MESHCONST_OPTVOLUME;
+ int Netgen_NbOfNodes;
+
+ computeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, Netgen_NbOfNodes);
+
+ netgen::OCCGeometry occgeo;
+ computePrepareParam(aMesh, ngLib, occgeo, helper, endWith);
+ computeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, startWith, endWith);
+
+ computeFillMesh(nodeVec, ngLib, helper, Netgen_NbOfNodes);
+
+ return false;