From: gdd Date: Thu, 10 Mar 2011 10:57:40 +0000 (+0000) Subject: rnc : first version with gui X-Git-Tag: Geodesic_Attractor_20110316~2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=e071b0d89112b986e1777e9909ca616170e29ab0;p=plugins%2Fblsurfplugin.git rnc : first version with gui --- diff --git a/idl/BLSURFPlugin_Algorithm.idl b/idl/BLSURFPlugin_Algorithm.idl index 291272a..12d2440 100644 --- a/idl/BLSURFPlugin_Algorithm.idl +++ b/idl/BLSURFPlugin_Algorithm.idl @@ -75,6 +75,17 @@ module BLSURFPlugin TEnfVertexCoordsList coordsList; }; typedef sequence TEntryCoordsListMap; + + // Attractors + struct TAttractorParams { + string faceEntry; + string attEntry; + double startSize; + double endSize; + double infDist; + double constDist; + }; + typedef sequence TAttParamsMap; // // ////////////// OLD ///////////////// // // typedef sequence OldTEnfVertexList; @@ -276,16 +287,15 @@ module BLSURFPlugin * Set/unset an attractor given as geom object on another geom object */ void SetAttractorGeom(in GEOM::GEOM_Object GeomObj, in GEOM::GEOM_Object AttractorShape, in double StartSize, in double EndSize, in double ActionRadius, in double ConstantRadius); - // void SetAttractorGeom(in GEOM::GEOM_Object theFace, in GEOM::GEOM_Object theAttractor, in string theParams, in long type); void UnsetAttractorGeom(in GEOM::GEOM_Object GeomObj); /*! * Set an attractor given by entry on a geom object given by entry */ - // void SetClassAttractorEntry(in string entry, in string att_entry, in double StartSize, in double EndSize, in double ActionRadius, in double ConstantRadius ); -// void SetAttractorEntryGeom(in string theFaceEntry, in GEOM::GEOM_Object theAttractor, in string theParams, in long type); - // string GetAttractorEntry(in string entry); // TODO a coder - //string_array GetAttractorEntries(); + void SetClassAttractorEntry(in string entry, in string att_entry, in double StartSize, in double EndSize, in double ActionRadius, in double ConstantRadius ); + BLSURFPlugin::TAttParamsMap GetAttractorParams(); + + /* void SetCustomSizeMapEntry(in string entry, in string sizeMap); diff --git a/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx b/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx index bd8c055..891108c 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Attractor.cxx @@ -9,6 +9,7 @@ BLSURFPlugin_Attractor::BLSURFPlugin_Attractor () : _face(), _attractorShape(), + _attEntry(), _step(0), _gridU(0), _gridV(0), @@ -29,9 +30,10 @@ BLSURFPlugin_Attractor::BLSURFPlugin_Attractor () _isMapBuilt(false), _isEmpty(true){ MESSAGE("construction of a void attractor"); } -BLSURFPlugin_Attractor::BLSURFPlugin_Attractor (const TopoDS_Face& Face, const TopoDS_Shape& Attractor, double Step) +BLSURFPlugin_Attractor::BLSURFPlugin_Attractor (const TopoDS_Face& Face, const TopoDS_Shape& Attractor, const std::string& attEntry, double Step) : _face(), _attractorShape(), + _attEntry(attEntry), _step(Step), _gridU(), _gridV(), @@ -197,8 +199,7 @@ double BLSURFPlugin_Attractor::_distance(double u, double v){ } -double BLSURFPlugin_Attractor::GetSize(double u, double v){ - +double BLSURFPlugin_Attractor::GetSize(double u, double v){ double myDist = 0.5 * (_distance(u,v) - _constantRadius + fabs(_distance(u,v) - _constantRadius)); if (myDist<0){ MESSAGE("Warning myDist<0 : myDist= "< 0 ){ min = _trial.begin(); // Get trial point with min distance from start i0 = (*min)[1]; j0 = (*min)[2]; _known[i0][j0] = true; // Move it to "Known" _trial.erase(min); // Remove it from "Trial" - // Loop on neighbours of the trial min ---------------------------------------------------------------------- + // Loop on neighbours of the trial min -------------------------------------------------------------------------------------------------------------- for (i=i0 - 1 ; i <= i0 + 1 ; i++){ if (!aSurf->IsUPeriodic()){ // Periodic conditions in U if (i > _gridU ){ @@ -251,8 +257,8 @@ void BLSURFPlugin_Attractor::BuildMap(){ else if (i < 0){ i++; } } - ip = (i + _gridU + 1) % (_gridU+1); // We get a periodic index ip=modulo(i,N+2) so that i=-1->ip=N; i=0 -> ip=0 ; ... ; i=N+1 -> ip=0; - for (j=j0 - 1 ; j <= j0 + 1 ; j++){ + ip = (i + _gridU + 1) % (_gridU+1); // We get a periodic index : + for (j=j0 - 1 ; j <= j0 + 1 ; j++){ // ip=modulo(i,N+2) so that i=-1->ip=N; i=0 -> ip=0 ; ... ; i=N+1 -> ip=0; if (!aSurf->IsVPeriodic()){ // Periodic conditions in V . if (j > _gridV ){ break; } @@ -269,8 +275,8 @@ void BLSURFPlugin_Attractor::BuildMap(){ Guu = D1U.X()*D1U.X() + D1U.Y()*D1U.Y() + D1U.Z()*D1U.Z(); // Guu = ||dS/du||**2 Gvv = D1V.X()*D1V.X() + D1V.Y()*D1V.Y() + D1V.Z()*D1V.Z(); // Gvv = ||dS/dv||**2 Guv = D1U.X()*D1V.X() + D1U.Y()*D1V.Y() + D1U.Z()*D1V.Z(); // Guv = Gvu = < dS/du,dS/dv > - D_Ref = _DMap[ip][jp]; // Set a ref. distance of the point to its value in _DMap (may be infinite or uncertain) - TPnt[0] = D_Ref; + D_Ref = _DMap[ip][jp]; // Set a ref. distance of the point to its value in _DMap + TPnt[0] = D_Ref; // (may be infinite or uncertain) TPnt[1] = ip; TPnt[2] = jp; Dist_changed = false; diff --git a/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx b/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx index f5cc2c4..88c3a66 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Attractor.hxx @@ -22,7 +22,8 @@ // Authors : Renaud Nédélec (OCC) // --- // -// The algorithm used to calculate the distance on a non-euclidian parametric surface has been found in the ref. below: +// The idea of the algorithm used to calculate the distance on a +// non-euclidian parametric surface has been found in the ref. below: // // Ref:"Accurate Anisotropic Fast Marching for Diffusion-Based Geodesic Tractography" // S. Jbabdi, P. Bellec, R. Toro, Daunizeau, M. Pélégrini-Issac, and H. Benali1 @@ -82,62 +83,24 @@ #define TYPE_EXP 0 #define TYPE_LIN 1 - -// class IJ_Pnt{ -// public: -// IJ_Pnt(int i,int j){ -// Pi=i; -// Pj=j; -// } -// int Pi; -// int Pj; -// }; -// -// class IJ_comp{ -// public: -// bool operator() (const IJ_Pnt p1, const IJ_Pnt p2) const { -// if (&p1 && &p2){ -// return ( (p1.Pi < p2.Pi) || (p1.Pi == p2.Pi && p1.Pj < p2.Pj) ) ; -// } -// else -// return (&p1 < &p2); -// } -// }; -// -// class Trial_Pnt{ -// public: -// Trial_Pnt(int i,int j,double d){ -// Ti=i; -// Tj=j; -// dist=d; -// } -// int Ti; -// int Tj; -// double dist; -// }; -// -// class Trial_comp { -// public: -// bool operator() (const Trial_Pnt p1, const Trial_Pnt p2) const { -// if (&p1 && &p2){ -// return ( (p1.dist < p2.dist) || -// (p1.dist == p2.dist && p1.Ti < p2.Ti) || -// (p1.dist == p2.dist && p1.Ti == p2.Ti && p1.Tj < p2.Tj) ) ; -// } -// else -// return false; -// } -// }; - class BLSURFPlugin_Attractor { + public: + BLSURFPlugin_Attractor (); - BLSURFPlugin_Attractor (const TopoDS_Face& Face, const TopoDS_Shape& Attractor, double Step = 0.015); - bool init(); // Calculates the discrete points correponding to attractor and intialises the map of distances - + BLSURFPlugin_Attractor (const TopoDS_Face& Face, const TopoDS_Shape& Attractor, const std::string& attEntry, double Step = 0.015); + bool init(); // Calculates the discrete points correponding to attractor + // and intialises the map of distances double GetSize (double u, double v); TopoDS_Face GetFace() const { return _face; } TopoDS_Shape GetAttractorShape() const { return _attractorShape; } + std::string GetAttractorEntry() const { return _attEntry; } + std::vector GetParameters() const + { + double tab_params[] = {_startSize, _endSize, _actionRadius, _constantRadius}; + std::vector params (tab_params, tab_params + sizeof(tab_params) / sizeof(double) ); + return params; + } void SetParameters(double Start_Size, double End_Size, double Action_Radius, double Constant_Radius); void SetType(int type){ _type = type; } @@ -145,7 +108,6 @@ class BLSURFPlugin_Attractor { void BuildMap(); // Builds the map of distances between source point and any point P(u,v) bool IsMapBuilt() const { return _isMapBuilt; } // Controls if the map has been built bool Empty() const { return _isEmpty; } - typedef std::vector TDiscreteParam; typedef std::vector< std::vector > TDistMap; @@ -158,6 +120,7 @@ class BLSURFPlugin_Attractor { TopoDS_Face _face; TopoDS_Shape _attractorShape; + std::string _attEntry; TDiscreteParam _vectU; TDiscreteParam _vectV; TDistMap _DMap; @@ -177,29 +140,4 @@ class BLSURFPlugin_Attractor { double _distance(double u, double v); }; - - - - - - - - - - - - - - - - - - - - - - - - - #endif diff --git a/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx b/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx index 66f53e2..c7afef1 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx @@ -281,6 +281,7 @@ BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF(int hypId, int studyId, VertexId2PythonSmp.clear(); FaceId2AttractorCoords.clear(); FaceId2ClassAttractor.clear(); + FaceIndex2ClassAttractor.clear(); FacesWithEnforcedVertices.Clear(); FaceId2EnforcedVertexCoords.clear(); EnfVertex2ProjVertex.clear(); @@ -982,6 +983,7 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) FacesWithSizeMap.Clear(); FaceId2SizeMap.clear(); FaceId2ClassAttractor.clear(); + FaceIndex2ClassAttractor.clear(); EdgesWithSizeMap.Clear(); EdgeId2SizeMap.clear(); VerticesWithSizeMap.Clear(); @@ -1061,12 +1063,14 @@ bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) } if (HasSizeMapOnFace){ - MESSAGE("A size map is defined on a face") +// MESSAGE("A size map is defined on a face") // std::cout << "A size map is defined on a face" << std::endl; // Classic size map faceKey = FacesWithSizeMap.FindIndex(f); + if (FaceId2SizeMap.find(faceKey)!=FaceId2SizeMap.end()){ + MESSAGE("A size map is defined on face :"<Empty()) + else if (FaceIndex2ClassAttractor.count(face_id) !=0 && !FaceIndex2ClassAttractor[face_id]->Empty()){ + MESSAGE("attractor used on face :"<Empty()) double result = FaceIndex2ClassAttractor[face_id]->GetSize(uv[0],uv[1]); *size = result; // MESSAGE("f(" << uv[0] << "," << uv[1] << ")" << " = " << result); diff --git a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx index 6f0dec0..db43e85 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx @@ -26,6 +26,7 @@ // #include "BLSURFPlugin_Hypothesis.hxx" #include "BLSURFPlugin_Attractor.hxx" +#include "SMESH_Gen_i.hxx" #include #include #include @@ -34,6 +35,10 @@ // cascade include #include "ShapeAnalysis.hxx" +// CORBA includes +#include CORBA_CLIENT_HEADER(SALOMEDS) +#include CORBA_CLIENT_HEADER(GEOM_Gen) + //============================================================================= BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis (int hypId, int studyId, SMESH_Gen * gen) @@ -151,6 +156,28 @@ BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis (int hypId, int studyId, */ } +TopoDS_Shape BLSURFPlugin_Hypothesis::entryToShape(std::string entry) +{ + MESSAGE("BLSURFPlugin_Hypothesis::entryToShape "<GetCurrentStudy(); + + TopoDS_Shape S = TopoDS_Shape(); + SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.c_str() ); + SALOMEDS::GenericAttribute_var anAttr; + + if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) { + SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + CORBA::String_var aVal = anIOR->Value(); + CORBA::Object_var obj = myStudy->ConvertIORToObject(aVal); + aGeomObj = GEOM::GEOM_Object::_narrow(obj); + } + if ( !aGeomObj->_is_nil() ) + S = smeshGen_i->GeomObjectToShape( aGeomObj.in() ); + return S; +} + //============================================================================= void BLSURFPlugin_Hypothesis::SetTopology(Topology theTopology) { @@ -428,10 +455,8 @@ BLSURFPlugin_Hypothesis::TSizeMap BLSURFPlugin_Hypothesis::GetAttractorEntries(c //======================================================================= //function : SetClassAttractorEntry //======================================================================= -void BLSURFPlugin_Hypothesis::SetClassAttractorEntry(const std::string& entry, const TopoDS_Face& FaceShape, const TopoDS_Shape& AttractorShape, double StartSize, double EndSize, double ActionRadius, double ConstantRadius) // TODO finir +void BLSURFPlugin_Hypothesis::SetClassAttractorEntry(const std::string& entry, const std::string& attEntry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius) { - - //double Step = _phyMin; pas connu a ce stade // The new attractor can't be defined on the same face as another sizemap TSizeMap::iterator it = _sizeMap.find( entry ); if ( it != _sizeMap.end() ) { @@ -446,14 +471,16 @@ void BLSURFPlugin_Hypothesis::SetClassAttractorEntry(const std::string& entry, } } + const TopoDS_Shape AttractorShape = BLSURFPlugin_Hypothesis::entryToShape(attEntry); + const TopoDS_Face FaceShape = TopoDS::Face(BLSURFPlugin_Hypothesis::entryToShape(entry)); bool attExists = (_classAttractors.find(entry) != _classAttractors.end()); double u1,u2,v1,v2, diag; - if ( !attExists || (attExists && !_classAttractors[entry]->GetAttractorShape().IsSame(AttractorShape))){ + + if ( !attExists || (attExists && _classAttractors[entry]->GetAttractorEntry().compare(attEntry) != 0)){ ShapeAnalysis::GetFaceUVBounds(FaceShape,u1,u2,v1,v2); diag = sqrt((u2 - u1) * (u2 - u1) + (v2 - v1) * (v2 - v1)); - BLSURFPlugin_Attractor* myAttractor = new BLSURFPlugin_Attractor(FaceShape, AttractorShape, 0.002 * diag); //TODO calculer MapGrid + BLSURFPlugin_Attractor* myAttractor = new BLSURFPlugin_Attractor(FaceShape, AttractorShape, attEntry, 0.003 * diag); myAttractor->BuildMap(); - //MESSAGE("Step = "<SetParameters(StartSize, EndSize, ActionRadius, ConstantRadius); _classAttractors[entry] = myAttractor; NotifySubMeshesHypothesisModification(); @@ -468,10 +495,27 @@ void BLSURFPlugin_Hypothesis::SetClassAttractorEntry(const std::string& entry, } -// //======================================================================= -// //function : GetClassAttractorEntry -// //======================================================================= -// std::string BLSURFPlugin_Hypothesis::GetClassAttractorEntry(const std::string& entry) +//======================================================================= +//function : SetConstantSizeOnAdjacentFaces +//======================================================================= +// TODO uncomment and test (include the needed .hxx) +// SetConstantSizeOnAdjacentFaces(myShape, att_entry, startSize, endSize = user_size, const_dist ) { +// TopTools_IndexedMapOfShapListOdShape anEdge2FaceMap; +// TopExp::MapShapesAnAncestors(myShape,TopAbs_EDGE, TopAbs_FACE, anEdge2FaceMap); +// TopTools_IndexedMapOfShapListOdShape::iterator it; +// for (it = anEdge2FaceMap.begin();it != anEdge2FaceMap.end();it++){ +// SetClassAttractorEntry((*it).first, att_entry, startSize, endSize, 0, const_dist) +// } + + + + + + +//======================================================================= +//function : GetClassAttractorEntry +//======================================================================= +// BLSURFPlugin_Attractor& BLSURFPlugin_Hypothesis::GetClassAttractorEntry(const std::string& entry) // { // TAttractorMap::iterator it = _classAttractors.find( entry ); // if ( it != _classAttractors.end() ) @@ -488,7 +532,6 @@ BLSURFPlugin_Hypothesis::TAttractorMap BLSURFPlugin_Hypothesis::GetClassAttracto return hyp ? hyp->_GetClassAttractorEntries():GetDefaultAttractorMap(); } - //======================================================================= //function : ClearEntry //======================================================================= @@ -510,6 +553,7 @@ void BLSURFPlugin_Hypothesis::ClearEntry(const std::string& entry) TAttractorMap::iterator it_clAt = _classAttractors.find( entry ); if ( it_clAt != _classAttractors.end() ) { _classAttractors.erase(it_clAt); + MESSAGE("_classAttractors.size() = "<<_classAttractors.size()) NotifySubMeshesHypothesisModification(); } else diff --git a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx index b8eec1b..924baa5 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx @@ -57,6 +57,8 @@ public: DefaultGeom, UserDefined }; + + TopoDS_Shape entryToShape(std::string entry); void SetTopology(Topology theTopology); Topology GetTopology() const { return _topology; } @@ -130,9 +132,10 @@ public: const TSizeMap& GetCustomSizeMapEntries() const { return _customSizeMap; } */ - typedef std::map TAttractorMap; + typedef std::map< std::string, BLSURFPlugin_Attractor* > TAttractorMap; + typedef std::map< std::string, std::vector > TParamsMap; //TODO à finir - void SetClassAttractorEntry(const std::string& entry, const TopoDS_Face& FaceShape, const TopoDS_Shape& AttractorShape, double StartSize, double EndSize, double ActionRadius, double ConstantRadius); + void SetClassAttractorEntry(const std::string& entry, const std::string& att_entry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius); std::string GetClassAttractorEntry(const std::string& entry); const TAttractorMap& _GetClassAttractorEntries() const { return _classAttractors; } /*! @@ -310,6 +313,8 @@ private: TSizeMap _sizeMap; TSizeMap _attractors; TAttractorMap _classAttractors; + TSizeMap _attEntry; + TParamsMap _attParams; // TEnfVertexList _enfVertexList; TEntryCoordsListMap _entryCoordsListMap; TCoordsEnfVertexMap _coordsEnfVertexMap; diff --git a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx index c4fca27..573053a 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx @@ -554,7 +554,6 @@ void BLSURFPlugin_Hypothesis_i::SetAttractorEntry(const char* entry,const char* try { valueChanged = ( this->GetImpl()->GetAttractorEntry(entry) != attractor ); if ( valueChanged ) { - //boost::regex re("^ATTRACTOR\\((?:(-?0(\\.\\d*)*|-?[1-9]+\\d*(\\.\\d*)*|-?\\.(\\d)+);){5}(True|False)\\)$"); boost::regex re("^ATTRACTOR\\((?:(-?0(\\.\\d*)*|-?[1-9]+\\d*(\\.\\d*)*|-?\\.(\\d)+);){5}(True|False)(?:;(-?0(\\.\\d*)*|-?[1-9]+\\d*(\\.\\d*)*|-?\\.(\\d)+))?\\)$"); if (!boost::regex_match(string(attractor), re)) throw std::invalid_argument("Error: an attractor is defined with the following pattern: ATTRACTOR(xa;ya;za;a;b;True|False;d(opt.))"); @@ -581,20 +580,20 @@ void BLSURFPlugin_Hypothesis_i::SetAttractorEntry(const char* entry,const char* //============================================================================= -void BLSURFPlugin_Hypothesis_i::SetClassAttractorEntry(const char* entry, const TopoDS_Face& FaceShape, const TopoDS_Shape& AttractorShape, double StartSize, double EndSize, double ActionRadius, double ConstantRadius) //TODO à finir +void BLSURFPlugin_Hypothesis_i::SetClassAttractorEntry(const char* entry, const char* att_entry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius) //TODO à finir throw (SALOME::SALOME_Exception) { ASSERT(myBaseImpl); MESSAGE("ENGINE : SETATTRACTOR START ENTRY : " << entry); - // bool valueChanged = false; + bool valueChanged = false; try { - this->GetImpl()->SetClassAttractorEntry(entry, FaceShape, AttractorShape, StartSize, EndSize, ActionRadius, ConstantRadius); + this->GetImpl()->SetClassAttractorEntry(entry, att_entry, StartSize, EndSize, ActionRadius, ConstantRadius); } catch (const std::invalid_argument& ex) { SALOME::ExceptionStruct ExDescription; ExDescription.text = ex.what(); ExDescription.type = SALOME::BAD_PARAM; - ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::SetClassAttractorEntry(entry,att_entry)"; + ExDescription.sourceFile = "BLSURFPlugin_Hypothesis::SetClassAttractorEntry(entry, att_entry, StartSize, EndSize, ActionRadius, ConstantRadius)"; ExDescription.lineNumber = 0; throw SALOME::SALOME_Exception(ExDescription); } @@ -603,9 +602,8 @@ void BLSURFPlugin_Hypothesis_i::SetClassAttractorEntry(const char* entry, const } MESSAGE("ENGINE : SETATTRACTOR END ENTRY : " << entry); //if ( valueChanged ) - //SMESH::TPythonDump() << _this() << ".SetAttractor(" - // << entry << ", '" << attractor << "' )"; - // TODO enable dump + SMESH::TPythonDump() << _this() << ".SetAttractorGeom(" + << entry << ", " << att_entry << ", "<GetImpl()->_GetClassAttractorEntries(); + result->length( attractors.size() ); + + ::BLSURFPlugin_Hypothesis::TAttractorMap::const_iterator atIt = attractors.begin(); + for ( int i = 0 ; atIt != attractors.end(); ++atIt, ++i ) { + string faceEntry = atIt->first; + string attEntry; + double startSize, endSize, infDist, constDist; + if ( !atIt->second->Empty() ) { + attEntry = atIt->second->GetAttractorEntry(); + MESSAGE("GetAttractorParams : attEntry ="< params = atIt->second->GetParameters(); + startSize = params[0]; + endSize = params[1]; + infDist = params[2]; + constDist = params[3]; + } + result[i].faceEntry = CORBA::string_dup(faceEntry.c_str()); + result[i].attEntry = CORBA::string_dup(attEntry.c_str()); + result[i].startSize = startSize; + result[i].endSize = endSize; + result[i].infDist = infDist; + result[i].constDist = constDist; + MESSAGE("GetAttractorParams : result[i].attEntry ="<GetName()); MESSAGE("IDL : SETATTRACTOR () ");//<< entry << " , " << att_entry << ")"); - SetClassAttractorEntry( entry.c_str(), FaceShape, AttractorShape, StartSize, EndSize, ActionRadius, ConstantRadius); + SetClassAttractorEntry( entry.c_str(), att_entry.c_str(), StartSize, EndSize, ActionRadius, ConstantRadius); } void BLSURFPlugin_Hypothesis_i::UnsetAttractorGeom(GEOM::GEOM_Object_ptr GeomObj) @@ -833,7 +867,7 @@ void BLSURFPlugin_Hypothesis_i::UnsetAttractorGeom(GEOM::GEOM_Object_ptr GeomObj MESSAGE("IDL : GetName : " << GeomObj->GetName()); MESSAGE("IDL : UNSETATTRACTOR ( "<< entry << ")"); UnsetEntry( entry.c_str()); - SMESH::TPythonDump() << _this() << ".UnsetAttractor( " << entry.c_str() << " )"; + SMESH::TPythonDump() << _this() << ".UnsetAttractorGeom( " << entry.c_str() << " )"; } diff --git a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx index d3bce63..b3d12ee 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx @@ -129,15 +129,18 @@ class BLSURFPlugin_Hypothesis_i: BLSURFPlugin::string_array* GetAttractorEntries(); + /*! + * Set/get/unset an attractor on a face + */ + void SetAttractorGeom(GEOM::GEOM_Object_ptr GeomObj, GEOM::GEOM_Object_ptr Attractor, double StartSize, double EndSize, double ActionRadius, double ConstantRadius ); void UnsetAttractorGeom(GEOM::GEOM_Object_ptr GeomObj); - void SetClassAttractorEntry(const char* entry,const TopoDS_Face& FaceShape, const TopoDS_Shape& AttractorShape, double StartSize, double EndSize, double ActionRadius, double ConstantRadius) throw (SALOME::SALOME_Exception); + void SetClassAttractorEntry(const char* entry, const char* att_entry, double StartSize, double EndSize, double ActionRadius, double ConstantRadius) throw (SALOME::SALOME_Exception); - //char* GetAttractorEntry(const char* entry) throw (SALOME::SALOME_Exception); - - //BLSURFPlugin_Attractor GetClassAttractorEntries(); + BLSURFPlugin::TAttParamsMap* GetAttractorParams(); + /* diff --git a/src/GUI/BLSURFPluginGUI_HypothesisCreator.cxx b/src/GUI/BLSURFPluginGUI_HypothesisCreator.cxx index 824d2ac..e895b6e 100644 --- a/src/GUI/BLSURFPluginGUI_HypothesisCreator.cxx +++ b/src/GUI/BLSURFPluginGUI_HypothesisCreator.cxx @@ -110,6 +110,7 @@ enum { SMP_ENTRY_COLUMN = 0, SMP_NAME_COLUMN, SMP_SIZEMAP_COLUMN, + SMP_DIST_COLUMN, SMP_NB_COLUMNS, // Enforced vertices array columns ENF_VER_NAME_COLUMN = 0, @@ -126,13 +127,29 @@ enum { SMP_BTNS = 0, // SMP_ATTRACTOR_BTN, // SMP_SEPARATOR1, - SMP_POINT_BTN, - SMP_EDGE_BTN, - SMP_SURFACE_BTN, +// SMP_POINT_BTN, +// SMP_EDGE_BTN, +// SMP_SURFACE_BTN, + SMP_GEOM_BTN, SMP_SEPARATOR2, + SMP_ATT_GROUP, + SMP_DIST_GROUP, + SMP_ADD_BTN, SMP_REMOVE_BTN, SMP_NB_LINES }; + +enum { + SMP_ATT_BTNS = 0, + SMP_ATT_SHAPE, + SMP_ATT_SIZE, + SMP_ATT_DIST +}; + +enum { + SMP_DIST_BTNS = 0, + SMP_DIST +}; // Enforced vertices inputs enum { @@ -738,39 +755,102 @@ QFrame* BLSURFPluginGUI_HypothesisCreator::buildFrame() QGridLayout* anSmpLayout = new QGridLayout(mySmpGroup); mySizeMapTable = new QTableWidget( 0, SMP_NB_COLUMNS, mySmpGroup ); + //mySizeMapTable->setSortingEnabled(true); QStringList sizeMapHeaders; - sizeMapHeaders << tr( "SMP_ENTRY_COLUMN" )<< tr( "SMP_NAME_COLUMN" ) << tr( "SMP_SIZEMAP_COLUMN" ); + sizeMapHeaders << tr( "SMP_ENTRY_COLUMN" )<< tr( "SMP_NAME_COLUMN" ) << tr( "SMP_SIZEMAP_COLUMN" ) << tr( "SMP_DIST_COLUMN" ); mySizeMapTable->setHorizontalHeaderLabels(sizeMapHeaders); mySizeMapTable->horizontalHeader()->hideSection( SMP_ENTRY_COLUMN ); mySizeMapTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive); + mySizeMapTable->horizontalHeader()->setStretchLastSection(true); + //mySizeMapTable->horizontalHeader()->setProperty("showSortIndicator", QVariant(true)); mySizeMapTable->resizeColumnToContents(SMP_NAME_COLUMN); mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN); + mySizeMapTable->resizeColumnToContents(SMP_DIST_COLUMN); mySizeMapTable->setAlternatingRowColors(true); mySizeMapTable->verticalHeader()->hide(); + mySizeMapTable->setShowGrid(true); + /* addAttractorButton = new QPushButton(tr("BLSURF_SM_ATTRACTOR"),mySmpGroup); QFrame *line = new QFrame(mySmpGroup); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); */ - addSurfaceButton = new QPushButton(tr("BLSURF_SM_SURFACE"),mySmpGroup); - addEdgeButton = new QPushButton(tr("BLSURF_SM_EDGE"),mySmpGroup); - addPointButton = new QPushButton(tr("BLSURF_SM_POINT"),mySmpGroup); + //addSurfaceButton = new QPushButton(tr("BLSURF_SM_SURFACE"),mySmpGroup); + //addEdgeButton = new QPushButton(tr("BLSURF_SM_EDGE"),mySmpGroup); + //addPointButton = new QPushButton(tr("BLSURF_SM_POINT"),mySmpGroup); + + // Filters of selection + TColStd_MapOfInteger SM_ShapeTypes, ATT_ShapeTypes; + + SM_ShapeTypes.Add( TopAbs_VERTEX ); + SM_ShapeTypes.Add( TopAbs_EDGE ); + SM_ShapeTypes.Add( TopAbs_FACE ); + + ATT_ShapeTypes.Add( TopAbs_VERTEX ); + ATT_ShapeTypes.Add( TopAbs_EDGE ); + + SMESH_NumberFilter* myFilter1 = new SMESH_NumberFilter("GEOM", TopAbs_SHAPE, 0, SM_ShapeTypes); + SMESH_NumberFilter* myFilter2 = new SMESH_NumberFilter("GEOM", TopAbs_SHAPE, 0, ATT_ShapeTypes); + + // Size Map GroupBox + myGeomSelWdg = new StdMeshersGUI_ObjectReferenceParamWdg( myFilter1, 0, /*multiSel=*/false,/*stretch=*/false); + myGeomSelWdg->SetDefaultText("Select a Shape", "QLineEdit { color: grey }"); QFrame *line2 = new QFrame(mySmpGroup); line2->setFrameShape(QFrame::HLine); line2->setFrameShadow(QFrame::Sunken); - removeButton = new QPushButton(tr("BLSURF_SM_REMOVE"),mySmpGroup); - - + removeMapButton = new QPushButton(tr("BLSURF_SM_REMOVE"),mySmpGroup); + addMapButton = new QPushButton(tr("BLSURF_SM_ADD"),mySmpGroup); + + // Attractor GroupBox + myAttractorGroup = new QGroupBox(tr("BLSURF_SM_ATTRACTOR"),mySmpGroup); + myAttractorGroup->setCheckable(true); + myAttractorGroup->setChecked(false); + myAttractorGroup->setEnabled(false); + QGridLayout* anAttLayout = new QGridLayout(myAttractorGroup); + myAttDistSpin = new QDoubleSpinBox(myAttractorGroup); + myAttSizeSpin = new QDoubleSpinBox(myAttractorGroup); + QLabel* myAttDistLabel = new QLabel(tr("BLSURF_ATT_DIST"),myAttractorGroup); + QLabel* myAttSizeLabel = new QLabel(tr("BLSURF_ATT_SIZE"),myAttractorGroup); + myAttSelWdg = new StdMeshersGUI_ObjectReferenceParamWdg( myFilter2, myAttractorGroup, /*multiSel=*/false,/*stretch=*/false); + myAttSelWdg->SetDefaultText("Select a Shape", "QLineEdit { color: grey }"); + myAttSelWdg->AvoidSimultaneousSelection(myGeomSelWdg); + + myAttDistSpin->setValue(0.); + myAttSizeSpin->setValue(0.); + // Constant Size GroupBox + myDistanceGroup = new QGroupBox(tr("BLSURF_SM_CONST"),mySmpGroup); + myDistanceGroup->setCheckable(true); + myDistanceGroup->setChecked(false); + myDistanceGroup->setEnabled(false); + QGridLayout* aDistLayout = new QGridLayout(myDistanceGroup); + mySmpDistSpin = new QDoubleSpinBox(myDistanceGroup); + QLabel* mySmpDistLabel = new QLabel(tr("BLSURF_SM_DIST"),myDistanceGroup); + + + // ADD WIDGETS (SIZEMAP TAB) - anSmpLayout->addWidget(mySizeMapTable, SMP_POINT_BTN, 0, SMP_NB_LINES+1, 1); +// anSmpLayout->addWidget(mySizeMapTable, SMP_POINT_BTN, 0, SMP_NB_LINES+1, 1); + anSmpLayout->addWidget(mySizeMapTable, 1, 0, SMP_NB_LINES+1, 1); // anSmpLayout->addWidget(addAttractorButton, SMP_ATTRACTOR_BTN, 1, 1, 1); // anSmpLayout->addWidget(line, SMP_SEPARATOR1, 1, 1, 1); - anSmpLayout->addWidget(addPointButton, SMP_POINT_BTN, 1, 1, 1); - anSmpLayout->addWidget(addEdgeButton, SMP_EDGE_BTN, 1, 1, 1); - anSmpLayout->addWidget(addSurfaceButton, SMP_SURFACE_BTN, 1, 1, 1); - anSmpLayout->addWidget(line2, SMP_SEPARATOR2, 1, 1, 1); - anSmpLayout->addWidget(removeButton, SMP_REMOVE_BTN, 1, 1, 1); +// anSmpLayout->addWidget(addPointButton, SMP_POINT_BTN, 1, 1, 1); +// anSmpLayout->addWidget(addEdgeButton, SMP_EDGE_BTN, 1, 1, 1); +// anSmpLayout->addWidget(addSurfaceButton, SMP_SURFACE_BTN, 1, 1, 1); + anSmpLayout->addWidget(myGeomSelWdg, SMP_GEOM_BTN, 1, 1, 2); + anSmpLayout->addWidget(line2, SMP_SEPARATOR2, 1, 1, 2); + anSmpLayout->addWidget(myAttractorGroup, SMP_ATT_GROUP, 1, 1, 2); + anAttLayout->addWidget(myAttDistLabel, SMP_ATT_DIST, 1, 1, 1); + anAttLayout->addWidget(myAttDistSpin, SMP_ATT_DIST, 2, 1, 1); + anAttLayout->addWidget(myAttSizeLabel, SMP_ATT_SIZE, 1, 1, 1); + anAttLayout->addWidget(myAttSizeSpin, SMP_ATT_SIZE, 2, 1, 1); + anAttLayout->addWidget(myAttSelWdg, SMP_ATT_SHAPE, 1, 1, 2); + anSmpLayout->addWidget(myDistanceGroup, SMP_DIST_GROUP, 1, 1, 2); + aDistLayout->addWidget(mySmpDistLabel, SMP_DIST, 1, 1, 1); + aDistLayout->addWidget(mySmpDistSpin, SMP_DIST, 2, 1, 1); + anSmpLayout->addWidget(addMapButton, SMP_ADD_BTN, 1, 1, 2); + anSmpLayout->addWidget(removeMapButton, SMP_REMOVE_BTN, 1, 1, 2); + // Enforced vertices parameters @@ -888,26 +968,26 @@ QFrame* BLSURFPluginGUI_HypothesisCreator::buildFrame() tab->setCurrentIndex( STD_TAB ); // --- - connect( myGeometricMesh, SIGNAL( activated( int ) ), this, SLOT( onGeometricMeshChanged() ) ); - connect( myPhysicalMesh, SIGNAL( activated( int ) ), this, SLOT( onPhysicalMeshChanged() ) ); - connect( addBtn->menu(), SIGNAL( aboutToShow() ), this, SLOT( onAddOption() ) ); - connect( addBtn->menu(), SIGNAL( triggered( QAction* ) ), this, SLOT( onOptionChosenInPopup( QAction* ) ) ); - connect( rmBtn, SIGNAL( clicked()), this, SLOT( onDeleteOption() ) ); - - connect( addSurfaceButton, SIGNAL( clicked()), this, SLOT( onAddMapOnSurface() ) ); - connect( addEdgeButton, SIGNAL( clicked()), this, SLOT( onAddMapOnEdge() ) ); - connect( addPointButton, SIGNAL( clicked()), this, SLOT( onAddMapOnPoint() ) ); - connect( removeButton, SIGNAL( clicked()), this, SLOT( onRemoveMap() ) ); - connect( mySizeMapTable, SIGNAL( cellChanged ( int, int )), this, SLOT( onSetSizeMap(int,int ) ) ); - - connect( myEnforcedTreeWidget,SIGNAL( itemClicked(QTreeWidgetItem *, int)), this, SLOT( synchronizeCoords() ) ); - connect( myEnforcedTreeWidget,SIGNAL( itemChanged(QTreeWidgetItem *, int)), this, SLOT( update(QTreeWidgetItem *, int) ) ); - connect( myEnforcedTreeWidget,SIGNAL( itemSelectionChanged() ), this, SLOT( synchronizeCoords() ) ); - connect( addVertexButton, SIGNAL( clicked()), this, SLOT( onAddEnforcedVertices() ) ); - connect( removeVertexButton, SIGNAL( clicked()), this, SLOT( onRemoveEnforcedVertex() ) ); - connect( myEnfVertexWdg, SIGNAL( contentModified()), this, SLOT( onSelectEnforcedVertex() ) ); -// connect( myEnfVertexWdg, SIGNAL( selectionActivated()), this, SLOT( onVertexSelectionActivated() ) ); -// connect( myEnfFaceWdg, SIGNAL( selectionActivated()), this, SLOT( onFaceSelectionActivated() ) ); + connect( myGeometricMesh, SIGNAL( activated( int ) ), this, SLOT( onGeometricMeshChanged() ) ); + connect( myPhysicalMesh, SIGNAL( activated( int ) ), this, SLOT( onPhysicalMeshChanged() ) ); + connect( addBtn->menu(), SIGNAL( aboutToShow() ), this, SLOT( onAddOption() ) ); + connect( addBtn->menu(), SIGNAL( triggered( QAction* ) ), this, SLOT( onOptionChosenInPopup( QAction* ) ) ); + connect( rmBtn, SIGNAL( clicked()), this, SLOT( onDeleteOption() ) ); + // Size Maps + connect( addMapButton, SIGNAL( clicked()), this, SLOT( onAddMap() ) ); + connect( removeMapButton, SIGNAL( clicked()), this, SLOT( onRemoveMap() ) ); + connect( mySizeMapTable, SIGNAL( cellChanged ( int, int )), this, SLOT( onSetSizeMap(int,int ) ) ); + connect( mySizeMapTable, SIGNAL( itemClicked (QTableWidgetItem *)),this, SLOT( onItemClicked(QTableWidgetItem *) ) ); + connect( myGeomSelWdg, SIGNAL( contentModified() ), this, SLOT( onMapGeomContentModified() ) ); + connect( myAttractorGroup, SIGNAL( clicked(bool) ), this, SLOT( onAttractorGroupClicked(bool) ) ); + + // Enforced vertices + connect( myEnforcedTreeWidget,SIGNAL( itemClicked(QTreeWidgetItem *, int)), this, SLOT( synchronizeCoords() ) ); + connect( myEnforcedTreeWidget,SIGNAL( itemChanged(QTreeWidgetItem *, int)), this, SLOT( update(QTreeWidgetItem *, int) ) ); + connect( myEnforcedTreeWidget,SIGNAL( itemSelectionChanged() ), this, SLOT( synchronizeCoords() ) ); + connect( addVertexButton, SIGNAL( clicked()), this, SLOT( onAddEnforcedVertices() ) ); + connect( removeVertexButton, SIGNAL( clicked()), this, SLOT( onRemoveEnforcedVertex() ) ); + connect( myEnfVertexWdg, SIGNAL( contentModified()), this, SLOT( onSelectEnforcedVertex() ) ); return fr; } @@ -1323,13 +1403,13 @@ void BLSURFPluginGUI_HypothesisCreator::retrieveParams() const myOptionTable->resizeColumnToContents( OPTION_NAME_COLUMN ); // Sizemaps -// MESSAGE("retrieveParams():that->mySMPMap.size() = " << that->mySMPMap.size()); + MESSAGE("retrieveParams():that->mySMPMap.size() = " << that->mySMPMap.size()); QMapIterator i(that->mySMPMap); GeomSelectionTools* myGeomToolSelected = that->getGeomSelectionTool(); while (i.hasNext()) { i.next(); const QString entry = i.key(); - string shapeName = myGeomToolSelected->getNameFromEntry(entry.toStdString()); + string shapeName = myGeomToolSelected->getNameFromEntry(entry.toStdString()); const QString sizeMap = i.value(); int row = mySizeMapTable->rowCount(); mySizeMapTable->setRowCount( row+1 ); @@ -1337,11 +1417,25 @@ void BLSURFPluginGUI_HypothesisCreator::retrieveParams() const mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->setFlags( 0 ); mySizeMapTable->setItem( row, SMP_NAME_COLUMN, new QTableWidgetItem( QString::fromStdString(shapeName) ) ); mySizeMapTable->item( row, SMP_NAME_COLUMN )->setFlags( 0 ); - mySizeMapTable->setItem( row, SMP_SIZEMAP_COLUMN, new QTableWidgetItem( sizeMap ) ); - mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->setFlags( Qt::ItemIsSelectable | + if (that->myATTMap.contains(entry)){ + const QString attEntry = that->myATTMap[entry]; + MESSAGE("attEntry = "<getNameFromEntry(attEntry.toStdString()); + MESSAGE("attName = "<setItem( row, SMP_SIZEMAP_COLUMN, new QTableWidgetItem( QString::fromStdString("Attractor :" + attName) ) ); + mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->setFlags( Qt::ItemIsSelectable | + Qt::ItemIsEnabled ); + } + else + { + mySizeMapTable->setItem( row, SMP_SIZEMAP_COLUMN, new QTableWidgetItem( sizeMap ) ); + mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled ); } + mySizeMapTable->setItem( row, SMP_DIST_COLUMN, new QTableWidgetItem( QString::number( that->myDistMap[entry], 'g', 6) ) ); + mySizeMapTable->item( row, SMP_DIST_COLUMN )->setFlags( 0 ); + } mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN ); mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN); @@ -1448,6 +1542,9 @@ bool BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo( BlsurfHypothesisData that->myOptions = h->GetOptionValues(); that->mySMPMap.clear(); + that->myATTMap.clear(); + that->myAttDistMap.clear(); + that->myDistMap.clear(); // classic size maps BLSURFPlugin::string_array_var mySizeMaps = h->GetSizeMapEntries(); @@ -1508,6 +1605,25 @@ bool BLSURFPluginGUI_HypothesisCreator::readParamsFromHypo( BlsurfHypothesisData } } + // attractor new version + MESSAGE("retriveParams, Attractors") + BLSURFPlugin::TAttParamsMap_var allMyAttractorParams = h->GetAttractorParams(); + for ( int i = 0;ilength(); ++i ) { + BLSURFPlugin::TAttractorParams myAttractorParams = allMyAttractorParams[i]; + QString faceEntry = myAttractorParams.faceEntry.in(); + QString attEntry = myAttractorParams.attEntry.in(); + MESSAGE("attEntry = "<mySMPMap[faceEntry] = QString::number( startSize, 'g', 6 ); // TODO utiliser les préférences ici (cf. sketcher) + that->mySMPShapeTypeMap[faceEntry] = myGeomToolSelected->entryToShapeType(faceEntry.toStdString()); + that->myATTMap[faceEntry] = attEntry; + that->myAttDistMap[faceEntry] = infDist; + that->myDistMap[faceEntry] = constDist; + } + // Enforced vertices h_data.coordsList.clear(); h_data.entryCoordsListMap.clear(); @@ -1641,6 +1757,9 @@ bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesi BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; QMapIterator i(that->mySMPMap); + // QMapIterator att_it(that->myATTMap); + // QMapIterator inf_dist_it(that->myAttDistMap); + // QMapIterator const_dist_it(that->myDistMap) // Iterate over each size map while (i.hasNext()) { i.next(); @@ -1648,7 +1767,7 @@ bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesi const QString sizeMap = i.value(); if (sizeMap == "__TO_DELETE__") { -// MESSAGE("Delete entry " << entry.toStdString() << " from engine"); + MESSAGE("Delete entry " << entry.toStdString() << " from engine"); h->UnsetEntry(entry.toLatin1().constData()); } else if (sizeMap.startsWith("ATTRACTOR")) { @@ -1660,17 +1779,31 @@ bool BLSURFPluginGUI_HypothesisCreator::storeParamsToHypo( const BlsurfHypothesi // h->SetCustomSizeMapEntry( entry.toLatin1().constData(), sizeMap.toLatin1().constData() ); } else { - QString fullSizeMap; - fullSizeMap = QString(""); - if (that->mySMPShapeTypeMap[entry] == TopAbs_FACE) - fullSizeMap = QString("def f(u,v): return ") + sizeMap; - else if (that->mySMPShapeTypeMap[entry] == TopAbs_EDGE) - fullSizeMap = QString("def f(t): return ") + sizeMap; - else if (that->mySMPShapeTypeMap[entry] == TopAbs_VERTEX) - fullSizeMap = QString("def f(): return ") + sizeMap; - -// MESSAGE("SetSizeMapEntry("<SetSizeMapEntry( entry.toLatin1().constData(), fullSizeMap.toLatin1().constData() ); + // TODO coder le stockage des parametres ici dans l'idee de ce qui est fait en dessous + if (!myATTMap[entry].isEmpty()){ + QString att_entry = myATTMap[entry]; + double infDist = myAttDistMap[entry]; + double constDist = myDistMap[entry]; + double phySize = h->GetPhySize(); + //double const_dist = myDistMap[entry]; + h->SetClassAttractorEntry( entry.toLatin1().constData(), att_entry.toLatin1().constData(), sizeMap.toDouble() , phySize, infDist, constDist ); + } +// else if( myAttDistMap[entry] > 1e-12) { +// h->SetConstantSizeOnAdjacentFaces(att_entry.toLatin1().constData(), conversion en double (sizeMap), endSize = user_size, const_dist ) +// } + else { + QString fullSizeMap; + fullSizeMap = QString(""); + if (that->mySMPShapeTypeMap[entry] == TopAbs_FACE) + fullSizeMap = QString("def f(u,v): return ") + sizeMap; + else if (that->mySMPShapeTypeMap[entry] == TopAbs_EDGE) + fullSizeMap = QString("def f(t): return ") + sizeMap; + else if (that->mySMPShapeTypeMap[entry] == TopAbs_VERTEX) + fullSizeMap = QString("def f(): return ") + sizeMap; + + // MESSAGE("SetSizeMapEntry("<SetSizeMapEntry( entry.toLatin1().constData(), fullSizeMap.toLatin1().constData() ); + } } } @@ -2086,6 +2219,36 @@ void BLSURFPluginGUI_HypothesisCreator::onDeleteOption() // *** BEGIN SIZE MAP *** // ********************** +void BLSURFPluginGUI_HypothesisCreator::onMapGeomContentModified() +{ + if ( myGeomSelWdg->IsObjectSelected() ){ + mySMapObject = myGeomSelWdg->GetObject< GEOM::GEOM_Object >(0); + TopAbs_ShapeEnum myShapeType = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( mySMapObject ).ShapeType(); + if ( myShapeType == TopAbs_FACE ){ + myAttractorGroup->setEnabled(true); + if (!myAttractorGroup->isChecked()){ + myDistanceGroup->setEnabled(false); + } + } + else + { + myAttractorGroup->setEnabled(false); + myAttractorGroup->setChecked(false); + myDistanceGroup->setEnabled(true); + } + } + +} + +void BLSURFPluginGUI_HypothesisCreator::onAttractorGroupClicked(bool checked){ + if (checked){ + myDistanceGroup->setEnabled(true); + } + else{ + myDistanceGroup->setEnabled(false); + } +} + void BLSURFPluginGUI_HypothesisCreator::onRemoveMap() { @@ -2112,15 +2275,70 @@ void BLSURFPluginGUI_HypothesisCreator::onRemoveMap() that->mySMPMap[entry] = "__TO_DELETE__"; if (that->mySMPShapeTypeMap.contains(entry)) that->mySMPShapeTypeMap.remove(entry); + if (that->myATTMap.contains(entry)) + that->myATTMap.remove(entry); + if (that->myDistMap.contains(entry)) + that->myDistMap.remove(entry); + if (that->myAttDistMap.contains(entry)) + that->myAttDistMap.remove(entry); mySizeMapTable->removeRow(row ); } mySizeMapTable->resizeColumnToContents(SMP_NAME_COLUMN); mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN); } +CORBA::Object_var BLSURFPluginGUI_HypothesisCreator::entryToObject(QString entry) +{ + SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen(); + SALOMEDS::Study_ptr myStudy = smeshGen_i->GetCurrentStudy(); + CORBA::Object_var obj; + SALOMEDS::GenericAttribute_var anAttr; + SALOMEDS::SObject_var aSObj = myStudy->FindObjectID( entry.toStdString().c_str() ); + if (!aSObj->_is_nil() && aSObj->FindAttribute(anAttr, "AttributeIOR")) { + SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr); + CORBA::String_var aVal = anIOR->Value(); + obj = myStudy->ConvertIORToObject(aVal); + } + return obj; +} + +void BLSURFPluginGUI_HypothesisCreator::onItemClicked(QTableWidgetItem * item) +{ + int row = item->row(); + int col = item->column(); + MESSAGE("BLSURFPluginGUI_HypothesisCreator::onCellClicked("<mySizeMapTable->item(row, SMP_ENTRY_COLUMN)->text(); + QString sizeMap = that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->text().trimmed(); + + if (sizeMap.startsWith("Attractor :")){ + myAttractorGroup->setChecked( true ); + myDistanceGroup->setChecked( true ); + double phySize = that->mySMPMap[entry].toDouble(); + double infDist = that->myAttDistMap[entry]; + QString attEntry = that->myATTMap[entry]; + CORBA::Object_var attObj = entryToObject(attEntry); + + myAttSelWdg->SetObject(attObj); + myAttSizeSpin->setValue(phySize); + myAttDistSpin->setValue(infDist); + } + else { + myAttractorGroup->setChecked( false ); + } + CORBA::Object_var obj = entryToObject(entry); + double constDist = that->myDistMap[entry]; + + myGeomSelWdg->SetObject(obj); + mySmpDistSpin->setValue(constDist); + } +} + void BLSURFPluginGUI_HypothesisCreator::onSetSizeMap(int row,int col) { MESSAGE("BLSURFPluginGUI_HypothesisCreator::onSetSizeMap("<< row << "," << col << ")"); + MESSAGE("mySMPMap.size() = "<mySizeMapTable->item(row, SMP_ENTRY_COLUMN)->text(); @@ -2129,113 +2347,204 @@ void BLSURFPluginGUI_HypothesisCreator::onSetSizeMap(int row,int col) if (! that->mySMPShapeTypeMap.contains(entry)) return; if (that->mySMPMap.contains(entry)) - if (that->mySMPMap[entry] == sizeMap) + if (that->mySMPMap[entry] == sizeMap || sizeMap.startsWith("Attractor :")){ return; - QColor* bgColor = new QColor("white"); - QColor* fgColor = new QColor("black"); + } +// QColor* bgColor = new QColor("white"); +// QColor* fgColor = new QColor("black"); + if (! sizeMap.isEmpty()) { that->mySMPMap[entry] = sizeMap; - if (! sizeMapValidationFromRow(row)) { - bgColor->setRgb(255,0,0); - fgColor->setRgb(255,255,255); - } + sizeMapValidationFromRow(row); +// if (! sizeMapValidationFromRow(row)) { +// bgColor->setRgb(255,0,0); +// fgColor->setRgb(255,255,255); +// } } else { -// MESSAGE("Size map empty: reverse to precedent value" ); + MESSAGE("Size map empty: reverse to precedent value" ); + } + if (sizeMap.isEmpty()) { that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setText(that->mySMPMap[entry]); } - that->mySizeMapTable->item(row, SMP_NAME_COLUMN)->setBackground(QBrush(*bgColor)); - that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setBackground(QBrush(*bgColor)); - that->mySizeMapTable->item(row, SMP_NAME_COLUMN)->setForeground(QBrush(*fgColor)); - that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setForeground(QBrush(*fgColor)); +// that->mySizeMapTable->item(row, SMP_NAME_COLUMN)->setBackground(QBrush(*bgColor)); +// that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setBackground(QBrush(*bgColor)); +// that->mySizeMapTable->item(row, SMP_NAME_COLUMN)->setForeground(QBrush(*fgColor)); +// that->mySizeMapTable->item(row, SMP_SIZEMAP_COLUMN)->setForeground(QBrush(*fgColor)); mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN); } } -void BLSURFPluginGUI_HypothesisCreator::onAddMapOnSurface() +void BLSURFPluginGUI_HypothesisCreator::onAddMap() { - insertElementType(TopAbs_FACE); + if ( myGeomSelWdg->IsObjectSelected() ){ + mySMapObject = myGeomSelWdg->GetObject< GEOM::GEOM_Object >(0); + if ( myAttractorGroup->isChecked() ){ + if ( myAttSelWdg->IsObjectSelected() ){ + myAttObject = myAttSelWdg->GetObject< GEOM::GEOM_Object >(0); + insertAttractor(mySMapObject, myAttObject); + } + } + else { + insertElement(mySMapObject); + } + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + that->getGeomSelectionTool()->selectionMgr()->clearFilters(); + myGeomSelWdg->deactivateSelection(); + myAttSizeSpin->clear(); + myAttDistSpin->clear(); + } } -void BLSURFPluginGUI_HypothesisCreator::onAddMapOnEdge() +void BLSURFPluginGUI_HypothesisCreator::insertElement(GEOM::GEOM_Object_var anObject) { - insertElementType(TopAbs_EDGE); + MESSAGE("BLSURFPluginGUI_HypothesisCreator::insertElement()"); + BLSURFPlugin::BLSURFPlugin_Hypothesis_var h = + BLSURFPlugin::BLSURFPlugin_Hypothesis::_narrow( initParamsHypothesis()); + + BLSURFPluginGUI_HypothesisCreator* that = (BLSURFPluginGUI_HypothesisCreator*)this; + + TopAbs_ShapeEnum shapeType; + string entry, shapeName; + entry = (string) anObject->GetStudyEntry(); + MESSAGE("entry = "<GetName(); + shapeType = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( anObject ).ShapeType(); + mySizeMapTable->setFocus(); + QString shapeEntry; + shapeEntry = QString::fromStdString(entry); + double phySize = h->GetPhySize(); + std::ostringstream oss; + oss << phySize; + QString sizeMap; + sizeMap = QString::fromStdString(oss.str()); + if (that->mySMPMap.contains(shapeEntry)) { + if (that->mySMPMap[shapeEntry] != "__TO_DELETE__") { +// MESSAGE("Size map for shape with name(entry): "<< shapeName << "(" << entry << ")"); + return; + } + } + that->mySMPMap[shapeEntry] = sizeMap; + that->myDistMap[shapeEntry] = 0. ; + that->mySMPShapeTypeMap[shapeEntry] = shapeType; + int row = mySizeMapTable->rowCount(); + mySizeMapTable->setRowCount( row + 1 ); + mySizeMapTable->setItem( row, SMP_ENTRY_COLUMN, new QTableWidgetItem( shapeEntry ) ); + mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->setFlags( 0 ); + mySizeMapTable->setItem( row, SMP_NAME_COLUMN, new QTableWidgetItem( QString::fromStdString(shapeName) ) ); + mySizeMapTable->item( row, SMP_NAME_COLUMN )->setFlags( 0 ); + mySizeMapTable->setItem( row, SMP_SIZEMAP_COLUMN, new QTableWidgetItem( sizeMap ) ); + mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->setFlags( Qt::ItemIsSelectable |Qt::ItemIsEditable |Qt::ItemIsEnabled ); + mySizeMapTable->setItem( row, SMP_DIST_COLUMN, new QTableWidgetItem( ) ); + mySizeMapTable->item( row, SMP_DIST_COLUMN )->setFlags( 0 ); + mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN ); + mySizeMapTable->resizeColumnToContents( SMP_SIZEMAP_COLUMN ); + mySizeMapTable->resizeColumnToContents( SMP_DIST_COLUMN ); + mySizeMapTable->clearSelection(); + mySizeMapTable->scrollToItem( mySizeMapTable->item( row , SMP_SIZEMAP_COLUMN ) ); + + if ( myPhysicalMesh->currentIndex() != SizeMap ) { + myPhysicalMesh->setCurrentIndex( SizeMap ); + onPhysicalMeshChanged(); + } } -void BLSURFPluginGUI_HypothesisCreator::onAddMapOnPoint() -{ - insertElementType(TopAbs_VERTEX); +int BLSURFPluginGUI_HypothesisCreator::findRowFromEntry(QString entry){ + QString entryForChecking; + int endRow = mySizeMapTable->rowCount()-1; + int row = 0; + entryForChecking = mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->text(); + while (entry != entryForChecking && row <= endRow){ + row++; + entryForChecking = mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->text(); + } + MESSAGE("BLSURFPluginGUI_HypothesisCreator::findRowFromEntry; row = "<getGeomSelectionTool(); - - LightApp_SelectionMgr* mySel = myGeomToolSelected->selectionMgr(); TopAbs_ShapeEnum shapeType; - string entry, shapeName; - SALOME_ListIO ListSelectedObjects; - mySel->selectedObjects(ListSelectedObjects, NULL, false ); - if (!ListSelectedObjects.IsEmpty()) - { - SALOME_ListIteratorOfListIO Object_It(ListSelectedObjects); - for (; Object_It.More(); Object_It.Next()) - { - Handle(SALOME_InteractiveObject) anObject = Object_It.Value(); - entry = myGeomToolSelected->getEntryOfObject(anObject); - shapeName = anObject->getName(); - shapeType = myGeomToolSelected->entryToShapeType(entry); -// MESSAGE("Object Name = " << shapeName << "& Type is " << anObject->getComponentDataType() << " & ShapeType is " << shapeType); - if (shapeType == typeShapeAsked) - { - mySizeMapTable->setFocus(); - QString shapeEntry; - shapeEntry = QString::fromStdString(entry); - double phySize = h->GetPhySize(); - std::ostringstream oss; - oss << phySize; - QString sizeMap; - sizeMap = QString::fromStdString(oss.str()); - if (that->mySMPMap.contains(shapeEntry)) { - if (that->mySMPMap[shapeEntry] != "__TO_DELETE__") { -// MESSAGE("Size map for shape with name(entry): "<< shapeName << "(" << entry << ")"); - break; - } - } - that->mySMPMap[shapeEntry] = sizeMap; - that->mySMPShapeTypeMap[shapeEntry] = typeShapeAsked; - int row = mySizeMapTable->rowCount() ; - mySizeMapTable->setRowCount( row+1 ); - mySizeMapTable->setItem( row, SMP_ENTRY_COLUMN, new QTableWidgetItem( shapeEntry ) ); - mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->setFlags( 0 ); - mySizeMapTable->setItem( row, SMP_NAME_COLUMN, new QTableWidgetItem( QString::fromStdString(shapeName) ) ); - mySizeMapTable->item( row, SMP_NAME_COLUMN )->setFlags( 0 ); - mySizeMapTable->setItem( row, SMP_SIZEMAP_COLUMN, new QTableWidgetItem( sizeMap ) ); - mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->setFlags( Qt::ItemIsSelectable |Qt::ItemIsEditable |Qt::ItemIsEnabled ); - mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN ); - mySizeMapTable->resizeColumnToContents(SMP_SIZEMAP_COLUMN); - mySizeMapTable->clearSelection(); - mySizeMapTable->scrollToItem( mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN ) ); - - if ( myPhysicalMesh->currentIndex() != SizeMap ) { - myPhysicalMesh->setCurrentIndex( SizeMap ); - onPhysicalMeshChanged(); - } - } - } + string entry, attEntry, faceName, attName; + entry = (string) aFace->GetStudyEntry(); + attEntry = (string) anAttractor->GetStudyEntry(); + faceName = aFace->GetName(); + attName = anAttractor->GetName(); + shapeType = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( aFace ).ShapeType(); + mySizeMapTable->setFocus(); + QString shapeEntry = QString::fromStdString(entry); + QString qAttEntry = QString::fromStdString(attEntry); + + //double phySize = h->GetPhySize(); + double phySize = myAttSizeSpin->value(); + double infDist = myAttDistSpin->value(); + double constDist = 0. ; + if (myDistanceGroup->isChecked()){ + constDist = mySmpDistSpin->value(); + } + std::ostringstream oss; + std::ostringstream oss2; + std::ostringstream oss3; + oss << phySize; + oss2 << infDist; + oss3 << constDist; + QString sizeMap = QString::fromStdString(oss.str()); + QString infDistString = QString::fromStdString(oss2.str()); + QString constDistString = QString::fromStdString(oss3.str()); + + int row = mySizeMapTable->rowCount(); + int rowToChange; + if (!that->mySMPMap.contains(shapeEntry)) { + mySizeMapTable->setRowCount( row + 1 ); + mySizeMapTable->setItem( row, SMP_ENTRY_COLUMN, new QTableWidgetItem( ) ); + mySizeMapTable->item( row, SMP_ENTRY_COLUMN )->setFlags( 0 ); + mySizeMapTable->setItem( row, SMP_NAME_COLUMN, new QTableWidgetItem( ) ); + mySizeMapTable->item( row, SMP_NAME_COLUMN )->setFlags( 0 ); + mySizeMapTable->setItem( row, SMP_SIZEMAP_COLUMN, new QTableWidgetItem( ) ); + mySizeMapTable->item( row, SMP_SIZEMAP_COLUMN )->setFlags( Qt::ItemIsSelectable |Qt::ItemIsEnabled ); + mySizeMapTable->setItem( row, SMP_DIST_COLUMN, new QTableWidgetItem( ) ); + mySizeMapTable->item( row, SMP_DIST_COLUMN )->setFlags( Qt::ItemIsSelectable |Qt::ItemIsEditable |Qt::ItemIsEnabled); + rowToChange = row; + } + // if (that->mySMPMap[shapeEntry] != "__TO_DELETE__") { +// // MESSAGE("Size map for shape with name(entry): "<< shapeName << "(" << entry << ")"); +// return; +// } + else { + rowToChange = findRowFromEntry(shapeEntry); + MESSAGE("rowToChange = "<mySMPMap.insert(shapeEntry,sizeMap); + that->myATTMap.insert(shapeEntry,qAttEntry); + that->myAttDistMap.insert(shapeEntry,infDist); + that->myDistMap.insert(shapeEntry,constDist); + that->mySMPShapeTypeMap.insert(shapeEntry,shapeType); + mySizeMapTable->item( rowToChange, SMP_ENTRY_COLUMN )->setText(shapeEntry); + mySizeMapTable->item( rowToChange, SMP_NAME_COLUMN )->setText( QString::fromStdString(faceName)); + mySizeMapTable->item( rowToChange, SMP_SIZEMAP_COLUMN )->setText(QString::fromStdString("Attractor : "+attName)); + mySizeMapTable->item( rowToChange, SMP_DIST_COLUMN )->setText(constDistString ); + mySizeMapTable->resizeColumnToContents( SMP_NAME_COLUMN ); + mySizeMapTable->resizeColumnToContents( SMP_SIZEMAP_COLUMN ); + mySizeMapTable->resizeColumnToContents( SMP_DIST_COLUMN ); + mySizeMapTable->clearSelection(); + mySizeMapTable->scrollToItem( mySizeMapTable->item( row , SMP_SIZEMAP_COLUMN ) ); + + if ( myPhysicalMesh->currentIndex() != SizeMap ) { + myPhysicalMesh->setCurrentIndex( SizeMap ); + onPhysicalMeshChanged(); } + MESSAGE("mySMPMap.size() = "<rowCount(); for ( ; row < nbRows; ++row ) if (! sizeMapValidationFromRow(row)) @@ -2245,7 +2554,7 @@ bool BLSURFPluginGUI_HypothesisCreator::sizeMapsValidation() bool BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow(int myRow, bool displayError) { -// MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow()"); + MESSAGE("BLSURFPluginGUI_HypothesisCreator::sizeMapValidationFromRow(), row = "<item( myRow, SMP_ENTRY_COLUMN )->text(); bool res = sizeMapValidationFromEntry(myEntry,displayError); mySizeMapTable->setFocus(); diff --git a/src/GUI/BLSURFPluginGUI_HypothesisCreator.h b/src/GUI/BLSURFPluginGUI_HypothesisCreator.h index ffb57e2..a412e70 100644 --- a/src/GUI/BLSURFPluginGUI_HypothesisCreator.h +++ b/src/GUI/BLSURFPluginGUI_HypothesisCreator.h @@ -69,9 +69,11 @@ class QTableWidget; class QTreeWidget; class QModelIndex; class QSpinBox; +class QDoubleSpinBox; class QMenu; class QAction; class QTreeWidgetItem; +class QTableWidgetItem; class SMESHGUI_SpinBox; class LightApp_SelectionMgr; @@ -137,7 +139,11 @@ public: virtual bool checkParams() const; virtual QString helpPage() const; - void insertElementType( TopAbs_ShapeEnum ); + //void insertElementType( TopAbs_ShapeEnum ); + void insertElement( GEOM::GEOM_Object_var ); + void insertAttractor(GEOM::GEOM_Object_var, GEOM::GEOM_Object_var); + int findRowFromEntry(QString entry); + CORBA::Object_var entryToObject(QString entry); static LightApp_SelectionMgr* selectionMgr(); protected: @@ -156,9 +162,11 @@ protected slots: void onDeleteOption(); void onOptionChosenInPopup( QAction* ); // void onAddAttractor(); - void onAddMapOnSurface(); - void onAddMapOnEdge(); - void onAddMapOnPoint(); +// void onMapSelectionActivated(); + void onMapGeomContentModified(); + void onAttractorGroupClicked(bool); + void onItemClicked( QTableWidgetItem * ); + void onAddMap(); void onRemoveMap(); void onSetSizeMap(int,int); @@ -209,8 +217,19 @@ private: QPushButton *addSurfaceButton; QPushButton *addEdgeButton; QPushButton *addPointButton; - QPushButton *removeButton; - + QPushButton *addMapButton; + QPushButton *removeMapButton; + QGroupBox *myAttractorGroup; + QGroupBox *myDistanceGroup; + QDoubleSpinBox *myAttSizeSpin; + QDoubleSpinBox *myAttDistSpin; + QDoubleSpinBox *mySmpDistSpin; + // Sizemap widgets + StdMeshersGUI_ObjectReferenceParamWdg *myGeomSelWdg; + StdMeshersGUI_ObjectReferenceParamWdg *myAttSelWdg; + GEOM::GEOM_Object_var mySMapObject; + GEOM::GEOM_Object_var myAttObject; + QWidget* myEnfGroup; // TODO FACE AND VERTEX SELECTION StdMeshersGUI_ObjectReferenceParamWdg *myEnfFaceWdg; @@ -218,6 +237,8 @@ private: StdMeshersGUI_ObjectReferenceParamWdg *myEnfVertexWdg; GEOM::GEOM_Object_var myEnfVertex; + + // DlgBlSurfHyp_Enforced* myEnforcedVertexWidget; QTreeWidget* myEnforcedTreeWidget; SMESHGUI_SpinBox* myXCoord; @@ -232,7 +253,10 @@ private: QPushButton* removeVertexButton; // map = entry , size map - QMap mySMPMap; + QMap mySMPMap; // Map + QMap myATTMap; // Map + QMap myDistMap; // Map + QMap myAttDistMap; // Map QMap mySMPShapeTypeMap; GeomSelectionTools* GeomToolSelected; LightApp_SelectionMgr* aSel; diff --git a/src/GUI/BLSURFPlugin_msg_en.ts b/src/GUI/BLSURFPlugin_msg_en.ts index a3e21dd..7c2433c 100644 --- a/src/GUI/BLSURFPlugin_msg_en.ts +++ b/src/GUI/BLSURFPlugin_msg_en.ts @@ -135,6 +135,10 @@ SMP_SIZEMAP_COLUMN Local size + + SMP_DIST_COLUMN + Constant size dist. + BLSURF_SM_SURFACE On face (or group) @@ -151,6 +155,22 @@ BLSURF_SM_ATTRACTOR Add Attractor + + BLSURF_ATT_DIST + Influence dist. + + + BLSURF_SM_CONST + Keep size constant + + + BLSURF_SM_DIST + Distance + + + BLSURF_SM_ADD + Add + BLSURF_SM_REMOVE Remove