}
}
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());
}
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;
}
// 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,
+static void saveSubName(CompositeFeaturePtr theComposite,
+ TDF_Label& theLab, const bool isSelectionMode, TopoDS_Shape aSub,
std::shared_ptr<Model_Document> theDoc, std::string theFullName)
{
+ // trying to store the edge of composite result, not sketch sub as it is
+ if (aSub.ShapeType() == TopAbs_EDGE) {
+ ResultPtr aRes = theComposite->firstResult();
+ ResultConstructionPtr aConstr = std::dynamic_pointer_cast<Model_ResultConstruction>(aRes);
+ if (aConstr.get()) {
+ Standard_Real aSubFirst, aSubLast;
+ TopoDS_Edge aSubEdge = TopoDS::Edge(aSub);
+ Handle(Geom_Curve) aSubCurve = BRep_Tool::Curve(aSubEdge, aSubFirst, aSubLast);
+ for(int aFaceIndex = 0; aFaceIndex < aConstr->facesNum(); aFaceIndex++) {
+ GeomShapePtr aGFace = aConstr->face(aFaceIndex);
+ TopoDS_Shape aFace = aGFace->impl<TopoDS_Shape>();
+ for(TopExp_Explorer anExp(aFace, TopAbs_EDGE); anExp.More(); anExp.Next()) {
+ TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
+ Standard_Real aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+ if (aCurve == aSubCurve &&
+ ((fabs(aFirst - aSubFirst) < 1.e-9 && fabs(aLast - aSubLast) < 1.e-9)) ||
+ (fabs(aFirst - aSubLast) < 1.e-9 && fabs(aLast - aSubFirst) < 1.e-9)) {
+ aSub = anEdge;
+ break;
+ }
+ }
+ }
+ }
+ }
+
TNaming_Builder aBuilder(theLab);
if (isSelectionMode)
aBuilder.Select(aSub, aSub);
// 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<TopoDS_Shape>(), 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<ModelAPI_Result>(data()->owner());
+ FeaturePtr aThisFeature = document()->feature(aThisPtr);
+ CompositeFeaturePtr aComposite =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(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<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
+ std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes;
+ for(aRes = aResults.cbegin(); aRes != aResults.cend(); aRes++) {
+ ResultConstructionPtr aConstr =
+ std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
+ if (aConstr->shape() && aConstr->shape()->isEdge()) {
+ TopoDS_Shape aResShape = aConstr->shape()->impl<TopoDS_Shape>();
+ 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<TopoDS_Shape>(), 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;
+ }
}
}
}
// 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<int> aUsedIDMap; // already used lab tags for placement of shapes
for(int a = 0; a < aSubNum; a++) {
FeaturePtr aSub = aComposite->subFeature(a);
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(aShapeSubLab, isSelectionMode, anEdge, aMyDoc, aFullNameSub);
+ saveSubName(aComposite, aSubLab, isSelectionMode, anEdge, aMyDoc, aFullNameSub);
int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge);
if (anOrient != 0) {
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(aShapeSubLab, isSelectionMode, aV, aMyDoc, aFullNameSub);
+ saveSubName(aComposite, aSubLab, isSelectionMode, aV, aMyDoc, aFullNameSub);
}
}
}
}
return aRes;
} else {
+ // check is this modified or not
+ std::shared_ptr<GeomAPI_Shape> 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<GeomAPI_Shape> anOldShape(new GeomAPI_Shape);
+ anOldShape->setImpl<TopoDS_Shape>(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<TopoDS_Shape>());
+ aBuilder.Generated(aNewShape->impl<TopoDS_Shape>());
}
return shape() && !shape()->isNull();
}
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