- if (aShapeType == TopAbs_FACE || aShapeType == TopAbs_WIRE) {
- // compound is for the whole sketch selection
- // If this is a wire with plane defined then it is a sketch-like object
- if (!facesNum()) // no faces, update can not work correctly
- return false;
- // if there is no edges indexes, any face can be used: take the first
- std::shared_ptr<GeomAPI_Shape> aNewSelected;
- if (aNoIndexes) {
- aNewSelected = face(0);
- } else { // searching for most looks-like initial face by the indexes
- // prepare edges of the current result for the fast searching
- // curves and orientations of edges
- NCollection_DataMap<Handle(Geom_Curve), int> allCurves;
- const int aSubNum = aComposite->numberOfSubs();
- for(int a = 0; a < aSubNum; a++) {
- int aSubID = aComposite->subFeatureId(a);
- if (aSubIds->Contains(aSubID)) {
- 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()) {
- const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
- TopoDS_Edge anEdge = TopoDS::Edge(aResShape);
- if (!anEdge.IsNull()) {
- Standard_Real aFirst, aLast;
- Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
- // searching for orientation information
- int anOrient = 0;
- Handle(TDataStd_Integer) anInt;
- if (aLab.FindChild(aSubID).FindAttribute(TDataStd_Integer::GetID(), anInt)) {
- anOrient = anInt->Get();
- }
- allCurves.Bind(aCurve, anOrient);
- }
- }
- }
- }
- }
- aNewSelected = Model_SelectionNaming::findAppropriateFace(
- aThisPtr, allCurves, aShapeType == TopAbs_WIRE);
- }
- if (aNewSelected) { // store this new selection
- select(aNewSelected, theExtDoc, theIndex);
- theModified = true;
- return true;
- } else {
- // if the selection is not found, put the empty shape:
- // it's better to have disappeared shape, than the old, the lost one
- TNaming_Builder anEmptyBuilder(aLab);
- return false;
- }
- } else if (aShapeType == TopAbs_EDGE) {
- // just reselect the edge by the id
- const int aSubNum = aComposite->numberOfSubs();
- for(int a = 0; a < aSubNum; a++) {
- // if aSubIds take any, the first appropriate
- if (aSubIds->IsEmpty() || aSubIds->Contains(aComposite->subFeatureId(a))) {
- // found the appropriate feature
- FeaturePtr aFeature = aComposite->subFeature(a);
- std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aResIter =
- aFeature->results().cbegin();
- for(;aResIter != aFeature->results().cend(); aResIter++) {
- ResultConstructionPtr aRes =
- std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aResIter);
- if (aRes && aRes->shape() && aRes->shape()->isEdge()) { // found!
- select(aRes->shape(), theExtDoc, theIndex);
- theModified = true;
- return true;
- }
- }
- }
- }
- } else if (aShapeType == TopAbs_VERTEX) {
- // just reselect the vertex by the id of edge
- const int aSubNum = aComposite->numberOfSubs();
- for(int a = 0; a < aSubNum; a++) {
- // if aSubIds take any, the first appropriate
- int aFeatureID = aComposite->subFeatureId(a);
- if (aSubIds->IsEmpty() || aSubIds->Contains(aFeatureID) ||
- aSubIds->Contains(aFeatureID + kSTART_VERTEX_DELTA) ||
- aSubIds->Contains(aFeatureID + kSTART_VERTEX_DELTA * 2)) {
- // searching for deltas
- int aVertexNum = 0;
- if (aSubIds->Contains(aFeatureID + kSTART_VERTEX_DELTA)) aVertexNum = 1;
- else if (aSubIds->Contains(aFeatureID + kSTART_VERTEX_DELTA * 2)) aVertexNum = 2;
- // found the feature with appropriate edge
- FeaturePtr aFeature = aComposite->subFeature(a);
- std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aResIter =
- aFeature->results().cbegin();
- for(;aResIter != aFeature->results().cend(); aResIter++) {
- ResultConstructionPtr aRes =
- std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aResIter);
- if (aRes && aRes->shape()) {
- if (aRes->shape()->isVertex() && aVertexNum == 0) { // found!
- select(aRes->shape(), theExtDoc, theIndex);
- theModified = true;
- return true;
- } else if (aRes->shape()->isEdge() && aVertexNum > 0) {
- const TopoDS_Shape& anEdge = aRes->shape()->impl<TopoDS_Shape>();
- int aVIndex = 1;
- for(TopExp_Explorer aVExp(anEdge, TopAbs_VERTEX); aVExp.More(); aVExp.Next()) {
- if (aVIndex == aVertexNum) { // found!
- std::shared_ptr<GeomAPI_Shape> aVertex(new GeomAPI_Shape);
- aVertex->setImpl(new TopoDS_Shape(aVExp.Current()));
- select(aVertex, theExtDoc, theIndex);
- theModified = true;
- return true;
- }
- aVIndex++;
- }
- }
- }
- }
+void faceToEdgeIndices(const ListOfShape& theFaces,
+ const NCollection_DataMap<Handle(Geom_Curve), int>& theCurvesIndices,
+ MapFaceToEdgeIndices& theFaceEdges)
+{
+ std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFIter = theFaces.begin();
+ for (; aFIter != theFaces.end(); aFIter++) {
+ std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(*aFIter));
+ // put them to a label, trying to keep the same faces on the same labels
+ if (aFace.get() && !aFace->isNull()) {
+ TopoDS_Face aTopoFace = TopoDS::Face(aFace->impl<TopoDS_Shape>());
+ theFaceEdges.Add(aTopoFace, TColStd_ListOfInteger());
+ // keep new indices of sub-elements used in this face
+ for (TopExp_Explorer anEdges(aTopoFace, TopAbs_EDGE); anEdges.More(); anEdges.Next()) {
+ TopoDS_Edge anEdge = TopoDS::Edge(anEdges.Current());
+ Standard_Real aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+ if (theCurvesIndices.IsBound(aCurve)) {
+ int anIndex = theCurvesIndices.Find(aCurve);
+ if ((aFirst > aLast) != (anEdge.Orientation() == TopAbs_REVERSED))
+ anIndex = -anIndex;
+ theFaceEdges.ChangeFromKey(aTopoFace).Append(anIndex);