X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_ResultConstruction.cpp;h=a0c8a519b703a5ad4640a088b4e23d016fb1bf2e;hb=cb2bfff600626039e210f08de27b5229541d367a;hp=127507249a61b7fa02d5fbc3cd17719f253643b1;hpb=04d7bcf071f895d43f6c4ecc4d741dc8b365d1da;p=modules%2Fshaper.git diff --git a/src/Model/Model_ResultConstruction.cpp b/src/Model/Model_ResultConstruction.cpp index 127507249..a0c8a519b 100644 --- a/src/Model/Model_ResultConstruction.cpp +++ b/src/Model/Model_ResultConstruction.cpp @@ -111,6 +111,21 @@ int Model_ResultConstruction::facesNum() } } myFacesUpToDate = true; + + // update all the faces and sub-elements in the naming structure + DocumentPtr anEmptyExt; + bool aNotExt = false; + TDF_Label aDataLab = startLabel(anEmptyExt, aNotExt); + TDF_ChildIterator aSubsIter(aDataLab, Standard_False); + for(; aSubsIter.More(); aSubsIter.Next()) { + const TDF_Label aLab = aSubsIter.Value(); + if (aLab.Tag() == 1) // skip the root shape label + continue; + Handle(TNaming_NamedShape) aNS; + if (aLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) { + update(aLab.Tag() - 1, anEmptyExt, aNotExt); + } + } } return int(myFaces.size()); } @@ -132,7 +147,7 @@ void Model_ResultConstruction::setInfinite(const bool theInfinite) void Model_ResultConstruction::setIsConcealed(const bool theValue) { - // do nothing: the construction element is never consealed + // do nothing: the construction element is never concealed } static const int kSTART_VERTEX_DELTA = 1000000; @@ -363,17 +378,50 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu // if the subshape is part of a result face, select the whole face (#1997) bool isSelectionMode = false; // and other don't set shapes - all the naming is in face label if (!aSubShape.IsNull() && aSubShape.ShapeType() > TopAbs_FACE) { - for(int aFaceIndex = 0; aFaceIndex < facesNum(); aFaceIndex++) { - TopExp_Explorer anExp(face(aFaceIndex)->impl(), aSubShape.ShapeType()); - for(; anExp.More(); anExp.Next()) { - if (aSubShape.IsSame(anExp.Current())) { // this is the case: select the whole face - // here just store the face index (to update face if update of edge is needed) - TNaming_Builder aBuilder(aLab); - aBuilder.Select(aSubShape, aSubShape); - int aFaceSelID = select(face(aFaceIndex), theExtDoc, -1); - TDF_Reference::Set(aLab, aLab.Father().FindChild(aFaceSelID)); - isSelectionMode = true; - break; + // but before check that sub-vertex correctly detected as intersection of sketch edges (#2389) + int anEdgesNum = 2; + if (aSubShape.ShapeType() == TopAbs_VERTEX) { + anEdgesNum = 0; + ResultPtr aThisPtr = std::dynamic_pointer_cast(data()->owner()); + FeaturePtr aThisFeature = document()->feature(aThisPtr); + CompositeFeaturePtr aComposite = + std::dynamic_pointer_cast(aThisFeature); + if (aComposite.get()) { + const int aSubNum = aComposite->numberOfSubs(); + for(int a = 0; a < aSubNum; a++) { + int aSubID = aComposite->subFeatureId(a); + FeaturePtr aSub = aComposite->subFeature(a); + const std::list >& aResults = aSub->results(); + std::list >::const_iterator aRes; + for(aRes = aResults.cbegin(); aRes != aResults.cend(); aRes++) { + ResultConstructionPtr aConstr = + std::dynamic_pointer_cast(*aRes); + if (aConstr->shape() && aConstr->shape()->isEdge()) { + TopoDS_Shape aResShape = aConstr->shape()->impl(); + for(TopExp_Explorer anExp(aResShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) { + if (aSubShape.IsSame(anExp.Current())) { + anEdgesNum++; + break; + } + } + } + } + } + } + } + if (anEdgesNum > 1) { + for(int aFaceIndex = 0; aFaceIndex < facesNum(); aFaceIndex++) { + TopExp_Explorer anExp(face(aFaceIndex)->impl(), aSubShape.ShapeType()); + for(; anExp.More(); anExp.Next()) { + if (aSubShape.IsSame(anExp.Current())) { // this is the case: select the whole face + // here just store the face index (to update face if update of edge is needed) + TNaming_Builder aBuilder(aLab); + aBuilder.Select(aSubShape, aSubShape); + int aFaceSelID = select(face(aFaceIndex), theExtDoc, -1); + TDF_Reference::Set(aLab, aLab.Father().FindChild(aFaceSelID)); + isSelectionMode = true; + break; + } } } } @@ -440,8 +488,9 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu // iterate and store the result ids of sub-elements and sub-elements to sub-labels Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab); const int aSubNum = aComposite->numberOfSubs(); - // subs are placed one by one because of #2248): sketch curve may produce several edges - int aSubLabId = 1; + // subs are placed on unique labels because of #2248: sketch curve may produce several edges, + // but #2401 - on stable labels + NCollection_Map aUsedIDMap; // already used lab tags for placement of shapes for(int a = 0; a < aSubNum; a++) { FeaturePtr aSub = aComposite->subFeature(a); @@ -471,11 +520,12 @@ 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) { + while(aUsedIDMap.Contains(anID)) + anID += 100000; + aUsedIDMap.Add(anID); TDF_Label aSubLab = aLab.FindChild(anID); - TDF_Label aShapeSubLab = aLab.FindChild(aSubLabId++); std::string aFullNameSub = fullName(aComposite, anEdge); - saveSubName(aComposite, - aShapeSubLab, isSelectionMode, anEdge, aMyDoc, aFullNameSub); + saveSubName(aComposite, aSubLab, isSelectionMode, anEdge, aMyDoc, aFullNameSub); int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge); if (anOrient != 0) { @@ -489,10 +539,12 @@ int Model_ResultConstruction::select(const std::shared_ptr& theSu for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_VERTEX); anEdgeExp.More(); anEdgeExp.Next()) { TopoDS_Vertex aV = TopoDS::Vertex(anEdgeExp.Current()); - TDF_Label aShapeSubLab = aLab.FindChild(aSubLabId++); + while(aUsedIDMap.Contains(anID)) + anID += 100000; + aUsedIDMap.Add(anID); + TDF_Label aSubLab = aLab.FindChild(anID); std::string aFullNameSub = fullName(aComposite, aV); - saveSubName(aComposite, - aShapeSubLab, isSelectionMode, aV, aMyDoc, aFullNameSub); + saveSubName(aComposite, aSubLab, isSelectionMode, aV, aMyDoc, aFullNameSub); } } } @@ -574,10 +626,30 @@ bool Model_ResultConstruction::update(const int theIndex, } return aRes; } else { + // check is this modified or not + std::shared_ptr aNewShape = shape(); + TopoDS_Shape anOldSh; + Handle(TNaming_NamedShape) aNS; + if (aLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) { + anOldSh = aNS->Get(); + } + if (aNewShape.get()) { + if (anOldSh.IsNull()) + theModified = true; + else { + std::shared_ptr anOldShape(new GeomAPI_Shape); + anOldShape->setImpl(new TopoDS_Shape(anOldSh)); + theModified = !anOldShape->isEqual(aNewShape); + } + } + else if (!anOldSh.IsNull()) { + theModified = true; + } + // For correct naming selection, put the shape into the naming structure. // It seems sub-shapes are not needed: only this shape is (and can be ) selected. TNaming_Builder aBuilder(aLab); - aBuilder.Generated(shape()->impl()); + aBuilder.Generated(aNewShape->impl()); } return shape() && !shape()->isNull(); } @@ -593,7 +665,7 @@ bool Model_ResultConstruction::update(const int theIndex, Handle(TDF_Reference) aRef; if (aLab.FindAttribute(TDF_Reference::GetID(), aRef)) { int aFaceIndex = aRef->Get().Tag(); - // don't check selection ,since face may disappear, but the shape stays correct + // don't check selection since face may disappear, but the shape stays correct Model_ResultConstruction::update(aFaceIndex, theExtDoc, theModified); } // getting a type of selected shape