X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FBLSURFPlugin%2FBLSURFPlugin_BLSURF.cxx;h=2fccd631396f90df50eea39e8f2343c21736e3b7;hb=a7ad9fe72a1b38e75b2a6ef7b2bbea41dbdfed94;hp=58a0c0fe228da233d2b99a229a5409cabae59e27;hpb=1ee1aea7333a0f0bfc8d1fcb5ba5396ad203608f;p=plugins%2Fblsurfplugin.git diff --git a/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx b/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx index 58a0c0f..2fccd63 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -31,14 +31,12 @@ extern "C"{ #include #include -#include } #include #include -#include #include #include @@ -62,17 +60,19 @@ extern "C"{ // OPENCASCADE includes #include #include -//#include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -96,6 +96,8 @@ extern "C"{ #include #endif +using namespace std; + /* ================================== * =========== PYTHON ============== * ==================================*/ @@ -143,8 +145,7 @@ namespace static PyTypeObject PyStdOut_Type = { /* The ob_type field must be initialized in the module init function * to be portable to Windows without using C++. */ - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ + PyVarObject_HEAD_INIT(NULL, 0) "PyOut", /*tp_name*/ sizeof(PyStdOut), /*tp_basicsize*/ 0, /*tp_itemsize*/ @@ -225,6 +226,7 @@ TopTools_IndexedMapOfShape FacesWithEnforcedVertices; std::map< int, BLSURFPlugin_Hypothesis::TEnfVertexCoordsList > FaceId2EnforcedVertexCoords; std::map< BLSURFPlugin_Hypothesis::TEnfVertexCoords, BLSURFPlugin_Hypothesis::TEnfVertexCoords > EnfVertexCoords2ProjVertex; std::map< BLSURFPlugin_Hypothesis::TEnfVertexCoords, BLSURFPlugin_Hypothesis::TEnfVertexList > EnfVertexCoords2EnfVertexList; +SMESH_MesherHelper* theHelper; bool HasSizeMapOnFace=false; bool HasSizeMapOnEdge=false; @@ -237,31 +239,21 @@ bool HasSizeMapOnVertex=false; */ //============================================================================= -BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF(int hypId, int studyId, - SMESH_Gen* gen) - : SMESH_2D_Algo(hypId, studyId, gen) +BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF(int hypId, + SMESH_Gen* gen, + bool theHasGEOM) + : SMESH_2D_Algo(hypId, gen) { - MESSAGE("BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF"); - - _name = "MG-CADSurf";//"BLSURF"; + _name = theHasGEOM ? "MG-CADSurf" : "MG-CADSurf_NOGEOM";//"BLSURF"; _shapeType = (1 << TopAbs_FACE); // 1 bit /shape type - _compatibleHypothesis.push_back(BLSURFPlugin_Hypothesis::GetHypType()); - _compatibleHypothesis.push_back(StdMeshers_ViscousLayers2D::GetHypType()); + _compatibleHypothesis.push_back(BLSURFPlugin_Hypothesis::GetHypType(theHasGEOM)); + if ( theHasGEOM ) + _compatibleHypothesis.push_back(StdMeshers_ViscousLayers2D::GetHypType()); _requireDiscreteBoundary = false; _onlyUnaryInput = false; _hypothesis = NULL; _supportSubmeshes = true; - - smeshGen_i = SMESH_Gen_i::GetSMESHGen(); - CORBA::Object_var anObject = smeshGen_i->GetNS()->Resolve("/myStudyManager"); - SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject); - - MESSAGE("studyid = " << _studyId); - - myStudy = NULL; - myStudy = aStudyMgr->GetStudyByID(_studyId); - if ( !myStudy->_is_nil() ) - MESSAGE("myStudy->StudyId() = " << myStudy->StudyId()); + _requireShape = theHasGEOM; /* Initialize the Python interpreter */ assert(Py_IsInitialized()); @@ -305,7 +297,6 @@ BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF(int hypId, int studyId, BLSURFPlugin_BLSURF::~BLSURFPlugin_BLSURF() { - MESSAGE("BLSURFPlugin_BLSURF::~BLSURFPlugin_BLSURF"); } @@ -338,7 +329,8 @@ bool BLSURFPlugin_BLSURF::CheckHypothesis { theHyp = *itl; string hypName = theHyp->GetName(); - if ( hypName == BLSURFPlugin_Hypothesis::GetHypType() ) + if ( hypName == BLSURFPlugin_Hypothesis::GetHypType(true) || + hypName == BLSURFPlugin_Hypothesis::GetHypType(false) ) { _hypothesis = static_cast (theHyp); ASSERT(_hypothesis); @@ -408,66 +400,120 @@ typedef struct { gp_XY uv; gp_XYZ xyz; } projectionPoint; + ///////////////////////////////////////////////////////// -projectionPoint getProjectionPoint(const TopoDS_Face& face, const gp_Pnt& point) + +projectionPoint getProjectionPoint(TopoDS_Face& theFace, const gp_Pnt& thePoint) { projectionPoint myPoint; - Handle(Geom_Surface) surface = BRep_Tool::Surface(face); - GeomAPI_ProjectPointOnSurf projector( point, surface ); - if ( !projector.IsDone() || projector.NbPoints()==0 ) - throw "getProjectionPoint: Can't project"; - - Quantity_Parameter u,v; - projector.LowerDistanceParameters(u,v); - myPoint.uv = gp_XY(u,v); - gp_Pnt aPnt = projector.NearestPoint(); - myPoint.xyz = gp_XYZ(aPnt.X(),aPnt.Y(),aPnt.Z()); - //return gp_XY(u,v); - return myPoint; -} -///////////////////////////////////////////////////////// -///////////////////////////////////////////////////////// -double getT(const TopoDS_Edge& edge, const gp_Pnt& point) -{ - Standard_Real f,l; - Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, f,l); - GeomAPI_ProjectPointOnCurve projector( point, curve); - if ( projector.NbPoints() == 0 ) - throw; - return projector.LowerDistanceParameter(); + if ( theFace.IsNull() ) + { + TopoDS_Shape foundFace, myShape = theHelper->GetSubShape(); + TopTools_MapOfShape checkedFaces; + std::map< double, std::pair< TopoDS_Face, gp_Pnt2d > > dist2face; + + for ( TopExp_Explorer exp ( myShape, TopAbs_FACE ); exp.More(); exp.Next()) + { + const TopoDS_Face& face = TopoDS::Face( exp.Current() ); + if ( !checkedFaces.Add( face )) continue; + + // check distance to face + Handle(ShapeAnalysis_Surface) surface = theHelper->GetSurface( face ); + gp_Pnt2d uv = surface->ValueOfUV( thePoint, Precision::Confusion()); + double distance = surface->Gap(); + if ( distance > Precision::Confusion() ) + { + // the face is far, store for future analysis + dist2face.insert( std::make_pair( distance, std::make_pair( face, uv ))); + } + else + { + // check location on the face + BRepClass_FaceClassifier FC( face, uv, BRep_Tool::Tolerance( face )); + if ( FC.State() == TopAbs_IN ) + { + if ( !foundFace.IsNull() ) + return myPoint; // thePoint seems to be TopAbs_ON + foundFace = face; + myPoint.uv = uv.XY(); + myPoint.xyz = surface->Value( uv ).XYZ(); + // break; + } + if ( FC.State() == TopAbs_ON ) + return myPoint; + } + } + if ( foundFace.IsNull() ) + { + // find the closest face + std::map< double, std::pair< TopoDS_Face, gp_Pnt2d > >::iterator d2f = dist2face.begin(); + for ( ; d2f != dist2face.end(); ++d2f ) + { + const TopoDS_Face& face = d2f->second.first; + const gp_Pnt2d & uv = d2f->second.second; + BRepClass_FaceClassifier FC( face, uv, Precision::Confusion()); + if ( FC.State() == TopAbs_IN ) + { + foundFace = face; + myPoint.uv = uv.XY(); + myPoint.xyz = theHelper->GetSurface( face )->Value( uv ).XYZ(); + break; + } + } + } + // set the resultShape + // if ( foundFace.IsNull() ) + // throw SMESH_ComputeError(COMPERR_BAD_PARMETERS, + // "getProjectionPoint: can't find a face by a vertex"); + theFace = TopoDS::Face( foundFace ); + } + else + { + Handle(Geom_Surface) surface = BRep_Tool::Surface( theFace ); + GeomAPI_ProjectPointOnSurf projector( thePoint, surface ); + if ( !projector.IsDone() || projector.NbPoints()==0 ) + throw SMESH_ComputeError(COMPERR_BAD_PARMETERS, + "getProjectionPoint: can't project a vertex to a face"); + + Standard_Real u,v; + projector.LowerDistanceParameters(u,v); + myPoint.uv = gp_XY(u,v); + gp_Pnt aPnt = projector.NearestPoint(); + myPoint.xyz = gp_XYZ(aPnt.X(),aPnt.Y(),aPnt.Z()); + + BRepClass_FaceClassifier FC( theFace, myPoint.uv, Precision::Confusion()); + if ( FC.State() != TopAbs_IN ) + theFace.Nullify(); + } + + return myPoint; } ///////////////////////////////////////////////////////// TopoDS_Shape BLSURFPlugin_BLSURF::entryToShape(std::string entry) { - MESSAGE("BLSURFPlugin_BLSURF::entryToShape "<FindObjectID( entry.c_str() ); + SALOMEDS::SObject_var aSObj = SMESH_Gen_i::getStudyServant()->FindObjectID( entry.c_str() ); if (!aSObj->_is_nil()) { CORBA::Object_var obj = aSObj->GetObject(); aGeomObj = GEOM::GEOM_Object::_narrow(obj); aSObj->UnRegister(); } if ( !aGeomObj->_is_nil() ) - S = smeshGen_i->GeomObjectToShape( aGeomObj.in() ); + S = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( aGeomObj.in() ); return S; } void _createEnforcedVertexOnFace(TopoDS_Face faceShape, gp_Pnt aPnt, BLSURFPlugin_Hypothesis::TEnfVertex *enfVertex) { BLSURFPlugin_Hypothesis::TEnfVertexCoords enf_coords, coords, s_coords; - enf_coords.clear(); - coords.clear(); - s_coords.clear(); - // Get the (u,v) values of the enforced vertex on the face + // Find the face and get the (u,v) values of the enforced vertex on the face projectionPoint myPoint = getProjectionPoint(faceShape,aPnt); - - MESSAGE("Enforced Vertex: " << aPnt.X() << ", " << aPnt.Y() << ", " << aPnt.Z()); - MESSAGE("Projected Vertex: " << myPoint.xyz.X() << ", " << myPoint.xyz.Y() << ", " << myPoint.xyz.Z()); - MESSAGE("Parametric coordinates: " << myPoint.uv.X() << ", " << myPoint.uv.Y() ); + if ( faceShape.IsNull() ) + return; enf_coords.push_back(aPnt.X()); enf_coords.push_back(aPnt.Y()); @@ -484,10 +530,7 @@ void _createEnforcedVertexOnFace(TopoDS_Face faceShape, gp_Pnt aPnt, BLSURFPlugi s_coords.push_back(myPoint.xyz.Z()); // Save pair projected vertex / enf vertex - MESSAGE("Storing pair projected vertex / enf vertex:"); - MESSAGE("("<< myPoint.xyz.X() << ", " << myPoint.xyz.Y() << ", " << myPoint.xyz.Z() <<") / (" << aPnt.X() << ", " << aPnt.Y() << ", " << aPnt.Z()<<")"); EnfVertexCoords2ProjVertex[s_coords] = enf_coords; - MESSAGE("Group name is: \"" << enfVertex->grpName << "\""); pair ret; BLSURFPlugin_Hypothesis::TEnfVertexList::iterator it; ret = EnfVertexCoords2EnfVertexList[s_coords].insert(enfVertex); @@ -513,26 +556,18 @@ void _createEnforcedVertexOnFace(TopoDS_Face faceShape, gp_Pnt aPnt, BLSURFPlugi sameAttractor = true; if (FaceId2EnforcedVertexCoords.find(key) != FaceId2EnforcedVertexCoords.end()) { - MESSAGE("Map of enf. vertex has key " << key) - MESSAGE("Enf. vertex list size is: " << FaceId2EnforcedVertexCoords[key].size()) if (! sameAttractor) FaceId2EnforcedVertexCoords[key].insert(coords); // there should be no redondant coords here (see std::set management) - else - MESSAGE("An attractor node is already defined: I don't add the enforced vertex"); - MESSAGE("New Enf. vertex list size is: " << FaceId2EnforcedVertexCoords[key].size()) } else { - MESSAGE("Map of enf. vertex has not key " << key << ": creating it") if (! sameAttractor) { BLSURFPlugin_Hypothesis::TEnfVertexCoordsList ens; ens.insert(coords); FaceId2EnforcedVertexCoords[key] = ens; } - else - MESSAGE("An attractor node is already defined: I don't add the enforced vertex"); } } - + ///////////////////////////////////////////////////////// void BLSURFPlugin_BLSURF::createEnforcedVertexOnFace(TopoDS_Shape faceShape, BLSURFPlugin_Hypothesis::TEnfVertexList enfVertexList) { @@ -553,18 +588,22 @@ void BLSURFPlugin_BLSURF::createEnforcedVertexOnFace(TopoDS_Shape faceShape, BLS if (enfVertex->geomEntry != "") { TopoDS_Shape GeomShape = entryToShape(enfVertex->geomEntry); TopAbs_ShapeEnum GeomType = GeomShape.ShapeType(); - if (GeomType == TopAbs_VERTEX){ - aPnt = BRep_Tool::Pnt(TopoDS::Vertex(GeomShape)); + if (GeomType == TopAbs_VERTEX) + { + enfVertex->vertex = TopoDS::Vertex( GeomShape ); + aPnt = BRep_Tool::Pnt( enfVertex->vertex ); _createEnforcedVertexOnFace( TopoDS::Face(faceShape), aPnt, enfVertex); } // Group Management - if (GeomType == TopAbs_COMPOUND){ - for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()){ - if (it.Value().ShapeType() == TopAbs_VERTEX){ - aPnt = BRep_Tool::Pnt(TopoDS::Vertex(it.Value())); + if (GeomType == TopAbs_COMPOUND) + { + for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()) + if (it.Value().ShapeType() == TopAbs_VERTEX) + { + enfVertex->vertex = TopoDS::Vertex( it.Value() ); + aPnt = BRep_Tool::Pnt( enfVertex->vertex ); _createEnforcedVertexOnFace( TopoDS::Face(faceShape), aPnt, enfVertex); } - } } } } @@ -573,7 +612,6 @@ void BLSURFPlugin_BLSURF::createEnforcedVertexOnFace(TopoDS_Shape faceShape, BLS ///////////////////////////////////////////////////////// void createAttractorOnFace(TopoDS_Shape GeomShape, std::string AttractorFunction, double defaultSize) { - MESSAGE("Attractor function: "<< AttractorFunction); double xa, ya, za; // Coordinates of attractor point double a, b; // Attractor parameter double d = 0.; @@ -621,7 +659,6 @@ void createAttractorOnFace(TopoDS_Shape GeomShape, std::string AttractorFunction pos2 = AttractorFunction.find(sep, pos1+1); if (pos2!=string::npos) { string createNodeStr = AttractorFunction.substr(pos1+1, pos2-pos1-1); - MESSAGE("createNode: " << createNodeStr); createNode = (AttractorFunction.substr(pos1+1, pos2-pos1-1) == "True"); pos1=pos2; } @@ -656,8 +693,6 @@ void createAttractorOnFace(TopoDS_Shape GeomShape, std::string AttractorFunction // of r-d where r is the distance to (u0,v0) attractorFunctionStream << "*exp(-(0.5*(sqrt((u-"<GetMeshDS()->ShapeToIndex(face_iter.Current()); if (face_id == 0) - throw SALOME_Exception ( SMESH_Comment("Sub_shape not found in main_shape")); + throw SALOME_Exception ( "Periodicity: sub_shape not found in main_shape"); face_ids.push_back(face_id); } @@ -737,37 +759,34 @@ BLSURFPlugin_BLSURF::TListOfIDs _getSubShapeIDsInMainShape(SMESH_Mesh* theM void BLSURFPlugin_BLSURF::addCoordsFromVertices(const std::vector &theVerticesEntries, std::vector &theVerticesCoords) { for (std::vector::const_iterator it = theVerticesEntries.begin(); it != theVerticesEntries.end(); it++) - { - BLSURFPlugin_Hypothesis::TEntry theVertexEntry = *it; - MESSAGE("Vertex entry " << theVertexEntry); - addCoordsFromVertex(theVertexEntry, theVerticesCoords); - } + { + BLSURFPlugin_Hypothesis::TEntry theVertexEntry = *it; + addCoordsFromVertex(theVertexEntry, theVerticesCoords); + } } void BLSURFPlugin_BLSURF::addCoordsFromVertex(BLSURFPlugin_Hypothesis::TEntry theVertexEntry, std::vector &theVerticesCoords) { if (theVertexEntry!="") - { - TopoDS_Shape aShape = entryToShape(theVertexEntry); + { + TopoDS_Shape aShape = entryToShape(theVertexEntry); - gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) ); - double theX, theY, theZ; - theX = aPnt.X(); - theY = aPnt.Y(); - theZ = aPnt.Z(); + gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) ); + double theX, theY, theZ; + theX = aPnt.X(); + theY = aPnt.Y(); + theZ = aPnt.Z(); - theVerticesCoords.push_back(theX); - theVerticesCoords.push_back(theY); - theVerticesCoords.push_back(theZ); - } + theVerticesCoords.push_back(theX); + theVerticesCoords.push_back(theY); + theVerticesCoords.push_back(theZ); + } } ///////////////////////////////////////////////////////// void BLSURFPlugin_BLSURF::createPreCadFacesPeriodicity(TopoDS_Shape theGeomShape, const BLSURFPlugin_Hypothesis::TPreCadPeriodicity &preCadPeriodicity) { - MESSAGE("BLSURFPlugin_BLSURF::createFacesPeriodicity"); - TopoDS_Shape geomShape1 = entryToShape(preCadPeriodicity.shape1Entry); TopoDS_Shape geomShape2 = entryToShape(preCadPeriodicity.shape2Entry); @@ -778,26 +797,15 @@ void BLSURFPlugin_BLSURF::createPreCadFacesPeriodicity(TopoDS_Shape theGeomShape preCadFacesPeriodicityIDs.shape1IDs = theFace1_ids; preCadFacesPeriodicityIDs.shape2IDs = theFace2_ids; - MESSAGE("preCadPeriodicity.theSourceVerticesEntries.size(): " << preCadPeriodicity.theSourceVerticesEntries.size()); - MESSAGE("preCadPeriodicity.theTargetVerticesEntries.size(): " << preCadPeriodicity.theTargetVerticesEntries.size()); - addCoordsFromVertices(preCadPeriodicity.theSourceVerticesEntries, preCadFacesPeriodicityIDs.theSourceVerticesCoords); addCoordsFromVertices(preCadPeriodicity.theTargetVerticesEntries, preCadFacesPeriodicityIDs.theTargetVerticesCoords); - MESSAGE("preCadFacesPeriodicityIDs.theSourceVerticesCoords.size(): " << preCadFacesPeriodicityIDs.theSourceVerticesCoords.size()); - MESSAGE("preCadFacesPeriodicityIDs.theTargetVerticesCoords.size(): " << preCadFacesPeriodicityIDs.theTargetVerticesCoords.size()); - _preCadFacesIDsPeriodicityVector.push_back(preCadFacesPeriodicityIDs); - MESSAGE("_preCadFacesIDsPeriodicityVector.size() = " << _preCadFacesIDsPeriodicityVector.size()); - MESSAGE("BLSURFPlugin_BLSURF::createFacesPeriodicity END"); - } ///////////////////////////////////////////////////////// void BLSURFPlugin_BLSURF::createPreCadEdgesPeriodicity(TopoDS_Shape theGeomShape, const BLSURFPlugin_Hypothesis::TPreCadPeriodicity &preCadPeriodicity) { - MESSAGE("BLSURFPlugin_BLSURF::createEdgesPeriodicity"); - TopoDS_Shape geomShape1 = entryToShape(preCadPeriodicity.shape1Entry); TopoDS_Shape geomShape2 = entryToShape(preCadPeriodicity.shape2Entry); @@ -812,130 +820,32 @@ void BLSURFPlugin_BLSURF::createPreCadEdgesPeriodicity(TopoDS_Shape theGeomShape addCoordsFromVertices(preCadPeriodicity.theTargetVerticesEntries, preCadEdgesPeriodicityIDs.theTargetVerticesCoords); _preCadEdgesIDsPeriodicityVector.push_back(preCadEdgesPeriodicityIDs); - MESSAGE("_preCadEdgesIDsPeriodicityVector.size() = " << _preCadEdgesIDsPeriodicityVector.size()); - MESSAGE("BLSURFPlugin_BLSURF::createEdgesPeriodicity END"); - -} - -///////////////////////////////////////////////////////// -void BLSURFPlugin_BLSURF::createFacesPeriodicity(TopoDS_Shape theGeomShape, BLSURFPlugin_Hypothesis::TEntry theFace1, BLSURFPlugin_Hypothesis::TEntry theFace2) -{ - MESSAGE("BLSURFPlugin_BLSURF::createFacesPeriodicity"); - - TopoDS_Shape GeomShape1 = entryToShape(theFace1); - TopoDS_Shape GeomShape2 = entryToShape(theFace2); - - TListOfIDs theFace1_ids = _getSubShapeIDsInMainShape(theGeomShape, GeomShape1, TopAbs_FACE); - TListOfIDs theFace2_ids = _getSubShapeIDsInMainShape(theGeomShape, GeomShape2, TopAbs_FACE); - - // Only one face id, since only a face can be selected - int theFace1_id = theFace1_ids[0]; - int theFace2_id = theFace2_ids[0]; - - std::pair pairOfFacesID = std::make_pair(theFace1_id, theFace2_id); - - _facesIDsPeriodicityVector.push_back(pairOfFacesID); - MESSAGE("_facesIDsPeriodicityVector.size() = " << _facesIDsPeriodicityVector.size()); - MESSAGE("BLSURFPlugin_BLSURF::createFacesPeriodicity END"); - } -///////////////////////////////////////////////////////// -void BLSURFPlugin_BLSURF::createEdgesPeriodicity(TopoDS_Shape theGeomShape, BLSURFPlugin_Hypothesis::TEntry theFace1, BLSURFPlugin_Hypothesis::TEntry theEdge1, - BLSURFPlugin_Hypothesis::TEntry theFace2, BLSURFPlugin_Hypothesis::TEntry theEdge2, int edge_orientation) -{ - MESSAGE("BLSURFPlugin_BLSURF::createEdgesPeriodicity"); - - TEdgePeriodicityIDs edgePeriodicityIDs; - - if (theFace1 != "") - { - TopoDS_Shape GeomFace1 = entryToShape(theFace1); - TListOfIDs theFace1_ids = _getSubShapeIDsInMainShape(theGeomShape, GeomFace1, TopAbs_FACE); - // Only one face id, since only a face can be selected - edgePeriodicityIDs.theFace1ID = theFace1_ids[0]; - } - else - edgePeriodicityIDs.theFace1ID = 0; - if (theFace2 != "") - { - TopoDS_Shape GeomFace2 = entryToShape(theFace2); - TListOfIDs theFace2_ids = _getSubShapeIDsInMainShape(theGeomShape, GeomFace2, TopAbs_FACE); - edgePeriodicityIDs.theFace2ID = theFace2_ids[0]; - } - else - edgePeriodicityIDs.theFace2ID = 0; - - TopoDS_Shape GeomEdge1 = entryToShape(theEdge1); - TopoDS_Shape GeomEdge2 = entryToShape(theEdge2); - - TListOfIDs theEdge1_ids = _getSubShapeIDsInMainShape(theGeomShape, GeomEdge1, TopAbs_EDGE); - TListOfIDs theEdge2_ids = _getSubShapeIDsInMainShape(theGeomShape, GeomEdge2, TopAbs_EDGE); - - if (edge_orientation == 0 && GeomEdge1.Closed()) - { - // if edge is closed, we have to set its orientation - MESSAGE("GeomEdge1.Orientation() = " << GeomEdge1.Orientation()); - MESSAGE("GeomEdge2.Orientation() = " << GeomEdge2.Orientation()); - if(GeomEdge1.Orientation() == TopAbs_FORWARD) - edge_orientation = CAD_ORIENTATION_REVERSED; - else - edge_orientation = CAD_ORIENTATION_FORWARD; - } - - // Only one edge id, since only a edge can be selected - edgePeriodicityIDs.theEdge1ID = theEdge1_ids[0]; - edgePeriodicityIDs.theEdge2ID = theEdge2_ids[0]; - edgePeriodicityIDs.edge_orientation = edge_orientation; - - _edgesIDsPeriodicityVector.push_back(edgePeriodicityIDs); - MESSAGE("_edgesIDsPeriodicityVector.size() = " << _edgesIDsPeriodicityVector.size()); - MESSAGE("BLSURFPlugin_BLSURF::createEdgesPeriodicity END"); - -} - - -///////////////////////////////////////////////////////// -void BLSURFPlugin_BLSURF::createVerticesPeriodicity(TopoDS_Shape theGeomShape, BLSURFPlugin_Hypothesis::TEntry theEdge1, BLSURFPlugin_Hypothesis::TEntry theVertex1, - BLSURFPlugin_Hypothesis::TEntry theEdge2, BLSURFPlugin_Hypothesis::TEntry theVertex2) -{ - MESSAGE("BLSURFPlugin_BLSURF::createVerticesPeriodicity"); - - TopoDS_Shape GeomEdge1 = entryToShape(theEdge1); - TopoDS_Shape GeomVertex1 = entryToShape(theVertex1); - TopoDS_Shape GeomEdge2 = entryToShape(theEdge2); - TopoDS_Shape GeomVertex2 = entryToShape(theVertex2); - - TListOfIDs theEdge1_ids = _getSubShapeIDsInMainShape(theGeomShape, GeomEdge1, TopAbs_EDGE); - TListOfIDs vertices1_ids = _getSubShapeIDsInMainShape(theGeomShape, GeomVertex1, TopAbs_VERTEX); - TListOfIDs theEdge2_ids = _getSubShapeIDsInMainShape(theGeomShape, GeomEdge2, TopAbs_EDGE); - TListOfIDs vertices2_ids = _getSubShapeIDsInMainShape(theGeomShape, GeomVertex2, TopAbs_VERTEX); - - // Only one vertex id, since only a vertex can be selected - TVertexPeriodicityIDs vertexPeriodicityIDs; - vertexPeriodicityIDs.theEdge1ID = theEdge1_ids[0]; - vertexPeriodicityIDs.theVertex1ID = vertices1_ids[0]; - vertexPeriodicityIDs.theEdge2ID = theEdge2_ids[0]; - vertexPeriodicityIDs.theVertex2ID = vertices2_ids[0]; - - _verticesIDsPeriodicityVector.push_back(vertexPeriodicityIDs); - MESSAGE("_verticesIDsPeriodicityVector.size() = " << _verticesIDsPeriodicityVector.size()); - MESSAGE("BLSURFPlugin_BLSURF::createVerticesPeriodicity END"); - -} - ///////////////////////////////////////////////////////// void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, cadsurf_session_t * css, - precad_session_t * pcs, - const TopoDS_Shape& theGeomShape, - bool * use_precad - ) + const TopoDS_Shape& theGeomShape) { // rnc : Bug 1457 // Clear map so that it is not stored in the algorithm with old enforced vertices in it + FacesWithSizeMap.Clear(); + FaceId2SizeMap.clear(); + EdgesWithSizeMap.Clear(); + EdgeId2SizeMap.clear(); + VerticesWithSizeMap.Clear(); + VertexId2SizeMap.clear(); + FaceId2PythonSmp.clear(); + EdgeId2PythonSmp.clear(); + VertexId2PythonSmp.clear(); + FaceId2AttractorCoords.clear(); + FaceId2ClassAttractor.clear(); + FaceIndex2ClassAttractor.clear(); + FacesWithEnforcedVertices.Clear(); + FaceId2EnforcedVertexCoords.clear(); + EnfVertexCoords2ProjVertex.clear(); EnfVertexCoords2EnfVertexList.clear(); double diagonal = SMESH_Mesh::GetShapeDiagonalSize( theGeomShape ); @@ -948,29 +858,43 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, bool _minSizeRel = BLSURFPlugin_Hypothesis::GetDefaultMinSizeRel(); double _maxSize = BLSURFPlugin_Hypothesis::GetDefaultMaxSize(diagonal); bool _maxSizeRel = BLSURFPlugin_Hypothesis::GetDefaultMaxSizeRel(); + double _use_gradation = BLSURFPlugin_Hypothesis::GetDefaultUseGradation(); double _gradation = BLSURFPlugin_Hypothesis::GetDefaultGradation(); - bool _quadAllowed = BLSURFPlugin_Hypothesis::GetDefaultQuadAllowed(); + double _use_volume_gradation = BLSURFPlugin_Hypothesis::GetDefaultUseVolumeGradation(); + double _volume_gradation = BLSURFPlugin_Hypothesis::GetDefaultVolumeGradation(); + BLSURFPlugin_Hypothesis::ElementType _elementType = BLSURFPlugin_Hypothesis::GetDefaultElementType(); double _angleMesh = BLSURFPlugin_Hypothesis::GetDefaultAngleMesh(); double _chordalError = BLSURFPlugin_Hypothesis::GetDefaultChordalError(diagonal); bool _anisotropic = BLSURFPlugin_Hypothesis::GetDefaultAnisotropic(); double _anisotropicRatio = BLSURFPlugin_Hypothesis::GetDefaultAnisotropicRatio(); bool _removeTinyEdges = BLSURFPlugin_Hypothesis::GetDefaultRemoveTinyEdges(); double _tinyEdgeLength = BLSURFPlugin_Hypothesis::GetDefaultTinyEdgeLength(diagonal); + bool _optimiseTinyEdges = BLSURFPlugin_Hypothesis::GetDefaultOptimiseTinyEdges(); + double _tinyEdgeOptimisLength = BLSURFPlugin_Hypothesis::GetDefaultTinyEdgeOptimisationLength(diagonal); + bool _correctSurfaceIntersec= BLSURFPlugin_Hypothesis::GetDefaultCorrectSurfaceIntersection(); + double _corrSurfaceIntersCost = BLSURFPlugin_Hypothesis::GetDefaultCorrectSurfaceIntersectionMaxCost(); bool _badElementRemoval = BLSURFPlugin_Hypothesis::GetDefaultBadElementRemoval(); double _badElementAspectRatio = BLSURFPlugin_Hypothesis::GetDefaultBadElementAspectRatio(); bool _optimizeMesh = BLSURFPlugin_Hypothesis::GetDefaultOptimizeMesh(); bool _quadraticMesh = BLSURFPlugin_Hypothesis::GetDefaultQuadraticMesh(); int _verb = BLSURFPlugin_Hypothesis::GetDefaultVerbosity(); - int _topology = BLSURFPlugin_Hypothesis::GetDefaultTopology(); + //int _topology = BLSURFPlugin_Hypothesis::GetDefaultTopology(); + bool _useSurfaceProximity = BLSURFPlugin_Hypothesis::GetDefaultUseSurfaceProximity (); + int _nbSurfaceProximityLayers = BLSURFPlugin_Hypothesis::GetDefaultNbSurfaceProximityLayers(); + double _surfaceProximityRatio = BLSURFPlugin_Hypothesis::GetDefaultSurfaceProximityRatio (); + bool _useVolumeProximity = BLSURFPlugin_Hypothesis::GetDefaultUseVolumeProximity (); + int _nbVolumeProximityLayers = BLSURFPlugin_Hypothesis::GetDefaultNbVolumeProximityLayers (); + double _volumeProximityRatio = BLSURFPlugin_Hypothesis::GetDefaultVolumeProximityRatio (); // PreCAD - int _precadMergeEdges = BLSURFPlugin_Hypothesis::GetDefaultPreCADMergeEdges(); - int _precadProcess3DTopology = BLSURFPlugin_Hypothesis::GetDefaultPreCADProcess3DTopology(); - int _precadDiscardInput = BLSURFPlugin_Hypothesis::GetDefaultPreCADDiscardInput(); + //int _precadMergeEdges = BLSURFPlugin_Hypothesis::GetDefaultPreCADMergeEdges(); + //int _precadRemoveDuplicateCADFaces = BLSURFPlugin_Hypothesis::GetDefaultPreCADRemoveDuplicateCADFaces(); + //int _precadProcess3DTopology = BLSURFPlugin_Hypothesis::GetDefaultPreCADProcess3DTopology(); + //int _precadDiscardInput = BLSURFPlugin_Hypothesis::GetDefaultPreCADDiscardInput(); + const BLSURFPlugin_Hypothesis::TPreCadPeriodicityVector preCadFacesPeriodicityVector = BLSURFPlugin_Hypothesis::GetPreCadFacesPeriodicityVector(hyp); if (hyp) { - MESSAGE("BLSURFPlugin_BLSURF::SetParameters"); _physicalMesh = (int) hyp->GetPhysicalMesh(); _geometricMesh = (int) hyp->GetGeometricMesh(); if (hyp->GetPhySize() > 0) { @@ -988,9 +912,13 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, // if max size is not explicitly specified, "relative" flag is ignored _maxSizeRel = hyp->IsMaxSizeRel(); } - if (hyp->GetGradation() > 0) + _use_gradation = hyp->GetUseGradation(); + if (hyp->GetGradation() > 0 && _use_gradation) _gradation = hyp->GetGradation(); - _quadAllowed = hyp->GetQuadAllowed(); + _use_volume_gradation = hyp->GetUseVolumeGradation(); + if (hyp->GetVolumeGradation() > 0 && _use_volume_gradation ) + _volume_gradation = hyp->GetVolumeGradation(); + _elementType = hyp->GetElementType(); if (hyp->GetAngleMesh() > 0) _angleMesh = hyp->GetAngleMesh(); if (hyp->GetChordalError() > 0) @@ -1001,71 +929,71 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, _removeTinyEdges = hyp->GetRemoveTinyEdges(); if (hyp->GetTinyEdgeLength() > 0) _tinyEdgeLength = hyp->GetTinyEdgeLength(); + _optimiseTinyEdges = hyp->GetOptimiseTinyEdges(); + if (hyp->GetTinyEdgeOptimisationLength() > 0) + _tinyEdgeOptimisLength = hyp->GetTinyEdgeOptimisationLength(); + _correctSurfaceIntersec = hyp->GetCorrectSurfaceIntersection(); + if (hyp->GetCorrectSurfaceIntersectionMaxCost() > 0) + _corrSurfaceIntersCost = hyp->GetCorrectSurfaceIntersectionMaxCost(); _badElementRemoval = hyp->GetBadElementRemoval(); if (hyp->GetBadElementAspectRatio() >= 0) _badElementAspectRatio = hyp->GetBadElementAspectRatio(); _optimizeMesh = hyp->GetOptimizeMesh(); _quadraticMesh = hyp->GetQuadraticMesh(); _verb = hyp->GetVerbosity(); - _topology = (int) hyp->GetTopology(); + //_topology = (int) hyp->GetTopology(); // PreCAD - _precadMergeEdges = hyp->GetPreCADMergeEdges(); - _precadProcess3DTopology = hyp->GetPreCADProcess3DTopology(); - _precadDiscardInput = hyp->GetPreCADDiscardInput(); + //_precadMergeEdges = hyp->GetPreCADMergeEdges(); + //_precadRemoveDuplicateCADFaces = hyp->GetPreCADRemoveDuplicateCADFaces(); + //_precadProcess3DTopology = hyp->GetPreCADProcess3DTopology(); + //_precadDiscardInput = hyp->GetPreCADDiscardInput(); + _useSurfaceProximity = hyp->GetUseSurfaceProximity (); + _nbSurfaceProximityLayers = hyp->GetNbSurfaceProximityLayers(); + _surfaceProximityRatio = hyp->GetSurfaceProximityRatio (); + _useVolumeProximity = hyp->GetUseVolumeProximity (); + _nbVolumeProximityLayers = hyp->GetNbVolumeProximityLayers (); + _volumeProximityRatio = hyp->GetVolumeProximityRatio (); + const BLSURFPlugin_Hypothesis::TOptionValues& opts = hyp->GetOptionValues(); BLSURFPlugin_Hypothesis::TOptionValues::const_iterator opIt; - for ( opIt = opts.begin(); opIt != opts.end(); ++opIt ) + for ( opIt = opts.begin(); opIt != opts.end(); ++opIt ){ + MESSAGE("OptionValue: " << opIt->first.c_str() << ", value: " << opIt->second.c_str()); if ( !opIt->second.empty() ) { - MESSAGE("cadsurf_set_param(): " << opIt->first << " = " << opIt->second); - set_param(css, opIt->first.c_str(), opIt->second.c_str()); + // With MeshGems 2.4-5, there are issues with periodicity and multithread + // => As a temporary workaround, we enforce to use only one thread if periodicity is used. + if (opIt->first == "max_number_of_threads" && opIt->second != "1" && ! preCadFacesPeriodicityVector.empty()){ + std::cout << "INFO: Disabling multithread to avoid periodicity issues" << std::endl; + set_param(css, opIt->first.c_str(), "1"); + } + else + set_param(css, opIt->first.c_str(), opIt->second.c_str()); } + } const BLSURFPlugin_Hypothesis::TOptionValues& custom_opts = hyp->GetCustomOptionValues(); for ( opIt = custom_opts.begin(); opIt != custom_opts.end(); ++opIt ) if ( !opIt->second.empty() ) { - MESSAGE("cadsurf_set_param(): " << opIt->first << " = " << opIt->second); set_param(css, opIt->first.c_str(), opIt->second.c_str()); - } + } const BLSURFPlugin_Hypothesis::TOptionValues& preCADopts = hyp->GetPreCADOptionValues(); for ( opIt = preCADopts.begin(); opIt != preCADopts.end(); ++opIt ) if ( !opIt->second.empty() ) { - *use_precad = true; - MESSAGE("precad_set_param(): " << opIt->first << " = " << opIt->second); - precad_set_param(pcs, opIt->first.c_str(), opIt->second.c_str()); - } - - const BLSURFPlugin_Hypothesis::TOptionValues& custom_preCADopts = hyp->GetCustomPreCADOptionValues(); - for ( opIt = custom_preCADopts.begin(); opIt != custom_preCADopts.end(); ++opIt ) - if ( !opIt->second.empty() ) { - *use_precad = true; - MESSAGE("precad_set_param(): " << opIt->first << " = " << opIt->second); - precad_set_param(pcs, opIt->first.c_str(), opIt->second.c_str()); + set_param(css, opIt->first.c_str(), opIt->second.c_str()); } } -// else { -// //0020968: EDF1545 SMESH: Problem in the creation of a mesh group on geometry -// // GetDefaultPhySize() sometimes leads to computation failure -// // GDD 26/07/2012 From Distene documentation, global physical size default value = diag/100 -// _phySize = BLSURFPlugin_Hypothesis::GetDefaultPhySize(diagonal); -// _minSize = BLSURFPlugin_Hypothesis::GetDefaultMinSize(diagonal); -// _maxSize = BLSURFPlugin_Hypothesis::GetDefaultMaxSize(diagonal); -// _chordalError = BLSURFPlugin_Hypothesis::GetDefaultChordalError(diagonal); -// _tinyEdgeLength = BLSURFPlugin_Hypothesis::GetDefaultTinyEdgeLength(diagonal); -// MESSAGE("BLSURFPlugin_BLSURF::SetParameters using defaults"); -// } - // PreCAD - if (_topology == BLSURFPlugin_Hypothesis::PreCAD) { - *use_precad = true; - precad_set_param(pcs, "verbose", val_to_string(_verb).c_str()); - precad_set_param(pcs, "merge_edges", _precadMergeEdges ? "1" : "0"); - precad_set_param(pcs, "process_3d_topology", _precadProcess3DTopology ? "1" : "0"); - precad_set_param(pcs, "discard_input_topology", _precadDiscardInput ? "1" : "0"); - } - // unlimit mesh size (issue 0022266) - set_param(css, "max_number_of_points_per_patch", "1000000"); + if ( BLSURFPlugin_Hypothesis::HasPreCADOptions( hyp )) + { + cadsurf_set_param(css, "use_precad", "yes" ); // for old versions + } + // PreProcessor (formerly PreCAD) -- commented params are preCADoptions (since 0023307) + //set_param(css, "merge_edges", _precadMergeEdges ? "yes" : "no"); + //set_param(css, "remove_duplicate_cad_faces", _precadRemoveDuplicateCADFaces ? "yes" : "no"); + //set_param(css, "process_3d_topology", _precadProcess3DTopology ? "1" : "0"); + //set_param(css, "discard_input_topology", _precadDiscardInput ? "1" : "0"); + //set_param(css, "max_number_of_points_per_patch", "1000000"); bool useGradation = false; switch (_physicalMesh) @@ -1073,11 +1001,12 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, case BLSURFPlugin_Hypothesis::PhysicalGlobalSize: set_param(css, "physical_size_mode", "global"); set_param(css, "global_physical_size", _phySizeRel ? val_to_string_rel(_phySize).c_str() : val_to_string(_phySize).c_str()); + //useGradation = true; break; case BLSURFPlugin_Hypothesis::PhysicalLocalSize: set_param(css, "physical_size_mode", "local"); set_param(css, "global_physical_size", _phySizeRel ? val_to_string_rel(_phySize).c_str() : val_to_string(_phySize).c_str()); - useGradation = true; + //useGradation = true; break; default: set_param(css, "physical_size_mode", "none"); @@ -1089,13 +1018,13 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, set_param(css, "geometric_size_mode", "global"); set_param(css, "geometric_approximation", val_to_string(_angleMesh).c_str()); set_param(css, "chordal_error", val_to_string(_chordalError).c_str()); - useGradation = true; + //useGradation = true; break; case BLSURFPlugin_Hypothesis::GeometricalLocalSize: set_param(css, "geometric_size_mode", "local"); set_param(css, "geometric_approximation", val_to_string(_angleMesh).c_str()); set_param(css, "chordal_error", val_to_string(_chordalError).c_str()); - useGradation = true; + //useGradation = true; break; default: set_param(css, "geometric_size_mode", "none"); @@ -1127,11 +1056,30 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, set_param(css, "max_size", _maxSizeRel ? val_to_string_rel(_maxSize).c_str() : val_to_string(_maxSize).c_str()); } // anisotropic and quadrangle mesh requires disabling gradation - if ( _anisotropic && _quadAllowed ) - useGradation = false; // limitation of V1.3 - if ( useGradation ) - set_param(css, "gradation", val_to_string(_gradation).c_str()); - set_param(css, "element_generation", _quadAllowed ? "quad_dominant" : "triangle"); + // if ( _anisotropic && _elementType != BLSURFPlugin_Hypothesis::Triangles ) + // useGradation = false; // limitation of V1.3 + useGradation = true; // bos #18758 + if ( useGradation && _use_gradation ) + set_param(css, "gradation", val_to_string(_gradation).c_str()); + if ( useGradation && _use_volume_gradation ) + set_param(css, "volume_gradation", val_to_string(_volume_gradation).c_str()); + + // New since MeshGems 2.5: add full_quad + const char * element_generation = ""; + switch ( _elementType ) + { + case BLSURFPlugin_Hypothesis::Triangles: + element_generation = "triangle"; + break; + case BLSURFPlugin_Hypothesis::QuadrangleDominant: + element_generation = "quad_dominant"; + break; + case BLSURFPlugin_Hypothesis::Quadrangles: + element_generation = "full_quad"; + break; + default: ; + } + set_param(css, "element_generation", element_generation); set_param(css, "metric", _anisotropic ? "anisotropic" : "isotropic"); @@ -1140,6 +1088,12 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, set_param(css, "remove_tiny_edges", _removeTinyEdges ? "1" : "0"); if ( _removeTinyEdges ) set_param(css, "tiny_edge_length", val_to_string(_tinyEdgeLength).c_str()); + set_param(css, "optimise_tiny_edges", _optimiseTinyEdges ? "1" : "0"); + if ( _optimiseTinyEdges ) + set_param(css, "tiny_edge_optimisation_length", val_to_string(_tinyEdgeOptimisLength).c_str()); + set_param(css, "correct_surface_intersections", _correctSurfaceIntersec ? "1" : "0"); + if ( _correctSurfaceIntersec ) + set_param(css, "surface_intersections_processing_max_cost", val_to_string(_corrSurfaceIntersCost ).c_str()); set_param(css, "force_bad_surface_element_removal", _badElementRemoval ? "1" : "0"); if ( _badElementRemoval ) set_param(css, "bad_surface_element_aspect_ratio", val_to_string(_badElementAspectRatio).c_str()); @@ -1147,26 +1101,37 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, set_param(css, "element_order", _quadraticMesh ? "quadratic" : "linear"); set_param(css, "verbose", val_to_string(_verb).c_str()); + set_param(css, "use_surface_proximity", _useSurfaceProximity ? "yes" : "no" ); + if ( _useSurfaceProximity ) + { + set_param(css, "surface_proximity_layers", SMESH_Comment( _nbSurfaceProximityLayers )); + set_param(css, "surface_proximity_ratio", SMESH_Comment( _surfaceProximityRatio )); + } + set_param(css, "use_volume_proximity", _useVolumeProximity ? "yes" : "no" ); + if ( _useVolumeProximity ) + { + set_param(css, "volume_proximity_layers", SMESH_Comment( _nbVolumeProximityLayers )); + set_param(css, "volume_proximity_ratio", SMESH_Comment( _volumeProximityRatio )); + } + _smp_phy_size = _phySizeRel ? _phySize*diagonal : _phySize; if ( _verb > 0 ) std::cout << "_smp_phy_size = " << _smp_phy_size << std::endl; - if (_physicalMesh == BLSURFPlugin_Hypothesis::PhysicalLocalSize){ + if (_physicalMesh == BLSURFPlugin_Hypothesis::PhysicalLocalSize) + { TopoDS_Shape GeomShape; TopoDS_Shape AttShape; TopAbs_ShapeEnum GeomType; // // Standard Size Maps // - MESSAGE("Setting a Size Map"); const BLSURFPlugin_Hypothesis::TSizeMap sizeMaps = BLSURFPlugin_Hypothesis::GetSizeMapEntries(hyp); BLSURFPlugin_Hypothesis::TSizeMap::const_iterator smIt = sizeMaps.begin(); for ( ; smIt != sizeMaps.end(); ++smIt ) { if ( !smIt->second.empty() ) { - MESSAGE("cadsurf_set_sizeMap(): " << smIt->first << " = " << smIt->second); GeomShape = entryToShape(smIt->first); GeomType = GeomShape.ShapeType(); - MESSAGE("Geomtype is " << GeomType); int key = -1; // Group Management if (GeomType == TopAbs_COMPOUND) { @@ -1179,7 +1144,6 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, } else { key = FacesWithSizeMap.FindIndex(TopoDS::Face(it.Value())); -// MESSAGE("Face with key " << key << " already in map"); } FaceId2SizeMap[key] = smIt->second; } @@ -1192,7 +1156,6 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, } else { key = EdgesWithSizeMap.FindIndex(TopoDS::Edge(it.Value())); -// MESSAGE("Edge with key " << key << " already in map"); } EdgeId2SizeMap[key] = smIt->second; } @@ -1206,9 +1169,7 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, } else { key = VerticesWithSizeMap.FindIndex(TopoDS::Vertex(it.Value())); - MESSAGE("Group of vertices with key " << key << " already in map"); } - MESSAGE("Group of vertices with key " << key << " has a size map: " << smIt->second); VertexId2SizeMap[key] = smIt->second; } } @@ -1221,7 +1182,6 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, } else { key = FacesWithSizeMap.FindIndex(TopoDS::Face(GeomShape)); -// MESSAGE("Face with key " << key << " already in map"); } FaceId2SizeMap[key] = smIt->second; } @@ -1234,7 +1194,6 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, } else { key = EdgesWithSizeMap.FindIndex(TopoDS::Edge(GeomShape)); -// MESSAGE("Edge with key " << key << " already in map"); } EdgeId2SizeMap[key] = smIt->second; } @@ -1248,9 +1207,7 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, } else { key = VerticesWithSizeMap.FindIndex(TopoDS::Vertex(GeomShape)); - MESSAGE("Vertex with key " << key << " already in map"); } - MESSAGE("Vertex with key " << key << " has a size map: " << smIt->second); VertexId2SizeMap[key] = smIt->second; } } @@ -1260,13 +1217,11 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, // Attractors // // TODO appeler le constructeur des attracteurs directement ici - MESSAGE("Setting Attractors"); // if ( !_phySizeRel ) { const BLSURFPlugin_Hypothesis::TSizeMap attractors = BLSURFPlugin_Hypothesis::GetAttractorEntries(hyp); BLSURFPlugin_Hypothesis::TSizeMap::const_iterator atIt = attractors.begin(); for ( ; atIt != attractors.end(); ++atIt ) { if ( !atIt->second.empty() ) { - MESSAGE("cadsurf_set_attractor(): " << atIt->first << " = " << atIt->second); GeomShape = entryToShape(atIt->first); GeomType = GeomShape.ShapeType(); // Group Management @@ -1299,8 +1254,6 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, } } // } -// else -// MESSAGE("Impossible to create the attractors when the physical size is relative"); // Class Attractors // temporary commented out for testing @@ -1319,7 +1272,6 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, BLSURFPlugin_Hypothesis::TAttractorMap::const_iterator AtIt = class_attractors.begin(); for ( ; AtIt != class_attractors.end(); ++AtIt ) { if ( !AtIt->second->Empty() ) { - // MESSAGE("cadsurf_set_attractor(): " << AtIt->first << " = " << AtIt->second); GeomShape = entryToShape(AtIt->first); if ( !SMESH_MesherHelper::IsSubShape( GeomShape, theGeomShape )) continue; @@ -1358,15 +1310,18 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, // // Enforced Vertices // - MESSAGE("Setting Enforced Vertices"); const BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexListMap entryEnfVertexListMap = BLSURFPlugin_Hypothesis::GetAllEnforcedVerticesByFace(hyp); BLSURFPlugin_Hypothesis::TFaceEntryEnfVertexListMap::const_iterator enfIt = entryEnfVertexListMap.begin(); for ( ; enfIt != entryEnfVertexListMap.end(); ++enfIt ) { if ( !enfIt->second.empty() ) { GeomShape = entryToShape(enfIt->first); - GeomType = GeomShape.ShapeType(); + if ( GeomShape.IsNull() ) + { + createEnforcedVertexOnFace( GeomShape, enfIt->second ); + } // Group Management - if (GeomType == TopAbs_COMPOUND){ + else if ( GeomShape.ShapeType() == TopAbs_COMPOUND) + { for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()){ if (it.Value().ShapeType() == TopAbs_FACE){ HasSizeMapOnFace = true; @@ -1374,8 +1329,8 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, } } } - - if (GeomType == TopAbs_FACE){ + else if ( GeomShape.ShapeType() == TopAbs_FACE) + { HasSizeMapOnFace = true; createEnforcedVertexOnFace(GeomShape, enfIt->second); } @@ -1386,11 +1341,9 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, bool useInternalVertexAllFaces = BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFaces(hyp); if (useInternalVertexAllFaces) { std::string grpName = BLSURFPlugin_Hypothesis::GetInternalEnforcedVertexAllFacesGroup(hyp); - MESSAGE("Setting Internal Enforced Vertices"); gp_Pnt aPnt; TopExp_Explorer exp (theGeomShape, TopAbs_FACE); for (; exp.More(); exp.Next()){ - MESSAGE("Iterating shapes. Shape type is " << exp.Current().ShapeType()); TopExp_Explorer exp_face (exp.Current(), TopAbs_VERTEX, TopAbs_EDGE); for (; exp_face.More(); exp_face.Next()) { @@ -1398,7 +1351,6 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, // Check if current coords is already in enfVertexList // If coords not in enfVertexList, add new enfVertex aPnt = BRep_Tool::Pnt(TopoDS::Vertex(exp_face.Current())); - MESSAGE("Found vertex on face at " << aPnt.X() <<", "<coords.push_back(aPnt.X()); enfVertex->coords.push_back(aPnt.Y()); @@ -1414,37 +1366,13 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, } } - MESSAGE("Setting Size Map on FACES "); -// #if BLSURF_VERSION_LONG < "3.1.1" - cadsurf_data_set_sizemap_iso_cad_face(css, size_on_surface, &_smp_phy_size); -// #else -// if (*use_precad) -// iso_sizemap_f = sizemap_new(c, distene_sizemap_type_iso_cad_face, (void *)size_on_surface, NULL); -// else -// clean_iso_sizemap_f = sizemap_new(c, distene_sizemap_type_iso_cad_face, (void *)size_on_surface, NULL); -// #endif + cadsurf_set_sizemap_iso_cad_face(css, size_on_surface, &_smp_phy_size); if (HasSizeMapOnEdge){ - MESSAGE("Setting Size Map on EDGES "); -// #if BLSURF_VERSION_LONG < "3.1.1" - cadsurf_data_set_sizemap_iso_cad_edge(css, size_on_edge, &_smp_phy_size); -// #else -// if (*use_precad) -// iso_sizemap_e = sizemap_new(c, distene_sizemap_type_iso_cad_edge, (void *)size_on_edge, NULL); -// else -// clean_iso_sizemap_e = sizemap_new(c, distene_sizemap_type_iso_cad_edge, (void *)size_on_edge, NULL); -// #endif + cadsurf_set_sizemap_iso_cad_edge(css, size_on_edge, &_smp_phy_size); } if (HasSizeMapOnVertex){ - MESSAGE("Setting Size Map on VERTICES "); -// #if BLSURF_VERSION_LONG < "3.1.1" - cadsurf_data_set_sizemap_iso_cad_point(css, size_on_vertex, &_smp_phy_size); -// #else -// if (*use_precad) -// iso_sizemap_p = sizemap_new(c, distene_sizemap_type_iso_cad_point, (void *)size_on_vertex, NULL); -// else -// clean_iso_sizemap_p = sizemap_new(c, distene_sizemap_type_iso_cad_point, (void *)size_on_vertex, NULL); -// #endif + cadsurf_set_sizemap_iso_cad_point(css, size_on_vertex, &_smp_phy_size); } } @@ -1453,66 +1381,16 @@ void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, // reset vectors _preCadFacesIDsPeriodicityVector.clear(); _preCadEdgesIDsPeriodicityVector.clear(); - _facesIDsPeriodicityVector.clear(); - _edgesIDsPeriodicityVector.clear(); - _verticesIDsPeriodicityVector.clear(); - - MESSAGE("SetParameters preCadFacesPeriodicityVector"); - const BLSURFPlugin_Hypothesis::TPreCadPeriodicityVector preCadFacesPeriodicityVector = BLSURFPlugin_Hypothesis::GetPreCadFacesPeriodicityVector(hyp); for (std::size_t i = 0; igetIdInShape() < n2->getIdInShape(); - // SMDS_TypeOfPosition pos1 = n1->GetPosition()->GetTypeOfPosition(); - // SMDS_TypeOfPosition pos2 = n2->GetPosition()->GetTypeOfPosition(); - // if ( pos1 == pos2 ) return 0; - // if ( pos1 < pos2 || pos1 == SMDS_TOP_3DSPACE ) return 1; - // return -1; + //return n1->getIdInShape() < n2->getIdInShape(); + return n1->GetID() < n2->GetID(); // earlier created nodes have less IDs } // sort sub-meshes in order: EDGE, VERTEX bool operator()( const SMESHDS_SubMesh* s1, const SMESHDS_SubMesh* s2 ) const @@ -1667,11 +1537,10 @@ namespace } case TopAbs_EDGE: { std::multimap< double, const SMDS_MeshNode* > u2node; - const SMDS_EdgePosition* ePos; while ( nIt->more() ) { const SMDS_MeshNode* n = nIt->next(); - if (( ePos = dynamic_cast< const SMDS_EdgePosition* >( n->GetPosition() ))) + if ( SMDS_EdgePositionPtr ePos = n->GetPosition() ) u2node.insert( make_pair( ePos->GetUParameter(), n )); } if ( u2node.size() < 2 ) return; @@ -1679,7 +1548,7 @@ namespace //double tol = (( u2node.rbegin()->first - u2node.begin()->first ) / 20.) / u2node.size(); Standard_Real f,l; BRep_Tool::Range( TopoDS::Edge( shape ), f,l ); - double tol = (( l - f ) / 20.) / u2node.size(); + double tol = (( l - f ) / 10.) / u2node.size(); // 10. - adjusted for #17262 std::multimap< double, const SMDS_MeshNode* >::iterator un2, un1; for ( un2 = u2node.begin(), un1 = un2++; un2 != u2node.end(); un1 = un2++ ) @@ -1744,12 +1613,17 @@ namespace const TopoDS_Face& makeProxyFace( SMESH_ProxyMesh::Ptr& viscousMesh, const TopoDS_Face& origFace) { - // get data of nodes on inner boundary of viscous layers SMESH_Mesh* origMesh = viscousMesh->GetMesh(); + + SMESH_MesherHelper helper( *origMesh ); + helper.SetSubShape( origFace ); + const bool hasSeam = helper.HasRealSeam(); + + // get data of nodes on inner boundary of viscous layers TError err; TSideVector wireVec = StdMeshers_FaceSide::GetFaceWires(origFace, *origMesh, /*skipMediumNodes = */true, - err, viscousMesh ); + err, &helper, viscousMesh ); if ( err && err->IsKO() ) throw *err.get(); // it should be caught at SMESH_subMesh @@ -1758,27 +1632,34 @@ namespace std::vector tmpVertex; // create a proxy FACE - TopoDS_Shape origFaceCopy = origFace.EmptyCopied(); - BRepBuilderAPI_MakeFace newFace( TopoDS::Face( origFaceCopy )); + TopoDS_Face origFaceCopy = TopoDS::Face( origFace.EmptyCopied() ); + BRepBuilderAPI_MakeFace newFace( origFaceCopy ); + bool hasPCurves = false; for ( size_t iW = 0; iW != wireVec.size(); ++iW ) { StdMeshers_FaceSidePtr& wireData = wireVec[iW]; - const UVPtStructVec& wirePoints = wireData->GetUVPtStruct(); + const UVPtStructVec& wirePoints = wireData->GetUVPtStruct(); if ( wirePoints.size() < 3 ) continue; - BRepBuilderAPI_MakePolygon wire; + BRepBuilderAPI_MakePolygon polygon; const size_t i0 = tmpVertex.size(); - for ( size_t iN = 1; iN < wirePoints.size(); ++iN ) + for ( size_t iN = 0; iN < wirePoints.size(); ++iN ) { - wire.Add( SMESH_TNodeXYZ( wirePoints[ iN ].node )); + polygon.Add( SMESH_TNodeXYZ( wirePoints[ iN ].node )); origNodes.push_back( wirePoints[ iN ].node ); - tmpVertex.push_back( wire.LastVertex() ); + tmpVertex.push_back( polygon.LastVertex() ); + + // check presence of a pcurve + checkPCurve( polygon, origFaceCopy, hasPCurves, &wirePoints[ iN-1 ] ); } - tmpVertex[ i0 ] = wire.FirstVertex(); // wire.LastVertex()==NULL for 1 vertex in wire - wire.Close(); - if ( !wire.IsDone() ) + tmpVertex[ i0 ] = polygon.FirstVertex(); // polygon.LastVertex()==NULL for 1 vertex in wire + polygon.Close(); + if ( !polygon.IsDone() ) throw SALOME_Exception("BLSURFPlugin_BLSURF: BRepBuilderAPI_MakePolygon failed"); + TopoDS_Wire wire = polygon; + if ( hasSeam ) + wire = updateSeam( wire, origNodes ); newFace.Add( wire ); } _proxyFace = newFace; @@ -1792,9 +1673,6 @@ namespace ShapeToMesh( auxCompoundToMesh ); - //TopExp_Explorer fExp( auxCompoundToMesh, TopAbs_FACE ); - //_proxyFace = TopoDS::Face( fExp.Current() ); - // Make input mesh for MG-CADSurf: segments on EDGE's of newFace @@ -1806,8 +1684,8 @@ namespace GetSubMesh( tmpVertex[i] )->ComputeStateEngine( SMESH_subMesh::COMPUTE ); if ( const SMDS_MeshNode* tmpN = SMESH_Algo::VertexNode( tmpVertex[i], tmpMeshDS )) _tmp2origNN.insert( _tmp2origNN.end(), make_pair( tmpN, origNodes[i] )); - else - throw SALOME_Exception("BLSURFPlugin_BLSURF: a proxy vertex not meshed"); + // else -- it can be a seam vertex replaced by updateSeam() + // throw SALOME_Exception("BLSURFPlugin_BLSURF: a proxy vertex not meshed"); } // make segments @@ -1826,6 +1704,69 @@ namespace return _proxyFace; } + //-------------------------------------------------------------------------------- + /*! + * \brief Add pcurve to the last edge of a wire + */ + //-------------------------------------------------------------------------------- + + void checkPCurve( BRepBuilderAPI_MakePolygon& wire, + const TopoDS_Face& face, + bool & hasPCurves, + const uvPtStruct * wirePoints ) + { + if ( hasPCurves ) + return; + TopoDS_Edge edge = wire.Edge(); + if ( edge.IsNull() ) return; + double f,l; + if ( BRep_Tool::CurveOnSurface(edge, face, f, l)) + { + hasPCurves = true; + return; + } + gp_XY p1 = wirePoints[ 0 ].UV(), p2 = wirePoints[ 1 ].UV(); + Handle(Geom2d_Line) pcurve = new Geom2d_Line( p1, gp_Dir2d( p2 - p1 )); + BRep_Builder().UpdateEdge( edge, Handle(Geom_Curve)(), Precision::Confusion() ); + BRep_Builder().UpdateEdge( edge, pcurve, face, Precision::Confusion() ); + BRep_Builder().Range( edge, 0, ( p2 - p1 ).Modulus() ); + // cout << "n1 = mesh.AddNode( " << p1.X()*10 << ", " << p1.Y() << ", 0 )" << endl + // << "n2 = mesh.AddNode( " << p2.X()*10 << ", " << p2.Y() << ", 0 )" << endl + // << "mesh.AddEdge( [ n1, n2 ] )" << endl; + } + + //-------------------------------------------------------------------------------- + /*! + * \brief Replace coincident EDGEs with reversed copies. + */ + //-------------------------------------------------------------------------------- + + TopoDS_Wire updateSeam( const TopoDS_Wire& wire, + const std::vector& nodesOfVertices ) + { + BRepBuilderAPI_MakeWire newWire; + + typedef NCollection_DataMap TSeg2EdgeMap; + TSeg2EdgeMap seg2EdgeMap; + + TopoDS_Iterator edgeIt( wire ); + for ( int iSeg = 1; edgeIt.More(); edgeIt.Next(), ++iSeg ) + { + SMESH_TLink link( nodesOfVertices[ iSeg-1 ], nodesOfVertices[ iSeg ]); + TopoDS_Edge edge( TopoDS::Edge( edgeIt.Value() )); + + TopoDS_Edge* edgeInMap = seg2EdgeMap.Bound( link, edge ); + bool isSeam = ( *edgeInMap != edge ); + if ( isSeam ) + { + edgeInMap->Reverse(); + edge = *edgeInMap; + } + newWire.Add( edge ); + } + return newWire; + } + //-------------------------------------------------------------------------------- /*! * \brief Fill in the origMesh with faces computed by MG-CADSurf in this tmp mesh @@ -1846,7 +1787,7 @@ namespace const SMDS_MeshNode* nodes[27]; const SMDS_MeshNode* nullNode = 0; double xyz[3]; - SMDS_FaceIteratorPtr fIt = GetMeshDS()->facesIterator(/*idInceasingOrder=*/true); + SMDS_FaceIteratorPtr fIt = GetMeshDS()->facesIterator(); while ( fIt->more() ) { const SMDS_MeshElement* f = fIt->next(); @@ -1855,7 +1796,7 @@ namespace for ( ; nIt->more(); ++nbN ) { const SMDS_MeshNode* n = static_cast( nIt->next() ); - TN2NMap::iterator n2nIt = + TN2NMap::iterator n2nIt = _tmp2origNN.insert( _tmp2origNN.end(), make_pair( n, nullNode )); if ( !n2nIt->second ) { n->GetXYZ( xyz ); @@ -1866,8 +1807,8 @@ namespace } switch( nbN ) { case 3: helper.AddFace( nodes[0], nodes[1], nodes[2] ); break; - // case 6: helper.AddFace( nodes[0], nodes[1], nodes[2], - // nodes[3], nodes[4], nodes[5]); break; + // case 6: helper.AddFace( nodes[0], nodes[1], nodes[2], + // nodes[3], nodes[4], nodes[5]); break; case 4: helper.AddFace( nodes[0], nodes[1], nodes[2], nodes[3] ); break; // case 9: helper.AddFace( nodes[0], nodes[1], nodes[2], nodes[3], // nodes[4], nodes[5], nodes[6], nodes[7], nodes[8]); break; @@ -1888,7 +1829,6 @@ namespace double * _progress; }; - } // namespace status_t curv_fun(real t, real *uv, real *dt, real *dtt, void *user_data); @@ -1903,19 +1843,22 @@ status_t interrupt_cb(integer *interrupt_status, void *user_data); */ //============================================================================= -bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { - - MESSAGE("BLSURFPlugin_BLSURF::Compute"); - +bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) +{ // Fix problem with locales Kernel_Utils::Localizer aLocalizer; this->SMESH_Algo::_progress = 1e-3; // prevent progress advancment while computing attractors - if ( !compute( aMesh, aShape, /*allowSubMeshClearing=*/true )) - return false; + bool viscousLayersMade = + ( aShape.ShapeType() == TopAbs_FACE && + StdMeshers_ViscousLayers2D::HasProxyMesh( TopoDS::Face( aShape ), aMesh )); + + if ( !viscousLayersMade ) + if ( !compute( aMesh, aShape, /*allowSubMeshClearing=*/true )) + return false; - if ( _haveViscousLayers ) + if ( _haveViscousLayers || viscousLayersMade ) { // Compute viscous layers @@ -1969,12 +1912,12 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, /* create a distene context (generic object) */ status_t status = STATUS_ERROR; - myMesh = &aMesh; SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - SMESH_MesherHelper helper( aMesh ); + SMESH_MesherHelper helper( aMesh ), helperWithShape( aMesh ); + myHelper = theHelper = & helperWithShape; // do not call helper.IsQuadraticSubMesh() because sub-meshes // may be cleaned and helper.myTLinkNodeMap gets invalid in such a case - bool haveQuadraticSubMesh = SMESH_MesherHelper( aMesh ).IsQuadraticSubMesh( aShape ); + bool haveQuadraticSubMesh = helperWithShape.IsQuadraticSubMesh( aShape ); bool quadraticSubMeshAndViscousLayer = false; bool needMerge = false; typedef set< SMESHDS_SubMesh*, ShapeTypeCompare > TSubMeshSet; @@ -1983,6 +1926,9 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, TopTools_IndexedMapOfShape pmap, emap, fmap; + TopTools_IndexedDataMapOfShapeListOfShape e2ffmap; + TopExp::MapShapesAndAncestors( aShape, TopAbs_EDGE, TopAbs_FACE, e2ffmap ); + // Issue 0019864. On DebianSarge, FE signals do not obey to OSD::SetSignal(false) #ifndef WIN32 feclearexcept( FE_ALL_EXCEPT ); @@ -2007,14 +1953,8 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, cad_t *c = cad_new(ctx); dcad_t *dcad = dcad_new(c); - FacesWithSizeMap.Clear(); - FaceId2SizeMap.clear(); - FaceId2ClassAttractor.clear(); - FaceIndex2ClassAttractor.clear(); - EdgesWithSizeMap.Clear(); - EdgeId2SizeMap.clear(); - VerticesWithSizeMap.Clear(); - VertexId2SizeMap.clear(); + // To enable multithreading + cad_set_thread_safety(c, 1); /* Now fill the CAD object with data from your CAD * environement. This is the most complex part of a successfull @@ -2022,25 +1962,13 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, */ // PreCAD - // If user requests it, send the CAD through Distene preprocessor : PreCAD - cad_t *cleanc = NULL; // preprocessed cad - dcad_t *cleandc = NULL; // preprocessed dcad - precad_session_t *pcs = precad_session_new(ctx); - // Give both dcad and cad to precad - precad_data_set_dcad(pcs, dcad); - precad_data_set_cad(pcs, c); cadsurf_session_t *css = cadsurf_session_new(ctx); // an object that correctly deletes all cadsurf objects at destruction - BLSURF_Cleaner cleaner( ctx,css,c,dcad,cleanc,cleandc ); + BLSURF_Cleaner cleaner( ctx,css,c,dcad ); - MESSAGE("BEGIN SetParameters"); - bool use_precad = false; - SetParameters(_hypothesis, css, pcs, aShape, &use_precad); - MESSAGE("END SetParameters"); - - MESSAGE("_preCadFacesIDsPeriodicityVector.size() = " << _preCadFacesIDsPeriodicityVector.size()); + SetParameters(_hypothesis, css, aShape); haveQuadraticSubMesh = haveQuadraticSubMesh || (_hypothesis != NULL && _hypothesis->GetQuadraticMesh()); helper.SetIsQuadratic( haveQuadraticSubMesh ); @@ -2092,10 +2020,6 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, f.Orientation(TopAbs_FORWARD); iface = fmap.Add(f); -// std::string aFileName = "fmap_face_"; -// aFileName.append(val_to_string(iface)); -// aFileName.append(".brep"); -// BRepTools::Write(f,aFileName.c_str()); surfaces.push_back(BRep_Tool::Surface(f)); @@ -2105,11 +2029,12 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, * (For this face, it will be called by cadsurf with your_face_object_ptr * as last parameter. */ - cad_face_t *fce = cad_face_new(c, iface, surf_fun, surfaces.back()); + cad_face_t *fce = cad_face_new(c, iface, surf_fun, surfaces.back().get()); /* by default a face has no tag (color). The following call sets it to the same value as the Geom module ID : */ - const int faceTag = meshDS->ShapeToIndex(f); + int faceTag = meshDS->ShapeToIndex(f); + faceTag = BLSURFPlugin_Hypothesis::GetHyperPatchTag( faceTag, _hypothesis ); cad_face_set_tag(fce, faceTag); /* Set face orientation (optional if you want a well oriented output mesh)*/ @@ -2126,8 +2051,8 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, faceKey = FacesWithSizeMap.FindIndex(f); - if (FaceId2SizeMap.find(faceKey)!=FaceId2SizeMap.end()) { - MESSAGE("A size map is defined on face :"< >::iterator attractor_iter = FaceId2AttractorCoords.begin(); for (; attractor_iter != FaceId2AttractorCoords.end(); ++attractor_iter) { - if (attractor_iter->first == faceKey) { - MESSAGE("Face indice: " << iface); - MESSAGE("Adding attractor"); - + if (attractor_iter->first == faceKey) + { double xyzCoords[3] = {attractor_iter->second[2], attractor_iter->second[3], attractor_iter->second[4]}; - MESSAGE("Check position of vertex =(" << xyzCoords[0] << "," << xyzCoords[1] << "," << xyzCoords[2] << ")"); gp_Pnt P(xyzCoords[0],xyzCoords[1],xyzCoords[2]); BRepClass_FaceClassifier scl(f,P,1e-7); - // OCC 6.3sp6 : scl.Perform() is bugged. The function was rewritten - // BRepClass_FaceClassifierPerform(&scl,f,P,1e-7); - // OCC 6.5.2: scl.Perform() is not bugged anymore scl.Perform(f, P, 1e-7); TopAbs_State result = scl.State(); - MESSAGE("Position of point on face: "<second[0],attractor_iter->second[1]}; ienf++; - MESSAGE("Add cad point on (u,v)=(" << uvCoords[0] << "," << uvCoords[1] << ") with id = " << ienf); cad_point_t* point_p = cad_point_new(fce, ienf, uvCoords); cad_point_set_tag(point_p, ienf); } @@ -2190,8 +2106,6 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, // ----------------- TId2ClsAttractorVec::iterator clAttractor_iter = FaceId2ClassAttractor.find(faceKey); if (clAttractor_iter != FaceId2ClassAttractor.end()){ - MESSAGE("Face indice: " << iface); - MESSAGE("Adding attractor"); std::vector< BLSURFPlugin_Attractor* > & attVec = clAttractor_iter->second; for ( size_t i = 0; i < attVec.size(); ++i ) if ( !attVec[i]->IsMapBuilt() ) { @@ -2203,83 +2117,44 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, } } // if (HasSizeMapOnFace && !use_precad) - // ------------------ - // Enforced Vertices - // ------------------ + // ------------------ + // Enforced Vertices + // ------------------ faceKey = FacesWithEnforcedVertices.FindIndex(f); std::map::const_iterator evmIt = FaceId2EnforcedVertexCoords.find(faceKey); - if (evmIt != FaceId2EnforcedVertexCoords.end()) { - MESSAGE("Some enforced vertices are defined"); - BLSURFPlugin_Hypothesis::TEnfVertexCoordsList evl; - MESSAGE("Face indice: " << iface); - MESSAGE("Adding enforced vertices"); - evl = evmIt->second; - MESSAGE("Number of vertices to add: "<< evl.size()); + if (evmIt != FaceId2EnforcedVertexCoords.end()) + { + BLSURFPlugin_Hypothesis::TEnfVertexCoordsList evl = evmIt->second; BLSURFPlugin_Hypothesis::TEnfVertexCoordsList::const_iterator evlIt = evl.begin(); - for (; evlIt != evl.end(); ++evlIt) { + for (; evlIt != evl.end(); ++evlIt) + { + double uvCoords[2] = { evlIt->at(0), evlIt->at(1) }; + ienf++; + cad_point_t* point_p = cad_point_new(fce, ienf, uvCoords); + int tag = 0; BLSURFPlugin_Hypothesis::TEnfVertexCoords xyzCoords; xyzCoords.push_back(evlIt->at(2)); xyzCoords.push_back(evlIt->at(3)); xyzCoords.push_back(evlIt->at(4)); - MESSAGE("Check position of vertex =(" << xyzCoords[0] << "," << xyzCoords[1] << "," << xyzCoords[2] << ")"); - gp_Pnt P(xyzCoords[0],xyzCoords[1],xyzCoords[2]); - BRepClass_FaceClassifier scl(f,P,1e-7); - // OCC 6.3sp6 : scl.Perform() is bugged. The function was rewritten - // BRepClass_FaceClassifierPerform(&scl,f,P,1e-7); - // OCC 6.5.2: scl.Perform() is not bugged anymore - scl.Perform(f, P, 1e-7); - TopAbs_State result = scl.State(); - MESSAGE("Position of point on face: "<::const_iterator enfCoordsIt = EnfVertexCoords2EnfVertexList.find(xyzCoords); + if (enfCoordsIt != EnfVertexCoords2EnfVertexList.end() && + !enfCoordsIt->second.empty() ) { - // Point is inside face and not on border - MESSAGE("Point is in face: node is created"); - double uvCoords[2] = {evlIt->at(0),evlIt->at(1)}; - ienf++; - MESSAGE("Add cad point on (u,v)=(" << uvCoords[0] << "," << uvCoords[1] << ") with id = " << ienf); - cad_point_t* point_p = cad_point_new(fce, ienf, uvCoords); - int tag = 0; - std::map< BLSURFPlugin_Hypothesis::TEnfVertexCoords, BLSURFPlugin_Hypothesis::TEnfVertexList >::const_iterator enfCoordsIt = EnfVertexCoords2EnfVertexList.find(xyzCoords); - if (enfCoordsIt != EnfVertexCoords2EnfVertexList.end() && - !enfCoordsIt->second.empty() ) + // to merge nodes of an INTERNAL vertex belonging to several faces + TopoDS_Vertex v = (*enfCoordsIt->second.begin() )->vertex; + if ( v.IsNull() ) v = (*enfCoordsIt->second.rbegin())->vertex; + if ( !v.IsNull() && meshDS->ShapeToIndex( v ) > 0 ) { - // to merge nodes of an INTERNAL vertex belonging to several faces - TopoDS_Vertex v = (*enfCoordsIt->second.begin())->vertex; - if ( v.IsNull() ) v = (*enfCoordsIt->second.rbegin())->vertex; - if ( !v.IsNull() ) { - tag = pmap.Add( v ); - SMESH_subMesh* vSM = aMesh.GetSubMesh( v ); - vSM->ComputeStateEngine( SMESH_subMesh::COMPUTE ); - mergeSubmeshes.insert( vSM->GetSubMeshDS() ); - // //if ( tag != pmap.Extent() ) - // needMerge = true; - } + tag = pmap.Add( v ); + SMESH_subMesh* vSM = aMesh.GetSubMesh( v ); + vSM->ComputeStateEngine( SMESH_subMesh::COMPUTE ); + mergeSubmeshes.insert( vSM->GetSubMeshDS() ); + // //if ( tag != pmap.Extent() ) + // needMerge = true; } - if ( tag == 0 ) tag = ienf; - cad_point_set_tag(point_p, tag); } + if ( tag == 0 ) tag = ienf; + cad_point_set_tag(point_p, tag); } FaceId2EnforcedVertexCoords.erase(faceKey); @@ -2297,18 +2172,13 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, if (ic <= 0) ic = emap.Add(e); -// std::string aFileName = "fmap_edge_"; -// aFileName.append(val_to_string(ic)); -// aFileName.append(".brep"); -// BRepTools::Write(e,aFileName.c_str()); - double tmin,tmax; curves.push_back(BRep_Tool::CurveOnSurface(e, f, tmin, tmax)); if (HasSizeMapOnEdge){ edgeKey = EdgesWithSizeMap.FindIndex(e); - if (EdgeId2SizeMap.find(edgeKey)!=EdgeId2SizeMap.end()) { - MESSAGE("Sizemap defined on edge with index " << edgeKey); + if (EdgeId2SizeMap.find(edgeKey)!=EdgeId2SizeMap.end()) + { theSizeMapStr = EdgeId2SizeMap[edgeKey]; if (theSizeMapStr.find(bad_end) == (theSizeMapStr.size()-bad_end.size()-1)) continue; @@ -2360,11 +2230,30 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, } /* attach the edge to the current cadsurf face */ - cad_edge_t *edg = cad_edge_new(fce, ic, tmin, tmax, curv_fun, curves.back()); + cad_edge_t *edg = cad_edge_new(fce, ic, tmin, tmax, curv_fun, curves.back().get()); /* by default an edge has no tag (color). The following call sets it to the same value as the edge_id : */ - cad_edge_set_tag(edg, ic); + // IMP23368. Do not set tag to an EDGE shared by FACEs of a hyper-patch + bool isInHyperPatch = false; + { + std::set< int > faceTags, faceIDs; + TopTools_ListIteratorOfListOfShape fIt( e2ffmap.FindFromKey( e )); + for ( ; fIt.More(); fIt.Next() ) + { + int faceTag = meshDS->ShapeToIndex( fIt.Value() ); + if ( !faceIDs.insert( faceTag ).second ) + continue; // a face encounters twice for a seam edge + int hpTag = BLSURFPlugin_Hypothesis::GetHyperPatchTag( faceTag, _hypothesis ); + if ( !faceTags.insert( hpTag ).second ) + { + isInHyperPatch = true; + break; + } + } + } + if ( !isInHyperPatch ) + cad_edge_set_tag(edg, ic); /* by default, an edge does not necessalry appear in the resulting mesh, unless the following property is set : @@ -2397,8 +2286,16 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, // << "\t uv = ( " << uv[0] << ","<< uv[1] << " ) " // << "\t u = " << nData.param // << "\t ID = " << nData.node->GetID() << endl; - dcad_edge_discretization_set_vertex_coordinates( dedge, iN+1, t, uv, nXYZ._xyz ); + dcad_edge_discretization_set_vertex_coordinates( dedge, iN+1, t, uv, nXYZ.ChangeData() ); } + TopoDS_Shape v = helper.GetSubShapeByNode( nodeDataVec[0].node, meshDS ); + if ( !v.IsNull() && v.ShapeType() == TopAbs_VERTEX ) + dcad_edge_discretization_set_vertex_tag( dedge, 1, pmap.Add( v )); + + v = helper.GetSubShapeByNode( nodeDataVec.back().node, meshDS ); + if ( !v.IsNull() && v.ShapeType() == TopAbs_VERTEX ) + dcad_edge_discretization_set_vertex_tag( dedge, nbNodes, pmap.Add( v )); + dcad_edge_discretization_set_property(dedge, DISTENE_DCAD_PROPERTY_REQUIRED); } @@ -2440,7 +2337,6 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, vertexKey = VerticesWithSizeMap.FindIndex(v); if (VertexId2SizeMap.find(vertexKey)!=VertexId2SizeMap.end()){ theSizeMapStr = VertexId2SizeMap[vertexKey]; - //MESSAGE("VertexId2SizeMap[faceKey]: " << VertexId2SizeMap[vertexKey]); if (theSizeMapStr.find(bad_end) == (theSizeMapStr.size()-bad_end.size()-1)) continue; // Expr To Python function, verification is performed at validation in GUI @@ -2516,10 +2412,8 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, // PERIODICITY // /////////////////////// - MESSAGE("BEFORE PERIODICITY"); - MESSAGE("_preCadFacesIDsPeriodicityVector.size() = " << _preCadFacesIDsPeriodicityVector.size()); - if (! _preCadFacesIDsPeriodicityVector.empty()) { - MESSAGE("INTO PRECAD FACES PERIODICITY"); + if (! _preCadFacesIDsPeriodicityVector.empty()) + { for (std::size_t i=0; i < _preCadFacesIDsPeriodicityVector.size(); i++){ std::vector theFace1_ids = _preCadFacesIDsPeriodicityVector[i].shape1IDs; std::vector theFace2_ids = _preCadFacesIDsPeriodicityVector[i].shape2IDs; @@ -2533,47 +2427,39 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, for (std::size_t j=0; j < theFace2_ids.size(); j++) o << theFace2_ids[j] << ", "; o << "]"; - MESSAGE(o.str()); - MESSAGE("theFace1_ids.size(): " << theFace1_ids.size()); - MESSAGE("theFace2_ids.size(): " << theFace2_ids.size()); + // if ( _hypothesis->GetVerbosity() > _hypothesis->GetDefaultVerbosity() ) + // cout << o.str() << endl; if (_preCadFacesIDsPeriodicityVector[i].theSourceVerticesCoords.empty()) - { - // If no source points, call peridoicity without transformation function - MESSAGE("periodicity without transformation function"); - meshgems_cad_periodicity_transformation_t periodicity_transformation = NULL; - status = cad_add_face_multiple_periodicity_with_transformation_function(c, theFace1_ids_c, theFace1_ids.size(), - theFace2_ids_c, theFace2_ids.size(), periodicity_transformation, NULL); - if(status != STATUS_OK) - cout << "cad_add_face_multiple_periodicity_with_transformation_function failed with error code " << status << "\n"; - } + { + // If no source points, call periodicity without transformation function + meshgems_cad_periodicity_transformation_t periodicity_transformation = NULL; + status = cad_add_face_multiple_periodicity_with_transformation_function(c, theFace1_ids_c, theFace1_ids.size(), + theFace2_ids_c, theFace2_ids.size(), periodicity_transformation, NULL); + if(status != STATUS_OK) + cout << "cad_add_face_multiple_periodicity_with_transformation_function failed with error code " << status << "\n"; + } else - { - // get the transformation vertices - MESSAGE("periodicity with transformation vertices"); - double* theSourceVerticesCoords_c = &_preCadFacesIDsPeriodicityVector[i].theSourceVerticesCoords[0]; - double* theTargetVerticesCoords_c = &_preCadFacesIDsPeriodicityVector[i].theTargetVerticesCoords[0]; - int nbSourceVertices = _preCadFacesIDsPeriodicityVector[i].theSourceVerticesCoords.size()/3; - int nbTargetVertices = _preCadFacesIDsPeriodicityVector[i].theTargetVerticesCoords.size()/3; - - MESSAGE("nbSourceVertices: " << nbSourceVertices << ", nbTargetVertices: " << nbTargetVertices); - - status = cad_add_face_multiple_periodicity_with_transformation_function_by_points(c, theFace1_ids_c, theFace1_ids.size(), - theFace2_ids_c, theFace2_ids.size(), theSourceVerticesCoords_c, nbSourceVertices, theTargetVerticesCoords_c, nbTargetVertices); - if(status != STATUS_OK) - cout << "cad_add_face_multiple_periodicity_with_transformation_function_by_points failed with error code " << status << "\n"; - } + { + // get the transformation vertices + double* theSourceVerticesCoords_c = &_preCadFacesIDsPeriodicityVector[i].theSourceVerticesCoords[0]; + double* theTargetVerticesCoords_c = &_preCadFacesIDsPeriodicityVector[i].theTargetVerticesCoords[0]; + int nbSourceVertices = _preCadFacesIDsPeriodicityVector[i].theSourceVerticesCoords.size()/3; + int nbTargetVertices = _preCadFacesIDsPeriodicityVector[i].theTargetVerticesCoords.size()/3; + + status = cad_add_face_multiple_periodicity_with_transformation_function_by_points(c, theFace1_ids_c, theFace1_ids.size(), + theFace2_ids_c, theFace2_ids.size(), theSourceVerticesCoords_c, nbSourceVertices, theTargetVerticesCoords_c, nbTargetVertices); + if(status != STATUS_OK) + cout << "cad_add_face_multiple_periodicity_with_transformation_function_by_points failed with error code " << status << "\n"; + } } - - MESSAGE("END PRECAD FACES PERIODICITY"); } - MESSAGE("_preCadEdgesIDsPeriodicityVector.size() = " << _preCadEdgesIDsPeriodicityVector.size()); - if (! _preCadEdgesIDsPeriodicityVector.empty()) { - MESSAGE("INTO PRECAD EDGES PERIODICITY"); + if (! _preCadEdgesIDsPeriodicityVector.empty()) + { for (std::size_t i=0; i < _preCadEdgesIDsPeriodicityVector.size(); i++){ std::vector theEdge1_ids = _preCadEdgesIDsPeriodicityVector[i].shape1IDs; std::vector theEdge2_ids = _preCadEdgesIDsPeriodicityVector[i].shape2IDs; - // Use the address of the first element of the vector to initialise the array + // Use the address of the first element of the vector to initialize the array int* theEdge1_ids_c = &theEdge1_ids[0]; int* theEdge2_ids_c = &theEdge2_ids[0]; @@ -2585,176 +2471,44 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, for (std::size_t j=0; j < theEdge2_ids.size(); j++) o << theEdge2_ids[j] << ", "; o << "]"; - MESSAGE(o.str()); - MESSAGE("theEdge1_ids.size(): " << theEdge1_ids.size()); - MESSAGE("theEdge2_ids.size(): " << theEdge2_ids.size()); + // if ( _hypothesis->GetVerbosity() > _hypothesis->GetDefaultVerbosity() ) + // cout << o.str() << endl; if (_preCadEdgesIDsPeriodicityVector[i].theSourceVerticesCoords.empty()) - { - // If no source points, call peridoicity without transformation function - MESSAGE("periodicity without transformation function"); - meshgems_cad_periodicity_transformation_t periodicity_transformation = NULL; - status = cad_add_edge_multiple_periodicity_with_transformation_function(c, theEdge1_ids_c, theEdge1_ids.size(), - theEdge2_ids_c, theEdge2_ids.size(), periodicity_transformation, NULL); - if(status != STATUS_OK) - cout << "cad_add_edge_multiple_periodicity_with_transformation_function failed with error code " << status << "\n"; - } - else - { - // get the transformation vertices - MESSAGE("periodicity with transformation vertices"); - double* theSourceVerticesCoords_c = &_preCadEdgesIDsPeriodicityVector[i].theSourceVerticesCoords[0]; - double* theTargetVerticesCoords_c = &_preCadEdgesIDsPeriodicityVector[i].theTargetVerticesCoords[0]; - int nbSourceVertices = _preCadEdgesIDsPeriodicityVector[i].theSourceVerticesCoords.size()/3; - int nbTargetVertices = _preCadEdgesIDsPeriodicityVector[i].theTargetVerticesCoords.size()/3; - - MESSAGE("nbSourceVertices: " << nbSourceVertices << ", nbTargetVertices: " << nbTargetVertices); - - status = cad_add_edge_multiple_periodicity_with_transformation_function_by_points(c, theEdge1_ids_c, theEdge1_ids.size(), - theEdge2_ids_c, theEdge2_ids.size(), theSourceVerticesCoords_c, nbSourceVertices, theTargetVerticesCoords_c, nbTargetVertices); - if(status != STATUS_OK) - cout << "cad_add_edge_multiple_periodicity_with_transformation_function_by_points failed with error code " << status << "\n"; - else - MESSAGE("cad_add_edge_multiple_periodicity_with_transformation_function_by_points succeeded.\n"); - } - } - - MESSAGE("END PRECAD EDGES PERIODICITY"); - } - - if (! _facesIDsPeriodicityVector.empty()){ - MESSAGE("INTO FACE PERIODICITY"); - for (std::size_t i=0; i < _facesIDsPeriodicityVector.size(); i++){ - int theFace1 = _facesIDsPeriodicityVector[i].first; - int theFace2 = _facesIDsPeriodicityVector[i].second; - MESSAGE("_facesIDsPeriodicityVector[" << i << "] = (" << theFace1 << ", " << theFace2 << ")"); - status = cad_add_face_periodicity(c, theFace1, theFace2); - if(status != STATUS_OK){ - cout << "cad_add_face_periodicity failed with error code " << status << "\n"; - } - } - MESSAGE("END FACE PERIODICITY"); - } - - - if (! _edgesIDsPeriodicityVector.empty()){ - MESSAGE("INTO EDGE PERIODICITY"); - for (std::size_t i=0; i < _edgesIDsPeriodicityVector.size(); i++){ - int theFace1 = _edgesIDsPeriodicityVector[i].theFace1ID; - int theEdge1 = _edgesIDsPeriodicityVector[i].theEdge1ID; - int theFace2 = _edgesIDsPeriodicityVector[i].theFace2ID; - int theEdge2 = _edgesIDsPeriodicityVector[i].theEdge2ID; - int edge_orientation = _edgesIDsPeriodicityVector[i].edge_orientation; - MESSAGE("_edgesIDsPeriodicityVector[" << i << "] = (" << theFace1 << ", " << theEdge1 << ", " << theFace2 << ", " << theEdge2 << ", " << edge_orientation << ")"); - status = cad_add_edge_periodicity(c, theFace1, theEdge1, theFace2, theEdge2, edge_orientation); - if(status != STATUS_OK){ - cout << "cad_add_edge_periodicity failed with error code " << status << "\n"; - } - } - MESSAGE("END EDGE PERIODICITY"); - } - - if (! _verticesIDsPeriodicityVector.empty()){ - MESSAGE("INTO VERTEX PERIODICITY"); - for (std::size_t i=0; i < _verticesIDsPeriodicityVector.size(); i++){ - int theEdge1 = _verticesIDsPeriodicityVector[i].theEdge1ID; - int theVertex1 = _verticesIDsPeriodicityVector[i].theVertex1ID; - int theEdge2 = _verticesIDsPeriodicityVector[i].theEdge2ID; - int theVertex2 = _verticesIDsPeriodicityVector[i].theVertex2ID; - MESSAGE("_verticesIDsPeriodicityVector[" << i << "] = (" << theEdge1 << ", " << theVertex1 << ", " << theEdge2 << ", " << theVertex2 << ")"); - status = cad_add_point_periodicity(c, theEdge1, theVertex1, theEdge2, theVertex2); - if(status != STATUS_OK){ - cout << "cad_add_vertex_periodicity failed with error code " << status << "\n"; - } - } - MESSAGE("END VERTEX PERIODICITY"); - } - - //// - - if (use_precad) { - MESSAGE("use_precad"); - /* Now launch the PreCAD process */ - status = precad_process(pcs); - if(status != STATUS_OK){ - // TODO: raise an error if status < 0. - cout << "================ WARNING =================== \n"; - stringstream msg; - msg << "PreCAD processing failed with error code " << status << "\n"; - msg << *mcud._error; - cout << msg.str(); - cout << "============================================ \n"; - // the text of _comment is set in message_cb by mcud->_error - // => No need to append msg to _comment - if (status > 0) - { - // TODO: fix the SIGSEGV of COMPERR_WARNING with 2 launches - error(COMPERR_WARNING, _comment); - } - if (status < 0) - { - error(_comment); - } - } - else { - // retrieve the pre-processed CAD object - - // dcad - cleandc = precad_new_dcad(pcs); - if(!cleandc){ - cout << "Unable to retrieve PreCAD result on dcad \n"; + { + // If no source points, call periodicity without transformation function + meshgems_cad_periodicity_transformation_t periodicity_transformation = NULL; + status = cad_add_edge_multiple_periodicity_with_transformation_function(c, theEdge1_ids_c, theEdge1_ids.size(), + theEdge2_ids_c, theEdge2_ids.size(), periodicity_transformation, NULL); + if(status != STATUS_OK) + cout << "cad_add_edge_multiple_periodicity_with_transformation_function failed with error code " << status << "\n"; } else - cout << "PreCAD processing successfull on dcad \n"; - - // cad - cleanc = precad_new_cad(pcs); - if(!cleanc){ - cout << "Unable to retrieve PreCAD result on cad \n"; + { + // get the transformation vertices + double* theSourceVerticesCoords_c = &_preCadEdgesIDsPeriodicityVector[i].theSourceVerticesCoords[0]; + double* theTargetVerticesCoords_c = &_preCadEdgesIDsPeriodicityVector[i].theTargetVerticesCoords[0]; + int nbSourceVertices = _preCadEdgesIDsPeriodicityVector[i].theSourceVerticesCoords.size()/3; + int nbTargetVertices = _preCadEdgesIDsPeriodicityVector[i].theTargetVerticesCoords.size()/3; + + status = cad_add_edge_multiple_periodicity_with_transformation_function_by_points(c, theEdge1_ids_c, theEdge1_ids.size(), + theEdge2_ids_c, theEdge2_ids.size(), theSourceVerticesCoords_c, nbSourceVertices, theTargetVerticesCoords_c, nbTargetVertices); + if(status != STATUS_OK) + cout << "cad_add_edge_multiple_periodicity_with_transformation_function_by_points failed with error code " << status << "\n"; } - else - cout << "PreCAD processing successfull on cad \n"; - - // #if BLSURF_VERSION_LONG >= "3.1.1" - // /* We can now get the updated sizemaps (if any) */ - // // if(geo_sizemap_e) - // // clean_geo_sizemap_e = precad_new_sizemap(pcs, geo_sizemap_e); - // // - // // if(geo_sizemap_f) - // // clean_geo_sizemap_f = precad_new_sizemap(pcs, geo_sizemap_f); - // - // if(iso_sizemap_p) - // clean_iso_sizemap_p = precad_new_sizemap(pcs, iso_sizemap_p); - // - // if(iso_sizemap_e) - // clean_iso_sizemap_e = precad_new_sizemap(pcs, iso_sizemap_e); - // - // if(iso_sizemap_f) - // clean_iso_sizemap_f = precad_new_sizemap(pcs, iso_sizemap_f); - // #endif } - // Now we can delete the PreCAD session - precad_session_delete(pcs); } - if (cleandc) { - cout << "Give the pre-processed dcad object to the current MG-CADSurf session \n"; - cadsurf_data_set_dcad(css, cleandc); - } - else { - // Use the original one - cadsurf_data_set_dcad(css, dcad); - } + + // TODO: be able to use a mesh in input. + // See imsh usage in Products/templates/mg-cadsurf_template_common.cpp + // => cadsurf_set_mesh + + // Use the original dcad + cadsurf_set_dcad(css, dcad); - if (cleanc) { - // Give the pre-processed CAD object to the current MG-CADSurf session - cout << "Give the pre-processed CAD object to the current MG-CADSurf session \n"; - cadsurf_data_set_cad(css, cleanc); - } - else { - // Use the original one - cadsurf_data_set_cad(css, c); - } + // Use the original cad + cadsurf_set_cad(css, c); std::cout << std::endl; std::cout << "Beginning of Surface Mesh generation" << std::endl; @@ -2786,10 +2540,10 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, std::cout << std::endl; mesh_t *msh = NULL; - cadsurf_data_get_mesh(css, &msh); + cadsurf_get_mesh(css, &msh); if(!msh){ /* release the mesh object */ - cadsurf_data_regain_mesh(css, msh); + cadsurf_regain_mesh(css, msh); return error(_comment); } @@ -2830,9 +2584,9 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, nodes[iv] = NULL; if ( tag > 0 && tag <= pmap.Extent() ) { TopoDS_Vertex v = TopoDS::Vertex(pmap(tag)); - double tol = BRep_Tool::Tolerance( v ); - gp_Pnt p = BRep_Tool::Pnt( v ); - if ( p.IsEqual( gp_Pnt( xyz[0], xyz[1], xyz[2]), 2*tol)) + double tol = BRep_Tool::Tolerance( v ); + gp_Pnt p = BRep_Tool::Pnt( v ); + if ( p.IsEqual( gp_Pnt( xyz[0], xyz[1], xyz[2]), 1e3*tol)) xyz[0] = p.X(), xyz[1] = p.Y(), xyz[2] = p.Z(); else tag = 0; // enforced or attracted vertex @@ -2848,8 +2602,8 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, projVertex.push_back((double)xyz[1]); projVertex.push_back((double)xyz[2]); std::map< BLSURFPlugin_Hypothesis::TEnfVertexCoords, BLSURFPlugin_Hypothesis::TEnfVertexList >::const_iterator enfCoordsIt = EnfVertexCoords2EnfVertexList.find(projVertex); - if (enfCoordsIt != EnfVertexCoords2EnfVertexList.end()) { - MESSAGE("Found enforced vertex @ " << xyz[0] << ", " << xyz[1] << ", " << xyz[2]); + if (enfCoordsIt != EnfVertexCoords2EnfVertexList.end()) + { BLSURFPlugin_Hypothesis::TEnfVertexList::const_iterator enfListIt = enfCoordsIt->second.begin(); BLSURFPlugin_Hypothesis::TEnfVertex *currentEnfVertex; for (; enfListIt != enfCoordsIt->second.end(); ++enfListIt) { @@ -2857,36 +2611,26 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, if (currentEnfVertex->grpName != "") { bool groupDone = false; SMESH_Mesh::GroupIteratorPtr grIt = aMesh.GetGroups(); - MESSAGE("currentEnfVertex->grpName: " << currentEnfVertex->grpName); - MESSAGE("Parsing the groups of the mesh"); while (grIt->more()) { SMESH_Group * group = grIt->next(); if ( !group ) continue; - MESSAGE("Group: " << group->GetName()); SMESHDS_GroupBase* groupDS = group->GetGroupDS(); if ( !groupDS ) continue; - MESSAGE("group->SMDSGroup().GetType(): " << (groupDS->GetType())); - MESSAGE("group->SMDSGroup().GetType()==SMDSAbs_Node: " << (groupDS->GetType()==SMDSAbs_Node)); - MESSAGE("currentEnfVertex->grpName.compare(group->GetStoreName())==0: " << (currentEnfVertex->grpName.compare(group->GetName())==0)); if ( groupDS->GetType()==SMDSAbs_Node && currentEnfVertex->grpName.compare(group->GetName())==0) { SMESHDS_Group* aGroupDS = static_cast( groupDS ); aGroupDS->SMDSGroup().Add(nodes[iv]); - MESSAGE("Node ID: " << nodes[iv]->GetID()); // How can I inform the hypothesis ? // _hypothesis->AddEnfVertexNodeID(currentEnfVertex->grpName,nodes[iv]->GetID()); groupDone = true; - MESSAGE("Successfully added enforced vertex to existing group " << currentEnfVertex->grpName); break; } } if (!groupDone) { - int groupId; - SMESH_Group* aGroup = aMesh.AddGroup(SMDSAbs_Node, currentEnfVertex->grpName.c_str(), groupId); + SMESH_Group* aGroup = aMesh.AddGroup( SMDSAbs_Node, currentEnfVertex->grpName.c_str() ); aGroup->SetName( currentEnfVertex->grpName.c_str() ); SMESHDS_Group* aGroupDS = static_cast( aGroup->GetGroupDS() ); aGroupDS->SMDSGroup().Add(nodes[iv]); - MESSAGE("Successfully created enforced vertex group " << currentEnfVertex->grpName); groupDone = true; } if (!groupDone) @@ -2920,10 +2664,10 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, mesh_get_composite_tag_definition(msh, tag, &nb_tag, tags_buff); if(nb_tag > 1) tag=tags_buff[nb_tag-1]; - if ( tag > emap.Extent() ) + if ( tag < 1 || tag > emap.Extent() ) { std::cerr << "MG-CADSurf BUG:::: Edge tag " << tag - << " more than nb CAD egdes (" << emap.Extent() << ")" << std::endl; + << " does not point to a CAD edge (nb edges " << emap.Extent() << ")" << std::endl; continue; } if (tags[vtx[0]]) { @@ -2984,6 +2728,8 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, nodes[evtri[0]], nodes[evtri[1]], nodes[evtri[2]]); } else { + if ( helper.GetIsQuadratic() ) + helper.SetSubShape( tag ); tri = helper.AddFace(nodes[vtx[0]], nodes[vtx[1]], nodes[vtx[2]]); } meshDS->SetMeshElementOnShape(tri, tag); @@ -3013,7 +2759,6 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, }; if (type == MESHGEMS_MESH_ELEMENT_TYPE_QUAD9) { // QUADRATIC QUADRANGLE - std::cout << "This is a quadratic quadrangle" << std::endl; if (tags[evquad[0]]) { meshDS->SetNodeOnFace(nodes[evquad[0]], tag); tags[evquad[0]] = false; @@ -3045,7 +2790,14 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, } /* release the mesh object, the rest is released by cleaner */ - cadsurf_data_regain_mesh(css, msh); + cadsurf_regain_mesh(css, msh); + + + // Remove free nodes that can appear e.g. if "remove tiny edges"(IPAL53235) + for(int iv=1;iv<=nv;iv++) + if ( nodes[iv] && nodes[iv]->NbInverseElements() == 0 ) + meshDS->RemoveFreeNode( nodes[iv], 0, /*fromGroups=*/false ); + if ( needMerge ) // sew mesh computed by MG-CADSurf with pre-existing mesh { @@ -3091,6 +2843,7 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, } } + // SetIsAlwaysComputed( true ) to sub-meshes of EDGEs w/o mesh for (int i = 1; i <= emap.Extent(); i++) if ( SMESH_subMesh* sm = aMesh.GetSubMeshContaining( emap( i ))) @@ -3114,8 +2867,17 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, SMESH_subMesh* sm = aMesh.GetSubMesh( f ); if ( !sm->GetSubMeshDS() || sm->GetSubMeshDS()->NbElements() == 0 ) { - sm->GetComputeError().reset( new SMESH_ComputeError( err, _comment, this )); - badFaceFound = true; + int faceTag = sm->GetId(); + if ( faceTag != BLSURFPlugin_Hypothesis::GetHyperPatchTag( faceTag, _hypothesis )) + { + // triangles are assigned to the first face of hyper-patch + sm->SetIsAlwaysComputed( true ); + } + else + { + sm->GetComputeError().reset( new SMESH_ComputeError( err, _comment, this )); + badFaceFound = true; + } } } if ( err == COMPERR_WARNING ) @@ -3144,10 +2906,196 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, FacesWithEnforcedVertices.Statistics(std::cout); */ - MESSAGE("END OF BLSURFPlugin_BLSURF::Compute()"); return ( status == STATUS_OK && !quadraticSubMeshAndViscousLayer ); } +//================================================================================ +/*! + * \brief Compute a mesh basing on discrete CAD description + */ +//================================================================================ + +bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper) +{ + if ( aMesh.NbFaces() == 0 ) + return error( COMPERR_BAD_INPUT_MESH, "2D elements are missing" ); + + context_t *ctx = context_new(); + if (!ctx) return error("Pb in context_new()"); + + BLSURF_Cleaner cleaner( ctx ); + + message_cb_user_data mcud; + mcud._error = & this->SMESH_Algo::_comment; + mcud._progress = & this->SMESH_Algo::_progress; + mcud._verbosity = + _hypothesis ? _hypothesis->GetVerbosity() : BLSURFPlugin_Hypothesis::GetDefaultVerbosity(); + meshgems_status_t ret = context_set_message_callback(ctx, message_cb, &mcud); + if (ret != STATUS_OK) return error("Pb. in context_set_message_callback() "); + + cadsurf_session_t * css = cadsurf_session_new(ctx); + if(!css) return error( "Pb. in cadsurf_session_new() " ); + cleaner._css = css; + + + // Fill an input mesh + + mesh_t * msh = meshgems_mesh_new_in_memory( ctx ); + if ( !msh ) return error("Pb. in meshgems_mesh_new_in_memory()"); + + // mark nodes used by 2D elements + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + SMDS_NodeIteratorPtr nodeIt = meshDS->nodesIterator(); + while ( nodeIt->more() ) + { + const SMDS_MeshNode* n = nodeIt->next(); + n->setIsMarked( n->NbInverseElements( SMDSAbs_Face )); + } + meshgems_mesh_set_vertex_count( msh, meshDS->NbNodes() ); + + // set node coordinates + if ( meshDS->NbNodes() != meshDS->MaxNodeID() ) + { + meshDS->CompactMesh(); + } + SMESH_NodeXYZ nXYZ; + nodeIt = meshDS->nodesIterator(); + meshgems_integer i; + for ( i = 1; nodeIt->more(); ++i ) + { + nXYZ.Set( nodeIt->next() ); + meshgems_mesh_set_vertex_coordinates( msh, i, nXYZ.ChangeData() ); + } + + // set nodes of faces + meshgems_mesh_set_triangle_count ( msh, meshDS->GetMeshInfo().NbTriangles() ); + meshgems_mesh_set_quadrangle_count( msh, meshDS->GetMeshInfo().NbQuadrangles() ); + meshgems_integer nodeIDs[4]; + meshgems_integer iT = 1, iQ = 1; + SMDS_FaceIteratorPtr faceIt = meshDS->facesIterator(); + while ( faceIt->more() ) + { + const SMDS_MeshElement* face = faceIt->next(); + meshgems_integer nbNodes = face->NbCornerNodes(); + if ( nbNodes > 4 || face->IsPoly() ) continue; + + for ( i = 0; i < nbNodes; ++i ) + nodeIDs[i] = face->GetNode( i )->GetID(); + if ( nbNodes == 3 ) + meshgems_mesh_set_triangle_vertices ( msh, iT++, nodeIDs ); + else + meshgems_mesh_set_quadrangle_vertices( msh, iQ++, nodeIDs ); + } + + ret = cadsurf_set_mesh(css, msh); + if ( ret != STATUS_OK ) return error("Pb in cadsurf_set_mesh()"); + + + // Compute the mesh + + SetParameters(_hypothesis, css, aMesh.GetShapeToMesh() ); + + ret = cadsurf_compute_mesh(css); + if ( ret != STATUS_OK ) return false; + + mesh_t *omsh = 0; + cadsurf_get_mesh(css, &omsh); + if ( !omsh ) return error( "Pb. in cadsurf_get_mesh()" ); + + + // Update SALOME mesh + + // remove quadrangles and triangles + for ( faceIt = meshDS->facesIterator(); faceIt->more(); ) + { + const SMDS_MeshElement* face = faceIt->next(); + if ( !face->IsPoly() ) + meshDS->RemoveFreeElement( face, /*sm=*/0, /*fromGroups=*/true ); + } + // remove edges that bound the just removed faces + for ( SMDS_EdgeIteratorPtr edgeIt = meshDS->edgesIterator(); edgeIt->more(); ) + { + const SMDS_MeshElement* edge = edgeIt->next(); + const SMDS_MeshNode* n0 = edge->GetNode(0); + const SMDS_MeshNode* n1 = edge->GetNode(1); + if ( n0->isMarked() && + n1->isMarked() && + n0->NbInverseElements( SMDSAbs_Volume ) == 0 && + n1->NbInverseElements( SMDSAbs_Volume ) == 0 ) + meshDS->RemoveFreeElement( edge, /*sm=*/0, /*fromGroups=*/true ); + } + // remove nodes that just became free + for ( nodeIt = meshDS->nodesIterator(); nodeIt->more(); ) + { + const SMDS_MeshNode* n = nodeIt->next(); + if ( n->isMarked() && n->NbInverseElements() == 0 ) + meshDS->RemoveFreeNode( n, /*sm=*/0, /*fromGroups=*/true ); + } + + // add nodes + meshgems_integer nbvtx = 0, nodeID; + meshgems_mesh_get_vertex_count( omsh, &nbvtx ); + meshgems_real xyz[3]; + for ( i = 1; i <= nbvtx; ++i ) + { + meshgems_mesh_get_vertex_coordinates( omsh, i, xyz ); + SMDS_MeshNode* n = meshDS->AddNode( xyz[0], xyz[1], xyz[2] ); + nodeID = n->GetID(); + meshgems_mesh_set_vertex_tag( omsh, i, &nodeID ); // save mapping of IDs in MG and SALOME meshes + } + + // add triangles + meshgems_integer nbtri = 0; + meshgems_mesh_get_triangle_count( omsh, &nbtri ); + const SMDS_MeshNode* nodes[4]; + for ( i = 1; i <= nbtri; ++i ) + { + meshgems_mesh_get_triangle_vertices( omsh, i, nodeIDs ); + for ( int j = 0; j < 3; ++j ) + { + meshgems_mesh_get_vertex_tag( omsh, nodeIDs[j], &nodeID ); + nodes[j] = meshDS->FindNode( nodeID ); + } + meshDS->AddFace( nodes[0], nodes[1], nodes[2] ); + } + + // add quadrangles + meshgems_integer nbquad = 0; + meshgems_mesh_get_quadrangle_count( omsh, &nbquad ); + for ( i = 1; i <= nbquad; ++i ) + { + meshgems_mesh_get_quadrangle_vertices( omsh, i, nodeIDs ); + for ( int j = 0; j < 4; ++j ) + { + meshgems_mesh_get_vertex_tag( omsh, nodeIDs[j], &nodeID ); + nodes[j] = meshDS->FindNode( nodeID ); + } + meshDS->AddFace( nodes[0], nodes[1], nodes[2], nodes[3] ); + } + + if ( _hypothesis ) + { + std::string GMFFileName = _hypothesis->GetGMFFile(); + if ( !GMFFileName.empty() ) + { + bool asciiFound = (GMFFileName.find(".mesh", GMFFileName.size()-5) != std::string::npos); + bool binaryFound = (GMFFileName.find(".meshb",GMFFileName.size()-6) != std::string::npos); + if ( !asciiFound && !binaryFound ) + GMFFileName.append(".mesh"); + mesh_write_mesh(msh, GMFFileName.c_str()); + } + } + + cadsurf_regain_mesh(css, omsh); + + // as we don't assign the new triangles to a shape (the pseudo-shape), + // we mark the shape as always computed to avoid the error messages + // that no elements assigned to the shape + aMesh.GetSubMesh( aHelper->GetSubShape() )->SetIsAlwaysComputed( true ); + + return true; +} + //================================================================================ /*! * \brief Terminates computation @@ -3165,7 +3113,10 @@ void BLSURFPlugin_BLSURF::CancelCompute() */ //============================================================================= -void BLSURFPlugin_BLSURF::Set_NodeOnEdge(SMESHDS_Mesh* meshDS, const SMDS_MeshNode* node, const TopoDS_Shape& ed) { +void BLSURFPlugin_BLSURF::Set_NodeOnEdge(SMESHDS_Mesh* meshDS, + const SMDS_MeshNode* node, + const TopoDS_Shape& ed) +{ const TopoDS_Edge edge = TopoDS::Edge(ed); gp_Pnt pnt(node->X(), node->Y(), node->Z()); @@ -3293,7 +3244,7 @@ status_t surf_fun(real *uv, real *xyz, real*du, real *dv, status_t size_on_surface(integer face_id, real *uv, real *size, void *user_data) { TId2ClsAttractorVec::iterator f2attVec; - if (FaceId2PythonSmp.count(face_id) != 0){ + if (FaceId2PythonSmp.count(face_id) != 0) { assert(Py_IsInitialized()); PyGILState_STATE gstate; gstate = PyGILState_Ensure(); @@ -3302,7 +3253,7 @@ status_t size_on_surface(integer face_id, real *uv, real *size, void *user_data) if ( pyresult != NULL) { result = PyFloat_AsDouble(pyresult); Py_DECREF(pyresult); -// *size = result; + // *size = result; } else{ fflush(stderr); @@ -3320,10 +3271,8 @@ status_t size_on_surface(integer face_id, real *uv, real *size, void *user_data) *size = result; PyGILState_Release(gstate); } - else if (( f2attVec = FaceIndex2ClassAttractor.find(face_id)) != FaceIndex2ClassAttractor.end() && !f2attVec->second.empty()){ -// MESSAGE("attractor used on face :"<Empty()) + else if (( f2attVec = FaceIndex2ClassAttractor.find(face_id)) != FaceIndex2ClassAttractor.end() && !f2attVec->second.empty()) + { real result = 0; result = 1e100; std::vector< BLSURFPlugin_Attractor* > & attVec = f2attVec->second; @@ -3336,10 +3285,9 @@ status_t size_on_surface(integer face_id, real *uv, real *size, void *user_data) *size = result; } else { - // MESSAGE("List of attractor is empty !!!") *size = *((real*)user_data); } -// std::cout << "Size_on_surface sur la face " << face_id << " donne une size de: " << *size << std::endl; + // std::cout << "Size_on_surface sur la face " << face_id << " donne une size de: " << *size << std::endl; return STATUS_OK; } @@ -3483,7 +3431,7 @@ bool BLSURFPlugin_BLSURF::Evaluate(SMESH_Mesh& aMesh, bool _phySizeRel = BLSURFPlugin_Hypothesis::GetDefaultPhySizeRel(); //int _geometricMesh = BLSURFPlugin_Hypothesis::GetDefaultGeometricMesh(); double _angleMesh = BLSURFPlugin_Hypothesis::GetDefaultAngleMesh(); - bool _quadAllowed = BLSURFPlugin_Hypothesis::GetDefaultQuadAllowed(); + BLSURFPlugin_Hypothesis::ElementType _elementType = BLSURFPlugin_Hypothesis::GetDefaultElementType(); if(_hypothesis) { _physicalMesh = (int) _hypothesis->GetPhysicalMesh(); _phySizeRel = _hypothesis->IsPhySizeRel(); @@ -3492,12 +3440,11 @@ bool BLSURFPlugin_BLSURF::Evaluate(SMESH_Mesh& aMesh, //_geometricMesh = (int) hyp->GetGeometricMesh(); if (_hypothesis->GetAngleMesh() > 0) _angleMesh = _hypothesis->GetAngleMesh(); - _quadAllowed = _hypothesis->GetQuadAllowed(); + _elementType = _hypothesis->GetElementType(); } else { //0020968: EDF1545 SMESH: Problem in the creation of a mesh group on geometry // GetDefaultPhySize() sometimes leads to computation failure _phySize = aMesh.GetShapeDiagonalSize() / _gen->GetBoundaryBoxSegmentation(); - MESSAGE("BLSURFPlugin_BLSURF::SetParameters using defaults"); } bool IsQuadratic = _quadraticMesh; @@ -3573,7 +3520,7 @@ bool BLSURFPlugin_BLSURF::Evaluate(SMESH_Mesh& aMesh, int nbQuad = 0; int nbTria = (int) ( anArea/( ELen*ELen*sqrt(3.) / 4 ) ); int nbNodes = (int) ( ( nbTria*3 - (nb1d-1)*2 ) / 6 + 1 ); - if ( _quadAllowed ) + if ( _elementType != BLSURFPlugin_Hypothesis::Quadrangles ) { if ( nb1dVec.size() == 4 ) // quadrangle geom face {