From f9d184932396590fe9eddb5d38a2be34054eba8e Mon Sep 17 00:00:00 2001 From: mpv Date: Wed, 24 May 2017 15:01:13 +0300 Subject: [PATCH] Make name of level-2 sub-shape in the sketch naming equal as it is named at level-1 (reproduced in bearing_puller test as name-instability) --- src/Model/Model_ResultConstruction.cpp | 229 +++++++++++++++---------- 1 file changed, 138 insertions(+), 91 deletions(-) diff --git a/src/Model/Model_ResultConstruction.cpp b/src/Model/Model_ResultConstruction.cpp index 7637544de..18d3cdcf8 100644 --- a/src/Model/Model_ResultConstruction.cpp +++ b/src/Model/Model_ResultConstruction.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include // identifier that it is full result selected, but in external document (for internal index is 0) @@ -122,19 +123,11 @@ void Model_ResultConstruction::setIsConcealed(const bool theValue) static const int kSTART_VERTEX_DELTA = 1000000; -static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape, +static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape, std::string theFullName, const int theID, std::shared_ptr theDoc, - bool theSelectionMode, - std::map& theOrientations, - // name of sub-elements by ID to be exported instead of indexes - std::map& theSubNames, - Handle(TDataStd_IntPackedMap) theRefs = Handle(TDataStd_IntPackedMap)(), - const int theOrientation = 0) + bool theSelectionMode) { TDF_Label aLab = theID == 0 ? theMainLabel : theMainLabel.FindChild(theID); - if (theOrientation != 0) { // store the orientation of edge relatively to face if needed - TDataStd_Integer::Set(aLab, theOrientation); - } TNaming_Builder aBuilder(aLab); // wire never happens as sub, it must be generated to be found // by SelectionNaming TNaming_Tool::NamedShape @@ -142,40 +135,139 @@ static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape, aBuilder.Select(theShape, theShape); else aBuilder.Generated(theShape); + + theDoc->addNamingName(aLab, theFullName); + TDataStd_Name::Set(aLab, theFullName.c_str()); +} + +// generates a full-name for sub-element of the composite feature (sketch) +std::string fullName(CompositeFeaturePtr theComposite, const TopoDS_Shape& theSubShape, + Handle(TDataStd_IntPackedMap) theRefs = Handle(TDataStd_IntPackedMap)()) +{ + TopAbs_ShapeEnum aShapeType = theSubShape.ShapeType(); + gp_Pnt aVertexPos; + TColStd_MapOfTransient allCurves; + if (aShapeType == TopAbs_VERTEX) { // compare positions + aVertexPos = BRep_Tool::Pnt(TopoDS::Vertex(theSubShape)); + } else { + for(TopExp_Explorer anEdgeExp(theSubShape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next()) { + TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExp.Current()); + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + allCurves.Add(aCurve); + } + } + std::map anOrientations; //map from edges IDs to orientations of these edges in face + std::map aSubNames; //map from edges IDs to names of edges + TColStd_PackedMapOfInteger aRefs; // indixes of sub-elements in composite + + const int aSubNum = theComposite->numberOfSubs(); + for(int a = 0; a < aSubNum; a++) { + FeaturePtr aSub = theComposite->subFeature(a); + const std::list >& aResults = aSub->results(); + std::list >::const_iterator aRes = aResults.cbegin(); + // there may be many shapes (circle and center): register if at least one is in selection + for(; aRes != aResults.cend(); aRes++) { + ResultConstructionPtr aConstr = + std::dynamic_pointer_cast(*aRes); + if (!aConstr->shape()) { + continue; + } + if (aShapeType == TopAbs_VERTEX) { + if (aConstr->shape()->isVertex()) { // compare vertices positions + const TopoDS_Shape& aVertex = aConstr->shape()->impl(); + gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVertex)); + if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) { + aRefs.Add(theComposite->subFeatureId(a)); + aSubNames[theComposite->subFeatureId(a)] = Model_SelectionNaming::shortName(aConstr); + } + } else { // get first or last vertex of the edge: last is stored with additional delta + const TopoDS_Shape& anEdge = aConstr->shape()->impl(); + int aDelta = kSTART_VERTEX_DELTA; + for(TopExp_Explorer aVExp(anEdge, TopAbs_VERTEX); aVExp.More(); aVExp.Next()) { + gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVExp.Current())); + if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) { + aRefs.Add(aDelta + theComposite->subFeatureId(a)); + aSubNames[aDelta + theComposite->subFeatureId(a)] = + Model_SelectionNaming::shortName(aConstr, aDelta / kSTART_VERTEX_DELTA); + break; + } + aDelta += kSTART_VERTEX_DELTA; + } + } + } else { + if (aConstr->shape()->isEdge()) { + const TopoDS_Shape& aResShape = aConstr->shape()->impl(); + TopoDS_Edge anEdge = TopoDS::Edge(aResShape); + if (!anEdge.IsNull()) { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (allCurves.Contains(aCurve)) { + int anID = theComposite->subFeatureId(a); + aRefs.Add(anID); + aSubNames[anID] = Model_SelectionNaming::shortName(aConstr); + if (aShapeType != TopAbs_EDGE) { // face needs the sub-edges on sub-labels + // add edges to sub-label to support naming for edges selection + TopExp_Explorer anEdgeExp(theSubShape, TopAbs_EDGE); + for(; anEdgeExp.More(); anEdgeExp.Next()) { + TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExp.Current()); + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aFaceCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (aFaceCurve == aCurve) { + int anOrient = Model_SelectionNaming::edgeOrientation(theSubShape, anEdge); + anOrientations[anID] = anOrient; + } + } + } + } + } + } + } + } + } std::stringstream aName; // #1839 : do not store name of the feature in the tree, since this name could be changed //aName<name(); - if (theShape.ShapeType() != TopAbs_COMPOUND) { // compound means the whole result for construction + if (theSubShape.ShapeType() != TopAbs_COMPOUND) { // compound means the whole result for construction //aName<<"/"; - if (theShape.ShapeType() == TopAbs_FACE) aName<<"Face"; - else if (theShape.ShapeType() == TopAbs_WIRE) aName<<"Wire"; - else if (theShape.ShapeType() == TopAbs_EDGE) aName<<"Edge"; - else if (theShape.ShapeType() == TopAbs_VERTEX) aName<<"Vertex"; - - if (theRefs.IsNull()) { - aName<GetMap()); - for(; aRef.More(); aRef.Next()) { - aName<<"-"<ChangeMap(aMap); + } + return aName.str(); +} - theDoc->addNamingName(aLab, aName.str()); - TDataStd_Name::Set(aLab, aName.str().c_str()); +// stores shape and name on sub-label of the main stored shape +static void saveSubName(TDF_Label& theLab, const bool isSelectionMode, const TopoDS_Shape& aSub, + std::shared_ptr theDoc, std::string theFullName) +{ + TNaming_Builder aBuilder(theLab); + if (isSelectionMode) + aBuilder.Select(aSub, aSub); + else + aBuilder.Generated(aSub); + theDoc->addNamingName(theLab, theFullName.c_str()); + TDataStd_Name::Set(theLab, theFullName.c_str()); } + TDF_Label Model_ResultConstruction::startLabel( const std::shared_ptr theExtDoc, bool& theExternal) { @@ -308,9 +400,6 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu std::dynamic_pointer_cast(document()); // iterate and store the result ids of sub-elements and sub-elements to sub-labels Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab); - std::map anOrientations; //map from edges IDs to orientations of these edges in face - std::map aSubNames; //map from edges IDs to names of edges - aRefs->Clear(); const int aSubNum = aComposite->numberOfSubs(); for(int a = 0; a < aSubNum; a++) { FeaturePtr aSub = aComposite->subFeature(a); @@ -323,29 +412,7 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu if (!aConstr->shape()) { continue; } - if (aShapeType == TopAbs_VERTEX) { - if (aConstr->shape()->isVertex()) { // compare vertices positions - const TopoDS_Shape& aVertex = aConstr->shape()->impl(); - gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVertex)); - if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) { - aRefs->Add(aComposite->subFeatureId(a)); - aSubNames[aComposite->subFeatureId(a)] = Model_SelectionNaming::shortName(aConstr); - } - } else { // get first or last vertex of the edge: last is stored with additional delta - const TopoDS_Shape& anEdge = aConstr->shape()->impl(); - int aDelta = kSTART_VERTEX_DELTA; - for(TopExp_Explorer aVExp(anEdge, TopAbs_VERTEX); aVExp.More(); aVExp.Next()) { - gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVExp.Current())); - if (aPnt.IsEqual(aVertexPos, Precision::Confusion())) { - aRefs->Add(aDelta + aComposite->subFeatureId(a)); - aSubNames[aDelta + aComposite->subFeatureId(a)] = - Model_SelectionNaming::shortName(aConstr, aDelta / kSTART_VERTEX_DELTA); - break; - } - aDelta += kSTART_VERTEX_DELTA; - } - } - } else { + if (aShapeType != TopAbs_VERTEX) { if (aConstr->shape()->isEdge()) { const TopoDS_Shape& aResShape = aConstr->shape()->impl(); TopoDS_Edge anEdge = TopoDS::Edge(aResShape); @@ -354,8 +421,6 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); if (allCurves.Contains(aCurve)) { int anID = aComposite->subFeatureId(a); - aRefs->Add(anID); - aSubNames[anID] = Model_SelectionNaming::shortName(aConstr); if (aShapeType != TopAbs_EDGE) { // face needs the sub-edges on sub-labels // add edges to sub-label to support naming for edges selection TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE); @@ -364,19 +429,11 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu Standard_Real aFirst, aLast; Handle(Geom_Curve) aFaceCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); if (aFaceCurve == aCurve) { - int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge); - anOrientations[anID] = anOrient; - TDF_Label aSubLab = aLab.FindChild(anID); - std::string aName = "Edge-" + Model_SelectionNaming::shortName(aConstr, 0); - TNaming_Builder aBuilder(aSubLab); - if (isSelectionMode) - aBuilder.Select(anEdge, anEdge); - else - aBuilder.Generated(anEdge); - aMyDoc->addNamingName(aSubLab, aName.c_str()); - TDataStd_Name::Set(aSubLab, aName.c_str()); + std::string aFullNameSub = fullName(aComposite, anEdge); + saveSubName(aSubLab, isSelectionMode, anEdge, aMyDoc, aFullNameSub); + int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge); if (anOrient != 0) { // store the orientation of edge relatively to face if needed TDataStd_Integer::Set(aSubLab, anOrient); @@ -385,25 +442,14 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu } } else { // put vertices of the selected edge to sub-labels // add edges to sub-label to support naming for edges selection - int aDelta = kSTART_VERTEX_DELTA; int aTagIndex = anID + kSTART_VERTEX_DELTA; for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_VERTEX); - anEdgeExp.More(); - anEdgeExp.Next(), - aTagIndex += kSTART_VERTEX_DELTA, - aDelta += kSTART_VERTEX_DELTA) { - TopoDS_Vertex aV = TopoDS::Vertex(anEdgeExp.Current()); - - TDF_Label aSubLab = aLab.FindChild(aTagIndex); - std::string aName = "Vertex-" - + Model_SelectionNaming::shortName(aConstr, aDelta / kSTART_VERTEX_DELTA); - TNaming_Builder aBuilder(aSubLab); - if (isSelectionMode) - aBuilder.Select(aV, aV); - else - aBuilder.Generated(aV); - aMyDoc->addNamingName(aSubLab, aName.c_str()); - TDataStd_Name::Set(aSubLab, aName.c_str()); + anEdgeExp.More(); + anEdgeExp.Next(), aTagIndex += kSTART_VERTEX_DELTA) { + TopoDS_Vertex aV = TopoDS::Vertex(anEdgeExp.Current()); + TDF_Label aSubLab = aLab.FindChild(aTagIndex); + std::string aFullNameSub = fullName(aComposite, aV); + saveSubName(aSubLab, isSelectionMode, aV, aMyDoc, aFullNameSub); } } } @@ -412,8 +458,9 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu } } } + std::string aFullName = fullName(aComposite, aSubShape, aRefs); // store the selected as primitive - registerSubShape(aLab, aSubShape, 0, aMyDoc, isSelectionMode, anOrientations, aSubNames, aRefs); + registerSubShape(aLab, aSubShape, aFullName, 0, aMyDoc, isSelectionMode); return anIndex - 1; } -- 2.39.2