-// Copyright (C) 2007-2016 CEA/DEN, EDF R&D
+// Copyright (C) 2007-2021 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
#include <Basics_Utils.hxx>
-#include <Basics_OCCTVersion.hxx>
#include <SMDS_EdgePosition.hxx>
#include <SMESHDS_Group.hxx>
#include <cstdlib>
// OPENCASCADE includes
+#include <BRepBndLib.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
-//#include <BRepBuilderAPI_MakeVertex.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepGProp.hxx>
#include <BRepTools.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <GProp_GProps.hxx>
#include <Geom2d_Curve.hxx>
+#include <Geom2d_Line.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <GeomAPI_ProjectPointOnSurf.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
+#include <NCollection_DataMap.hxx>
#include <NCollection_Map.hxx>
#include <Standard_ErrorHandler.hxx>
#include <TopExp.hxx>
static PyMethodDef PyStdOut_methods[] = {
{"write", (PyCFunction)PyStdOut_write, METH_VARARGS,
PyDoc_STR("write(string) -> None")},
- {NULL, NULL} /* sentinel */
+ {0, 0, 0, 0} /* sentinel */
};
static PyMemberDef PyStdOut_memberlist[] = {
{(char*)"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
(char*)"flag indicating that a space needs to be printed; used by print"},
- {NULL} /* Sentinel */
+ {0, 0, 0, 0, 0} /* Sentinel */
};
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*/
0, /*tp_new*/
0, /*tp_free*/
0, /*tp_is_gc*/
+ 0, /*tp_bases*/
+ 0, /*tp_mro*/
+ 0, /*tp_cache*/
+ 0, /*tp_subclasses*/
+ 0, /*tp_weaklist*/
+ 0, /*tp_del*/
+ 0, /*tp_version_tag*/
+ 0, /*tp_finalize*/
};
PyObject * newPyStdOut( std::string& out )
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;
*/
//=============================================================================
-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());
BLSURFPlugin_BLSURF::~BLSURFPlugin_BLSURF()
{
- MESSAGE("BLSURFPlugin_BLSURF::~BLSURFPlugin_BLSURF");
}
{
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<const BLSURFPlugin_Hypothesis*> (theHyp);
ASSERT(_hypothesis);
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 "<<entry );
GEOM::GEOM_Object_var aGeomObj;
TopoDS_Shape S = TopoDS_Shape();
- SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.c_str() );
+ SALOMEDS::SObject_var aSObj = SMESH_Gen_i::GetSMESHGen()->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());
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<BLSURFPlugin_Hypothesis::TEnfVertexList::iterator,bool> ret;
BLSURFPlugin_Hypothesis::TEnfVertexList::iterator it;
ret = EnfVertexCoords2EnfVertexList[s_coords].insert(enfVertex);
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)
{
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);
}
- }
}
}
}
/////////////////////////////////////////////////////////
void createAttractorOnFace(TopoDS_Shape GeomShape, std::string AttractorFunction, double defaultSize)
{
- MESSAGE("Attractor function: "<< AttractorFunction);
- double xa, ya, za; // Coordinates of attractor point
+ double xa=0., ya=0., za=0.; // Coordinates of attractor point
double a, b; // Attractor parameter
double d = 0.;
bool createNode=false; // To create a node on attractor projection
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;
}
// of r-d where r is the distance to (u0,v0)
attractorFunctionStream << "*exp(-(0.5*(sqrt((u-"<<u0<<")**2+(v-"<<v0<<")**2)-"<<d<<"+abs(sqrt((u-"<<u0<<")**2+(v-"<<v0<<")**2)-"<<d<<"))/(" << b << "))**2)";
- MESSAGE("Python function for attractor:" << std::endl << attractorFunctionStream.str());
-
int key;
if (! FacesWithSizeMap.Contains(TopoDS::Face(GeomShape))) {
key = FacesWithSizeMap.Add(TopoDS::Face(GeomShape));
}
FaceId2SizeMap[key] =attractorFunctionStream.str();
if (createNode) {
- MESSAGE("Creating node on ("<<x0<<","<<y0<<","<<z0<<")");
FaceId2AttractorCoords[key] = coords;
}
// // Test for new attractors
// myAttractor.SetType(1);
// FaceId2ClassAttractor[key] = myAttractor;
// if(FaceId2ClassAttractor[key].GetFace().IsNull()){
-// MESSAGE("face nulle ");
-// }
-// else
-// MESSAGE("face OK");
-//
-// if (FaceId2ClassAttractor[key].GetAttractorShape().IsNull()){
-// MESSAGE("pas de point");
// }
-// else
-// MESSAGE("point OK");
}
// One sub-shape to get ids from
-BLSURFPlugin_BLSURF::TListOfIDs _getSubShapeIDsInMainShape(TopoDS_Shape theMainShape, TopoDS_Shape theSubShape,
- TopAbs_ShapeEnum theShapeType)
+BLSURFPlugin_BLSURF::TListOfIDs _getSubShapeIDsInMainShape(const TopoDS_Shape& theMainShape,
+ const TopoDS_Shape& theSubShape,
+ TopAbs_ShapeEnum theShapeType)
{
BLSURFPlugin_BLSURF::TListOfIDs face_ids;
+
+ TopTools_MapOfShape subShapes;
TopTools_IndexedMapOfShape anIndices;
- anIndices.Clear();
TopExp::MapShapes(theMainShape, theShapeType, anIndices);
-// Standard_Boolean result = BRepTools::Write(theMainShape,"main_shape.brep");
-
for (TopExp_Explorer face_iter(theSubShape,theShapeType);face_iter.More();face_iter.Next())
+ {
+ if ( subShapes.Add( face_iter.Current() )) // issue 23416
{
- int face_id = anIndices.FindIndex(face_iter.Current());
- if (face_id == 0)
- throw SALOME_Exception ( SMESH_Comment("Sub_shape not found in main_shape"));
- face_ids.push_back(face_id);
-// std::ostringstream o;
-// o << "face_" << face_id << ".brep";
-// std::string face_name = o.str();
-// const TopoDS_Face& face = TopoDS::Face(face_iter.Current());
-// Standard_Boolean result = BRepTools::Write(face,face_name.c_str());
+ int face_id = anIndices.FindIndex( face_iter.Current() );
+ if ( face_id == 0 )
+ throw SALOME_Exception( "Periodicity: sub_shape not found in main_shape");
+ face_ids.push_back( face_id );
}
-
+ }
return face_ids;
}
{
int face_id = theMesh->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);
}
void BLSURFPlugin_BLSURF::addCoordsFromVertices(const std::vector<std::string> &theVerticesEntries, std::vector<double> &theVerticesCoords)
{
for (std::vector<std::string>::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<double> &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::createPreCadFacesPeriodicity");
-
TopoDS_Shape geomShape1 = entryToShape(preCadPeriodicity.shape1Entry);
TopoDS_Shape geomShape2 = entryToShape(preCadPeriodicity.shape2Entry);
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::createPreCadFacesPeriodicity END");
-
}
/////////////////////////////////////////////////////////
void BLSURFPlugin_BLSURF::createPreCadEdgesPeriodicity(TopoDS_Shape theGeomShape, const BLSURFPlugin_Hypothesis::TPreCadPeriodicity &preCadPeriodicity)
{
- MESSAGE("BLSURFPlugin_BLSURF::createPreCadEdgesPeriodicity");
-
TopoDS_Shape geomShape1 = entryToShape(preCadPeriodicity.shape1Entry);
TopoDS_Shape geomShape2 = entryToShape(preCadPeriodicity.shape2Entry);
addCoordsFromVertices(preCadPeriodicity.theTargetVerticesEntries, preCadEdgesPeriodicityIDs.theTargetVerticesCoords);
_preCadEdgesIDsPeriodicityVector.push_back(preCadEdgesPeriodicityIDs);
- MESSAGE("_preCadEdgesIDsPeriodicityVector.size() = " << _preCadEdgesIDsPeriodicityVector.size());
- MESSAGE("BLSURFPlugin_BLSURF::createPreCadEdgesPeriodicity END");
-
}
void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp,
cadsurf_session_t * css,
- const TopoDS_Shape& theGeomShape
- )
+ 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 );
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 _precadRemoveTinyUVEdges = BLSURFPlugin_Hypothesis::GetDefaultPreCADRemoveTinyUVEdges();
- int _precadRemoveDuplicateCADFaces = BLSURFPlugin_Hypothesis::GetDefaultPreCADRemoveDuplicateCADFaces();
- 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) {
// 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)
_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();
- _precadRemoveTinyUVEdges = hyp->GetPreCADRemoveTinyUVEdges();
- _precadRemoveDuplicateCADFaces = hyp->GetPreCADRemoveDuplicateCADFaces();
- _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() ) {
- MESSAGE("cadsurf_set_param(): " << opIt->first << " = " << opIt->second);
set_param(css, 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() ) {
- MESSAGE("cadsurf_set_param(): " << opIt->first << " = " << opIt->second);
- set_param(css, opIt->first.c_str(), opIt->second.c_str());
- }
+ if ( hyp->GetHyperPatches().size() < hyp->GetHyperPatchEntries().size() )
+ {
+ std::map< std::string, TopoDS_Shape > entryToShape;
+ FillEntryToShape( hyp, entryToShape );
+ const_cast<BLSURFPlugin_Hypothesis*>( hyp )->SetHyperPatchIDsByEntry( theGeomShape,
+ entryToShape );
+ }
}
-// 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");
-// }
- // PreProcessor (formerly PreCAD)
- set_param(css, "merge_edges", _precadMergeEdges ? "yes" : "no");
- set_param(css, "remove_tiny_uv_edges", _precadRemoveTinyUVEdges ? "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");
-
- // 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)
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");
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");
// - if maxsize is not explicitly specified, we pass default value computed automatically, in this case "relative" flag is ignored
set_param(css, "max_size", _maxSizeRel ? val_to_string_rel(_maxSize).c_str() : val_to_string(_maxSize).c_str());
}
+ useGradation = true; // bos #18758
// anisotropic and quadrangle mesh requires disabling gradation
- if ( _anisotropic && _quadAllowed )
+ if ( _anisotropic && _elementType != BLSURFPlugin_Hypothesis::Triangles )
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 ( 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");
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());
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) {
}
else {
key = FacesWithSizeMap.FindIndex(TopoDS::Face(it.Value()));
-// MESSAGE("Face with key " << key << " already in map");
}
FaceId2SizeMap[key] = smIt->second;
}
}
else {
key = EdgesWithSizeMap.FindIndex(TopoDS::Edge(it.Value()));
-// MESSAGE("Edge with key " << key << " already in map");
}
EdgeId2SizeMap[key] = smIt->second;
}
}
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;
}
}
}
else {
key = FacesWithSizeMap.FindIndex(TopoDS::Face(GeomShape));
-// MESSAGE("Face with key " << key << " already in map");
}
FaceId2SizeMap[key] = smIt->second;
}
}
else {
key = EdgesWithSizeMap.FindIndex(TopoDS::Edge(GeomShape));
-// MESSAGE("Edge with key " << key << " already in map");
}
EdgeId2SizeMap[key] = smIt->second;
}
}
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;
}
}
// 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
}
}
// }
-// else
-// MESSAGE("Impossible to create the attractors when the physical size is relative");
// Class Attractors
// temporary commented out for testing
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;
//
// 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;
}
}
}
-
- if (GeomType == TopAbs_FACE){
+ else if ( GeomShape.ShapeType() == TopAbs_FACE)
+ {
HasSizeMapOnFace = true;
createEnforcedVertexOnFace(GeomShape, enfIt->second);
}
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())
{
// 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() <<", "<<aPnt.Y()<<", "<<aPnt.Z());
BLSURFPlugin_Hypothesis::TEnfVertex* enfVertex = new BLSURFPlugin_Hypothesis::TEnfVertex();
enfVertex->coords.push_back(aPnt.X());
enfVertex->coords.push_back(aPnt.Y());
}
}
- MESSAGE("Setting Size Map on FACES ");
cadsurf_set_sizemap_iso_cad_face(css, size_on_surface, &_smp_phy_size);
if (HasSizeMapOnEdge){
- MESSAGE("Setting Size Map on EDGES ");
cadsurf_set_sizemap_iso_cad_edge(css, size_on_edge, &_smp_phy_size);
}
if (HasSizeMapOnVertex){
- MESSAGE("Setting Size Map on VERTICES ");
cadsurf_set_sizemap_iso_cad_point(css, size_on_vertex, &_smp_phy_size);
}
}
_preCadFacesIDsPeriodicityVector.clear();
_preCadEdgesIDsPeriodicityVector.clear();
- MESSAGE("SetParameters preCadFacesPeriodicityVector");
- const BLSURFPlugin_Hypothesis::TPreCadPeriodicityVector preCadFacesPeriodicityVector = BLSURFPlugin_Hypothesis::GetPreCadFacesPeriodicityVector(hyp);
-
for (std::size_t i = 0; i<preCadFacesPeriodicityVector.size(); i++){
- MESSAGE("SetParameters preCadFacesPeriodicityVector[" << i << "]");
createPreCadFacesPeriodicity(theGeomShape, preCadFacesPeriodicityVector[i]);
}
- MESSAGE("_preCadFacesIDsPeriodicityVector.size() = " << _preCadFacesIDsPeriodicityVector.size());
- MESSAGE("SetParameters preCadEdgesPeriodicityVector");
const BLSURFPlugin_Hypothesis::TPreCadPeriodicityVector preCadEdgesPeriodicityVector = BLSURFPlugin_Hypothesis::GetPreCadEdgesPeriodicityVector(hyp);
for (std::size_t i = 0; i<preCadEdgesPeriodicityVector.size(); i++){
- MESSAGE("SetParameters preCadEdgesPeriodicityVector[" << i << "]");
createPreCadEdgesPeriodicity(theGeomShape, preCadEdgesPeriodicityVector[i]);
}
- MESSAGE("_preCadEdgesIDsPeriodicityVector.size() = " << _preCadEdgesIDsPeriodicityVector.size());
-
}
//================================================================================
const char * option_value)
{
status_t status = cadsurf_set_param(css, option_name, option_value );
+
+ if ( _hypothesis && _hypothesis->GetVerbosity() > _hypothesis->GetDefaultVerbosity() )
+ cout << option_name << " = " << option_value << endl;
+
if ( status != MESHGEMS_STATUS_OK )
{
if ( status == MESHGEMS_STATUS_UNKNOWN_PARAMETER ) {
( "No valid license available" );
else
throw SALOME_Exception
- ( SMESH_Comment("Unacceptable value of CADSURF parameter '")
+ ( SMESH_Comment("Either wrong name or unacceptable value of CADSURF parameter '")
<< option_name << "': " << option_value);
}
}
/*!
* \brief Class correctly terminating usage of MG-CADSurf library at destruction
*/
- class BLSURF_Cleaner
+ struct BLSURF_Cleaner
{
- context_t * _ctx;
+ context_t * _ctx;
cadsurf_session_t* _css;
- cad_t * _cad;
- dcad_t * _dcad;
- public:
- BLSURF_Cleaner(context_t * ctx,
- cadsurf_session_t* css,
- cad_t * cad,
- dcad_t * dcad)
+ cad_t * _cad;
+ dcad_t * _dcad;
+
+ BLSURF_Cleaner(context_t * ctx,
+ cadsurf_session_t* css=0,
+ cad_t * cad=0,
+ dcad_t * dcad=0)
: _ctx ( ctx ),
_css ( css ),
_cad ( cad ),
bool operator()( const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ) const
{
// NEW ORDER: nodes earlier added to sub-mesh are considered "less"
- return n1->getIdInShape() < 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
}
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;
//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.) / double( 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++ )
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
std::vector<TopoDS_Vertex> 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 = 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;
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
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
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<const SMDS_MeshNode*>& nodesOfVertices )
+ {
+ BRepBuilderAPI_MakeWire newWire;
+
+ typedef NCollection_DataMap<SMESH_TLink, TopoDS_Edge, SMESH_TLink > 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
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();
if ( !n2nIt->second ) {
n->GetXYZ( xyz );
gp_XY uv = tmpHelper.GetNodeUV( _proxyFace, n );
- n2nIt->second = helper.AddNode( xyz[0], xyz[1], xyz[2], uv.X(), uv.Y() );
+ n2nIt->second = helper.AddNode( xyz[0], xyz[1], xyz[2], /*id=*/0, uv.X(), uv.Y() );
}
nodes[ nbN ] = n2nIt->second;
}
*/
//=============================================================================
-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;
/* 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;
TSubMeshSet edgeSubmeshes;
TSubMeshSet& mergeSubmeshes = edgeSubmeshes;
+ double existingPhySize = 0;
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 );
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
*/
// PreCAD
- // If user requests it, send the CAD through Distene preprocessor : PreCAD
- cad_t *cleanc = NULL; // preprocessed cad
- dcad_t *cleandc = NULL; // preprocessed dcad
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 );
- MESSAGE("BEGIN SetParameters");
- bool use_precad = false;
SetParameters(_hypothesis, css, aShape);
- MESSAGE("END SetParameters");
-
- MESSAGE("_preCadFacesIDsPeriodicityVector.size() = " << _preCadFacesIDsPeriodicityVector.size());
haveQuadraticSubMesh = haveQuadraticSubMesh || (_hypothesis != NULL && _hypothesis->GetQuadraticMesh());
helper.SetIsQuadratic( haveQuadraticSubMesh );
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));
* (For this face, it will be called by cadsurf with your_face_object_ptr
* as last parameter.
*/
-#if OCC_VERSION_MAJOR < 7
- cad_face_t *fce = cad_face_new(c, iface, surf_fun, surfaces.back());
-#else
cad_face_t *fce = cad_face_new(c, iface, surf_fun, surfaces.back().get());
-#endif
/* 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)*/
faceKey = FacesWithSizeMap.FindIndex(f);
- if (FaceId2SizeMap.find(faceKey)!=FaceId2SizeMap.end()) {
- MESSAGE("A size map is defined on face :"<<faceKey);
+ if (FaceId2SizeMap.find(faceKey)!=FaceId2SizeMap.end())
+ {
theSizeMapStr = FaceId2SizeMap[faceKey];
// check if function ends with "return"
if (theSizeMapStr.find(bad_end) == (theSizeMapStr.size()-bad_end.size()-1))
std::map<int,std::vector<double> >::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: "<<result);
if ( result == TopAbs_OUT )
MESSAGE("Point is out of face: node is not created");
if ( result == TopAbs_UNKNOWN )
if ( result == TopAbs_IN )
{
// Point is inside face and not on border
- MESSAGE("Point is in face: node is created");
double uvCoords[2] = {attractor_iter->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);
}
// -----------------
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() ) {
}
} // if (HasSizeMapOnFace && !use_precad)
- // ------------------
- // Enforced Vertices
- // ------------------
+ // ------------------
+ // Enforced Vertices
+ // ------------------
faceKey = FacesWithEnforcedVertices.FindIndex(f);
std::map<int,BLSURFPlugin_Hypothesis::TEnfVertexCoordsList >::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: "<<result);
- if ( result == TopAbs_OUT ) {
- MESSAGE("Point is out of face: node is not created");
- if (EnfVertexCoords2ProjVertex.find(xyzCoords) != EnfVertexCoords2ProjVertex.end()) {
- EnfVertexCoords2ProjVertex.erase(xyzCoords);
- // isssue 22783. Do not erase as this point can be IN other face of a group
- //EnfVertexCoords2EnfVertexList.erase(xyzCoords);
- }
- }
- if ( result == TopAbs_UNKNOWN ) {
- MESSAGE("Point position on face is unknown: node is not created");
- if (EnfVertexCoords2ProjVertex.find(xyzCoords) != EnfVertexCoords2ProjVertex.end()) {
- EnfVertexCoords2ProjVertex.erase(xyzCoords);
- //EnfVertexCoords2EnfVertexList.erase(xyzCoords);
- }
- }
- if ( result == TopAbs_ON ) {
- MESSAGE("Point is on border of face: node is not created");
- if (EnfVertexCoords2ProjVertex.find(xyzCoords) != EnfVertexCoords2ProjVertex.end()) {
- EnfVertexCoords2ProjVertex.erase(xyzCoords);
- //EnfVertexCoords2EnfVertexList.erase(xyzCoords);
- }
- }
- if ( result == TopAbs_IN )
+ std::map< BLSURFPlugin_Hypothesis::TEnfVertexCoords, BLSURFPlugin_Hypothesis::TEnfVertexList >::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);
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;
// tmin and tmax can change in case of viscous layer on an adjacent edge
tmin = nodeDataVec.front().param;
tmax = nodeDataVec.back().param;
+
+ existingPhySize += nodeData->Length() / double( nodeDataVec.size() - 1 );
}
else
{
}
/* attach the edge to the current cadsurf face */
-#if OCC_VERSION_MAJOR < 7
- cad_edge_t *edg = cad_edge_new(fce, ic, tmin, tmax, curv_fun, curves.back());
-#else
cad_edge_t *edg = cad_edge_new(fce, ic, tmin, tmax, curv_fun, curves.back().get());
-#endif
/* 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 :
if ( nodeData )
{
const std::vector<UVPtStruct>& nodeDataVec = nodeData->GetUVPtStruct();
- const int nbNodes = nodeDataVec.size();
+ const int nbNodes = (int) nodeDataVec.size();
dcad_edge_discretization_t *dedge;
dcad_get_edge_discretization(dcad, edg, &dedge);
// << "\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);
}
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
} // for edge
} //for face
- // Clear mesh from already meshed edges if possible else
- // remember that merge is needed
- TSubMeshSet::iterator smIt = edgeSubmeshes.begin();
- for ( ; smIt != edgeSubmeshes.end(); ++smIt ) // loop on already meshed EDGEs
- {
- SMESHDS_SubMesh* smDS = *smIt;
- if ( !smDS ) continue;
- SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
- if ( nIt->more() )
- {
- const SMDS_MeshNode* n = nIt->next();
- if ( n->NbInverseElements( SMDSAbs_Face ) > 0 )
- {
- needMerge = true; // to correctly sew with viscous mesh
- // add existing medium nodes to helper
- if ( aMesh.NbEdges( ORDER_QUADRATIC ) > 0 )
- {
- SMDS_ElemIteratorPtr edgeIt = smDS->GetElements();
- while ( edgeIt->more() )
- helper.AddTLinks( static_cast<const SMDS_MeshEdge*>(edgeIt->next()));
- }
- continue;
- }
- }
- if ( allowSubMeshClearing )
- {
- SMDS_ElemIteratorPtr eIt = smDS->GetElements();
- while ( eIt->more() ) meshDS->RemoveFreeElement( eIt->next(), 0 );
- SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
- while ( nIt->more() ) meshDS->RemoveFreeNode( nIt->next(), 0 );
- smDS->Clear();
- }
- else
- {
- needMerge = true;
- }
- }
-
///////////////////////
// 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<int> theFace1_ids = _preCadFacesIDsPeriodicityVector[i].shape1IDs;
std::vector<int> theFace2_ids = _preCadFacesIDsPeriodicityVector[i].shape2IDs;
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, (meshgems_integer) theFace1_ids.size(), theFace2_ids_c,
+ (meshgems_integer) 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 = (int)_preCadFacesIDsPeriodicityVector[i].theSourceVerticesCoords.size()/3;
+ int nbTargetVertices = (int)_preCadFacesIDsPeriodicityVector[i].theTargetVerticesCoords.size()/3;
+
+ status = cad_add_face_multiple_periodicity_with_transformation_function_by_points
+ (c, theFace1_ids_c, (meshgems_integer) theFace1_ids.size(), theFace2_ids_c,
+ (meshgems_integer) 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<int> theEdge1_ids = _preCadEdgesIDsPeriodicityVector[i].shape1IDs;
std::vector<int> 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];
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";
- }
+ {
+ // 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, (meshgems_integer) theEdge1_ids.size(), theEdge2_ids_c,
+ (meshgems_integer) 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");
- }
+ {
+ // get the transformation vertices
+ double* theSourceVerticesCoords_c = &_preCadEdgesIDsPeriodicityVector[i].theSourceVerticesCoords[0];
+ double* theTargetVerticesCoords_c = &_preCadEdgesIDsPeriodicityVector[i].theTargetVerticesCoords[0];
+ int nbSourceVertices = (int) _preCadEdgesIDsPeriodicityVector[i].theSourceVerticesCoords.size()/3;
+ int nbTargetVertices = (int) _preCadEdgesIDsPeriodicityVector[i].theTargetVerticesCoords.size()/3;
+
+ status = cad_add_edge_multiple_periodicity_with_transformation_function_by_points
+ (c, theEdge1_ids_c, (meshgems_integer) theEdge1_ids.size(), theEdge2_ids_c,
+ (meshgems_integer) 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";
+ }
}
-
- MESSAGE("END PRECAD EDGES PERIODICITY");
}
+ if ( !_hypothesis && !edgeSubmeshes.empty() && existingPhySize != 0 )
+ {
+ // prevent failure due to the default PhySize incompatible with size of existing 1D mesh
+ // and with face size
+ // double minFaceSize = existingPhySize / edgeSubmeshes.size();
+ // for ( int iF = 1; iF <= fmap.Extent(); ++iF )
+ // {
+ // Bnd_Box box;
+ // BRepBndLib::Add( fmap( iF ), box );
+ // gp_XYZ delta = box.CornerMax().XYZ() - box.CornerMin().XYZ();
+ // std::sort( delta.ChangeData(), delta.ChangeData() + 3 );
+ // minFaceSize = Min( minFaceSize, delta.Coord(2) );
+ // }
+ // set_param(css, "global_physical_size", val_to_string( minFaceSize * 0.5 ).c_str());
+ // set_param(css, "max_size", val_to_string( minFaceSize * 5 ).c_str());
+ }
// TODO: be able to use a mesh in input.
// See imsh usage in Products/templates/mg-cadsurf_template_common.cpp
mesh_t *msh = NULL;
cadsurf_get_mesh(css, &msh);
- if(!msh){
+ if ( !msh || STATUS_IS_ERROR( status ))
+ {
/* release the mesh object */
cadsurf_regain_mesh(css, msh);
return error(_comment);
}
+ // Clear mesh from already meshed edges if possible else
+ // remember that merge is needed
+ TSubMeshSet::iterator smIt = edgeSubmeshes.begin();
+ for ( ; smIt != edgeSubmeshes.end(); ++smIt ) // loop on already meshed EDGEs
+ {
+ SMESHDS_SubMesh* smDS = *smIt;
+ if ( !smDS ) continue;
+ SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
+ if ( nIt->more() )
+ {
+ const SMDS_MeshNode* n = nIt->next();
+ if ( n->NbInverseElements( SMDSAbs_Face ) > 0 )
+ {
+ needMerge = true; // to correctly sew with viscous mesh
+ // add existing medium nodes to helper
+ if ( aMesh.NbEdges( ORDER_QUADRATIC ) > 0 )
+ {
+ SMDS_ElemIteratorPtr edgeIt = smDS->GetElements();
+ while ( edgeIt->more() )
+ helper.AddTLinks( static_cast<const SMDS_MeshEdge*>(edgeIt->next()));
+ }
+ continue;
+ }
+ }
+ if ( allowSubMeshClearing )
+ {
+ SMDS_ElemIteratorPtr eIt = smDS->GetElements();
+ while ( eIt->more() ) meshDS->RemoveFreeElement( eIt->next(), 0 );
+ SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
+ while ( nIt->more() ) meshDS->RemoveFreeNode( nIt->next(), 0 );
+ smDS->Clear();
+ }
+ else
+ {
+ needMerge = true;
+ }
+ }
+
std::string GMFFileName = BLSURFPlugin_Hypothesis::GetDefaultGMFFile();
if (_hypothesis)
GMFFileName = _hypothesis->GetGMFFile();
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
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) {
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<SMESHDS_Group*>( 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<SMESHDS_Group*>( aGroup->GetGroupDS() );
aGroupDS->SMDSGroup().Add(nodes[iv]);
- MESSAGE("Successfully created enforced vertex group " << currentEnfVertex->grpName);
groupDone = true;
}
if (!groupDone)
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]]) {
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);
};
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;
/* release the mesh object, the rest is released by cleaner */
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
{
SMESH_MeshEditor editor( &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 )))
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 )
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()");
+
+ if ( aMesh.NbNodes() > std::numeric_limits< meshgems_integer >::max() ||
+ aMesh.NbFaces() > std::numeric_limits< meshgems_integer >::max() )
+ return error("Too large input mesh");
+
+ 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, (meshgems_integer) 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, (meshgems_integer) meshDS->GetMeshInfo().NbTriangles() );
+ meshgems_mesh_set_quadrangle_count( msh, (meshgems_integer) 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] = (meshgems_integer) 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 = (meshgems_integer) 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
*/
//=============================================================================
-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());
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();
if ( pyresult != NULL) {
result = PyFloat_AsDouble(pyresult);
Py_DECREF(pyresult);
-// *size = result;
+ // *size = result;
}
else{
fflush(stderr);
*size = result;
PyGILState_Release(gstate);
}
- else if (( f2attVec = FaceIndex2ClassAttractor.find(face_id)) != FaceIndex2ClassAttractor.end() && !f2attVec->second.empty()){
-// MESSAGE("attractor used on face :"<<face_id)
- // MESSAGE("List of attractor is not empty")
- // MESSAGE("Attractor empty : "<< FaceIndex2ClassAttractor[face_id]->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;
*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;
}
err.find("periodicity") != string::npos )
{
// remove ^A from the tail
- int len = strlen( desc );
+ size_t len = strlen( desc );
while (len > 0 && desc[len-1] != '\n')
len--;
mcud->_error->append( desc, len );
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();
//_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;
nb1d = (int)( fullAng/_angleMesh + 1 );
}
fullNbSeg += nb1d;
- std::vector<int> aVec(SMDSEntity_Last);
- for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i]=0;
+ std::vector<smIdType> aVec(SMDSEntity_Last);
+ for(smIdType i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i]=0;
if( IsQuadratic > 0 ) {
aVec[SMDSEntity_Node] = 2*nb1d - 1;
aVec[SMDSEntity_Quad_Edge] = nb1d;
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
{
nbTria = nbQuad = nbTria / 3 + 1;
}
}
- std::vector<int> aVec(SMDSEntity_Last,0);
+ std::vector<smIdType> aVec(SMDSEntity_Last,0);
if( IsQuadratic ) {
int nb1d_in = (nbTria*3 - nb1d) / 2;
aVec[SMDSEntity_Node] = nbNodes + nb1d_in;
double tetrVol = 0.1179*ELen*ELen*ELen;
int nbVols = int(aVolume/tetrVol);
int nb1d_in = int(( nbVols*6 - fullNbSeg ) / 6 );
- std::vector<int> aVec(SMDSEntity_Last);
- for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i]=0;
+ std::vector<smIdType> aVec(SMDSEntity_Last);
+ for(smIdType i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i]=0;
if( IsQuadratic ) {
aVec[SMDSEntity_Node] = nb1d_in/3 + 1 + nb1d_in;
aVec[SMDSEntity_Quad_Tetra] = nbVols;
return true;
}
+
+//================================================================================
+/*!
+ * \brief Find TopoDS_Shape for each hyper-patch study entry in a hypothesis
+ */
+//================================================================================
+
+void BLSURFPlugin_BLSURF::FillEntryToShape( const BLSURFPlugin_Hypothesis* hyp,
+ std::map< std::string, TopoDS_Shape > & entryToShape )
+{
+ SMESH_Gen_i* smeshGen = SMESH_Gen_i::GetSMESHGen();
+ for ( const ::BLSURFPlugin_Hypothesis::THyperPatchEntries& entries : hyp->GetHyperPatchEntries() )
+ for ( const std::string& entry : entries )
+ {
+ GEOM::GEOM_Object_var go = smeshGen->GetGeomObjectByEntry( entry );
+ TopoDS_Shape shape = smeshGen->GeomObjectToShape( go );
+ if ( !shape.IsNull() )
+ entryToShape.insert({ entry, shape });
+ }
+}