1 // File: Model_AttributeSelection.h
3 // Author: Mikhail PONIKAROV
5 #include "Model_AttributeSelection.h"
6 #include "Model_Application.h"
7 #include "Model_Events.h"
8 #include "Model_Data.h"
9 #include <ModelAPI_Feature.h>
10 #include <ModelAPI_ResultBody.h>
11 #include <ModelAPI_ResultConstruction.h>
12 #include <ModelAPI_CompositeFeature.h>
13 #include <GeomAPI_Shape.h>
15 #include <TNaming_Selector.hxx>
16 #include <TNaming_NamedShape.hxx>
17 #include <TNaming_Tool.hxx>
18 #include <TopoDS_Shape.hxx>
19 #include <TDataStd_ReferenceList.hxx>
20 #include <TopTools_MapOfShape.hxx>
21 #include <TopExp_Explorer.hxx>
25 void Model_AttributeSelection::setValue(const ResultPtr& theContext,
26 const boost::shared_ptr<GeomAPI_Shape>& theSubShape)
28 const boost::shared_ptr<GeomAPI_Shape>& anOldShape = value();
30 (theSubShape == anOldShape || (theSubShape && anOldShape && theSubShape->isEqual(anOldShape)));
31 if (isOldShape) return; // shape is the same, so context is also unchanged
32 // update the referenced object if needed
33 bool isOldContext = theContext == myRef.value();
35 myRef.setValue(theContext);
37 if (theContext->groupName() == ModelAPI_ResultBody::group())
38 selectBody(theContext, theSubShape);
39 else if (theContext->groupName() == ModelAPI_ResultConstruction::group())
40 selectConstruction(theContext, theSubShape);
42 myIsInitialized = true;
43 owner()->data()->sendAttributeUpdated(this);
46 boost::shared_ptr<GeomAPI_Shape> Model_AttributeSelection::value()
48 boost::shared_ptr<GeomAPI_Shape> aResult;
49 if (myIsInitialized) {
50 Handle(TNaming_NamedShape) aSelection;
51 if (myRef.myRef->Label().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) {
52 TopoDS_Shape aSelShape = aSelection->Get();
53 aResult->setImpl(&aSelShape);
59 Model_AttributeSelection::Model_AttributeSelection(TDF_Label& theLabel)
62 myIsInitialized = myRef.isInitialized();
65 ResultPtr Model_AttributeSelection::context() {
66 return boost::dynamic_pointer_cast<ModelAPI_Result>(myRef.value());
70 void Model_AttributeSelection::setObject(const boost::shared_ptr<ModelAPI_Object>& theObject)
72 ModelAPI_AttributeSelection::setObject(theObject);
73 myRef.setObject(theObject);
76 void Model_AttributeSelection::selectBody(
77 const ResultPtr& theContext, const boost::shared_ptr<GeomAPI_Shape>& theSubShape)
79 // perform the selection
80 TNaming_Selector aSel(myRef.myRef->Label());
81 TopoDS_Shape aNewShape = theSubShape ? theSubShape->impl<TopoDS_Shape>() : TopoDS_Shape();
82 TopoDS_Shape aContext;
84 ResultBodyPtr aBody = boost::dynamic_pointer_cast<ModelAPI_ResultBody>(myRef.value());
86 aContext = aBody->shape()->impl<TopoDS_Shape>();
88 ResultConstructionPtr aConstr = boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(myRef.value());
90 aContext = aConstr->shape()->impl<TopoDS_Shape>();
92 throw std::invalid_argument("a result with shape is expected");
94 Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aNewShape, myRef.myRef->Label());
95 TDF_Label aLab = aNS->Label();
97 aSel.Select(aNewShape, aContext);
100 #include <BRepTools.hxx>
102 void Model_AttributeSelection::selectConstruction(
103 const ResultPtr& theContext, const boost::shared_ptr<GeomAPI_Shape>& theSubShape)
105 FeaturePtr aContextFeature = owner()->document()->feature(theContext);
106 CompositeFeaturePtr aComposite =
107 boost::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aContextFeature);
108 if (!aComposite || aComposite->numberOfSubs() == 0) {
109 return; // saving of context is enough: result construction contains exactly the needed shape
111 boost::shared_ptr<Model_Data> aData = boost::dynamic_pointer_cast<Model_Data>(owner()->data());
112 TDF_Label aLab = aData->label();
113 // identify the reuslts of sub-object of the composite by edges
114 const TopoDS_Shape& aSubShape = theSubShape->impl<TopoDS_Shape>();
115 TopTools_MapOfShape allEdges;
116 for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next()) {
117 BRepTools::Write(anEdgeExp.Current(), "D:\\selected.brep");
118 allEdges.Add(anEdgeExp.Current());
120 // iterate and store the result ids of sub-elements
121 Handle(TDataStd_ReferenceList) aRefs = TDataStd_ReferenceList::Set(aLab);
122 const int aSubNum = aComposite->numberOfSubs();
123 for(int a = 0; a < aSubNum; a++) {
124 FeaturePtr aSub = aComposite->subFeature(a);
125 const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
126 std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResults.cbegin();
127 // there may be many shapes (circle and center): register if at least one is in selection
128 for(; aRes != aResults.cend(); aRes++) {
129 ResultConstructionPtr aConstr =
130 boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
131 if (aConstr->shape()) {
132 const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
133 BRepTools::Write(aResShape, "D:\\sub.brep");
134 if (allEdges.Contains(aResShape)) {
135 boost::shared_ptr<Model_Data> aSubData = boost::dynamic_pointer_cast<Model_Data>(aSub->data());
136 TDF_Label aSubLab = aSubData->label();
137 aRefs->Append(aSubLab);