From 3b93f7eed4d805f1bb82ef559417be29f1c70409 Mon Sep 17 00:00:00 2001 From: mpv Date: Fri, 5 Oct 2018 16:13:12 +0300 Subject: [PATCH] Make big models naming work correctly: piece_12.py , flange.py --- src/Model/Model_ResultConstruction.cpp | 197 +++++++++++++++---------- src/Model/Model_SelectionNaming.cpp | 34 +++-- 2 files changed, 142 insertions(+), 89 deletions(-) diff --git a/src/Model/Model_ResultConstruction.cpp b/src/Model/Model_ResultConstruction.cpp index 9b2520a45..d9a78134c 100644 --- a/src/Model/Model_ResultConstruction.cpp +++ b/src/Model/Model_ResultConstruction.cpp @@ -171,6 +171,8 @@ static void registerSubShape(TDF_Label theMainLabel, TopoDS_Shape theShape, std: TDataStd_Name::Set(aLab, theFullName.c_str()); } +#include + // 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)()) @@ -178,109 +180,148 @@ std::string fullName(CompositeFeaturePtr theComposite, const TopoDS_Shape& theSu TopAbs_ShapeEnum aShapeType = theSubShape.ShapeType(); gp_Pnt aVertexPos; NCollection_Map allExactEdges; - NCollection_Map allEdges; - NCollection_Map allCurves; + NCollection_DataMap allEdges; + NCollection_DataMap allCurves; + /// map from edges from theSubShape to the found corresponded indices of the sub-components + NCollection_DataMap, TopTools_OrientedShapeMapHasher> + anEdgesCorrespondence; 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()); allExactEdges.Add(anEdge); - allEdges.Add(anEdge); + allEdges.Bind(anEdge, anEdge); Standard_Real aFirst, aLast; Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); - allCurves.Add(aCurve); + allCurves.Bind(aCurve, anEdge); + anEdgesCorrespondence.Bind(anEdge, NCollection_List()); } } 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(); - // reduce equality criteria from strong to weak - for(int aTypeOfIdentification = 0; aTypeOfIdentification < 3; aTypeOfIdentification++) { - 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)); + 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(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; + 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()) - continue; - bool aIsEqual = false; - if (aTypeOfIdentification == 0) { // check equality of curves - aIsEqual = allExactEdges.Contains(anEdge); - } else if (aTypeOfIdentification == 1) { // check EdgesHash equality of edges - aIsEqual = allEdges.Contains(anEdge); - } else { // check CurvesHash equality of curves - Standard_Real aFirst, aLast; - Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); - aIsEqual = allCurves.Contains(aCurve); + } + } else { + if (aConstr->shape()->isEdge()) { + const TopoDS_Shape& aResShape = aConstr->shape()->impl(); + TopoDS_Edge anEdge = TopoDS::Edge(aResShape); + if (anEdge.IsNull()) + continue; + if (allEdges.IsBound(anEdge)) { + anEdgesCorrespondence.ChangeFind(allEdges.Find(anEdge)).Append(a); + } else { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (allCurves.IsBound(aCurve)) { + anEdgesCorrespondence.ChangeFind(allCurves.Find(aCurve)).Append(a); } - if (aIsEqual) { - 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 aFaceEdge = TopoDS::Edge(anEdgeExp.Current()); - bool aIsEqual = false; - if (aTypeOfIdentification == 0) { // check equality of curves - aIsEqual = anEdge.IsSame(aFaceEdge); - } else if (aTypeOfIdentification == 1) { // check EdgesHash equality of edges - aIsEqual = Model_EdgesHasher::IsEqual(aFaceEdge, anEdge); - } else { // check CurvesHash equality of curves - Standard_Real aFirst, aLast; - Handle(Geom_Curve) aFaceCurve = BRep_Tool::Curve(aFaceEdge, aFirst, aLast); - Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); - aIsEqual = Model_CurvesHasher::IsEqual(aFaceCurve, aCurve); - } - if (aIsEqual) { - int anOrient = Model_SelectionNaming::edgeOrientation(theSubShape, aFaceEdge); - anOrientations[anID] = anOrient; - } - } + } + } + } + } + } + + if (aShapeType != TopAbs_VERTEX) { // get best candidates from the correspondances + NCollection_DataMap, TopTools_OrientedShapeMapHasher> + ::Iterator aCorIter(anEdgesCorrespondence); + for(; aCorIter.More(); aCorIter.Next()) { + TopoDS_Edge anOrig = aCorIter.Key(); + NCollection_List::Iterator aCandidate(aCorIter.Value()); + int aBestScore = 0; + int aBestIndex = -1; + ResultConstructionPtr aBestConstr; + for(; aCandidate.More(); aCandidate.Next()) { + FeaturePtr aSub = theComposite->subFeature(aCandidate.Value()); + 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() || !aConstr->shape()->isEdge()) + continue; + const TopoDS_Shape& aResShape = aConstr->shape()->impl(); + TopoDS_Edge anEdge = TopoDS::Edge(aResShape); + if (anEdge.IsNull()) + continue; + // detect score of the candidate + int aScore = 0; + if (anEdge.IsEqual(anOrig)) + aScore = 10; + else if (anEdge.IsSame(anOrig)) + aScore = 9; + else { + Standard_Real aFirst, aLast; + Handle(Geom_Curve) anOrigCurve = BRep_Tool::Curve(anOrig, aFirst, aLast); + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast); + if (anOrigCurve == aCurve) { + if (Model_EdgesHasher::IsEqual(anEdge, anOrig)) { + aScore = 8; + } else { + aScore = 6; + } + } else { + if (Model_EdgesHasher::IsEqual(anEdge, anOrig)) { + aScore = 7; + } else if (Model_CurvesHasher::IsEqual(aCurve, anOrigCurve)) { + aScore = 5; } } } + if (aScore > aBestScore) { + aBestIndex = aCandidate.Value(); + aBestScore = aScore; + aBestConstr = aConstr; + } + } + } + if (aBestIndex >= 0) { + int anID = theComposite->subFeatureId(aBestIndex); + aRefs.Add(anID); + aSubNames[anID] = Model_SelectionNaming::shortName(aBestConstr); + if (aShapeType != TopAbs_EDGE) { // face needs the sub-edges on sub-labels + // add edges to sub-label to support naming for edges selection + int anOrient = Model_SelectionNaming::edgeOrientation(theSubShape, anOrig); + anOrientations[anID] = anOrient; } } } - if (!aRefs.IsEmpty() || aShapeType == TopAbs_VERTEX) - break; } std::stringstream aName; // #1839 : do not store name of the feature in the tree, since this name could be changed diff --git a/src/Model/Model_SelectionNaming.cpp b/src/Model/Model_SelectionNaming.cpp index 9daf02c95..802b13cfc 100644 --- a/src/Model/Model_SelectionNaming.cpp +++ b/src/Model/Model_SelectionNaming.cpp @@ -765,6 +765,7 @@ std::shared_ptr Model_SelectionNaming::findAppropriateFace( NCollection_DataMap& theCurves, const bool theIsWire) { int aBestFound = 0; // best number of found edges (not percentage: issue 1019) + int aBestNotFound = 1000000; // best number of not found edges (must be minimum) int aBestOrient = 0; // for the equal "BestFound" additional parameter is orientation std::shared_ptr aResult; ResultConstructionPtr aConstructionContext = @@ -807,18 +808,29 @@ std::shared_ptr Model_SelectionNaming::findAppropriateFace( } } } + if (theIsWire && aFound + aNotFound != 0) { + if (aBestNotFound > aNotFound || (aBestNotFound == aNotFound && aFound > aBestFound) || + (aBestNotFound == aNotFound && aFound == aBestFound && aSameOrientation > aBestOrient)) { + aBestFound = aFound; + aBestOrient = aSameOrientation; + aBestNotFound = aNotFound; + std::shared_ptr aWire(new GeomAPI_Wire); + aWire->setImpl(new TopoDS_Shape(*aFW)); + aResult = aWire; + } + aFound = 0; + aNotFound = 0; + aSameOrientation = 0; + } + } + if (!theIsWire) { if (aFound + aNotFound != 0) { - if (aFound > aBestFound || - (aFound == aBestFound && aSameOrientation > aBestOrient)) { - aBestFound = aFound; - aBestOrient = aSameOrientation; - if (theIsWire) { - std::shared_ptr aWire(new GeomAPI_Wire); - aWire->setImpl(new TopoDS_Shape(*aFW)); - aResult = aWire; - } else { - aResult = aConstructionContext->face(aFaceIndex); - } + if (aBestNotFound > aNotFound || (aBestNotFound == aNotFound && aFound > aBestFound) || + (aBestNotFound == aNotFound && aFound == aBestFound && aSameOrientation > aBestOrient)) { + aBestFound = aFound; + aBestOrient = aSameOrientation; + aBestNotFound = aNotFound; + aResult = aConstructionContext->face(aFaceIndex); } } } -- 2.39.2