1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: PartSet_Validators.cpp
4 // Created: 09 July 2014
5 // Author: Vitaly SMETANNIKOV
7 #include "PartSet_Validators.h"
10 #include <TopoDS_Edge.hxx>
11 #include <BRep_Tool.hxx>
12 #include <GeomAdaptor_Curve.hxx>
13 #include <GeomAbs_CurveType.hxx>
14 #include <GeomValidators_Tools.h>
15 #include <ModuleBase_ISelection.h>
16 #include <ModuleBase_WidgetShapeSelector.h>
18 #include <ModelAPI_AttributeRefAttr.h>
19 #include <ModelAPI_AttributeSelection.h>
20 #include <ModelAPI_AttributeReference.h>
21 #include <ModelAPI_AttributeSelectionList.h>
22 #include <ModelAPI_Object.h>
23 #include <ModelAPI_Session.h>
25 #include <SketchPlugin_Sketch.h>
32 int shapesNbPoints(const ModuleBase_ISelection* theSelection)
34 QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
36 foreach (ModuleBase_ViewerPrs aPrs, aList) {
37 const TopoDS_Shape& aShape = aPrs.shape();
38 if (!aShape.IsNull()) {
39 if (aShape.ShapeType() == TopAbs_VERTEX)
46 int shapesNbLines(const ModuleBase_ISelection* theSelection)
48 QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
50 foreach(ModuleBase_ViewerPrs aPrs, aList) {
51 const TopoDS_Shape& aShape = aPrs.shape();
52 if (!aShape.IsNull()) {
53 if (aShape.ShapeType() == TopAbs_EDGE) {
54 TopoDS_Edge aEdge = TopoDS::Edge(aShape);
55 Standard_Real aStart, aEnd;
56 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd);
57 GeomAdaptor_Curve aAdaptor(aCurve);
58 if (aAdaptor.GetType() == GeomAbs_Line)
66 bool PartSet_DistanceValidator::isValid(const ModuleBase_ISelection* theSelection) const
68 int aCount = shapesNbPoints(theSelection) + shapesNbLines(theSelection);
69 return (aCount > 0) && (aCount < 3);
72 bool PartSet_LengthValidator::isValid(const ModuleBase_ISelection* theSelection) const
74 int aCount = shapesNbLines(theSelection);
75 return (aCount > 0) && (aCount < 2);
78 bool PartSet_PerpendicularValidator::isValid(const ModuleBase_ISelection* theSelection) const
80 int aCount = shapesNbLines(theSelection);
81 return (aCount > 0) && (aCount < 3);
84 bool PartSet_ParallelValidator::isValid(const ModuleBase_ISelection* theSelection) const
86 int aCount = shapesNbLines(theSelection);
87 return (aCount > 0) && (aCount < 3);
90 bool PartSet_RadiusValidator::isValid(const ModuleBase_ISelection* theSelection) const
92 QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
93 ModuleBase_ViewerPrs aPrs;
95 foreach (ModuleBase_ViewerPrs aPrs, aList) {
96 const TopoDS_Shape& aShape = aPrs.shape();
97 if (!aShape.IsNull()) {
98 if (aShape.ShapeType() == TopAbs_EDGE) {
99 TopoDS_Edge aEdge = TopoDS::Edge(aShape);
100 Standard_Real aStart, aEnd;
101 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd);
102 GeomAdaptor_Curve aAdaptor(aCurve);
103 if (aAdaptor.GetType() == GeomAbs_Circle)
108 return (aCount > 0) && (aCount < 2);
111 bool PartSet_RigidValidator::isValid(const ModuleBase_ISelection* theSelection) const
113 int aCount = shapesNbLines(theSelection);
114 return (aCount > 0) && (aCount < 2);
117 bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute,
118 const std::list<std::string>& theArguments) const
120 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
122 // 1. check whether the object of the attribute is not among the feature attributes
123 // find the attribute's object
124 ObjectPtr anObject = GeomValidators_Tools::getObject(theAttribute);
126 // check whether the object is not among other feature attributes
127 if (anObject.get() != NULL) {
128 // Check RefAttr attributes
129 std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs = aFeature->data()->attributes("");
130 //if (anAttrs.size() > 0) {
131 std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anIt = anAttrs.begin();
132 for(; anIt != anAttrs.end(); anIt++) {
133 AttributePtr anAttr = *anIt;
134 // the function parameter attribute should be skipped
135 if (anAttr.get() == NULL || anAttr->id() == theAttribute->id())
137 ObjectPtr aCurObject = GeomValidators_Tools::getObject(anAttr);
138 if (aCurObject && aCurObject == anObject)
143 // 2. collect object referenced by theAttribute and ...
144 if (featureHasReferences(theAttribute)) {
145 // 3. check whether the attribute value is not among other feature attributes
146 std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
147 aFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
148 std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
149 for(; anAttr != anAttrs.end(); anAttr++) {
151 std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
152 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
153 // check the object is already presented
154 if (!aRef->isObject() && aRef->attr() == theAttribute)
157 // TODO(nds) v1.0.2 master
158 //bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature,
159 // const std::list<std::string>& theArguments,
160 // const ObjectPtr& theObject,
161 // const GeomShapePtr& theShape) const
163 // // Check RefAttr attributes
164 // std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
165 // theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
166 // if (anAttrs.size() > 0) {
167 // std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
168 // for(; anAttr != anAttrs.end(); anAttr++) {
170 // std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
171 // std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
172 // // check the object is already presented
173 // if (aRef->isObject() && aRef->object() == theObject)
178 // // Check selection attributes
179 // anAttrs = theFeature->data()->attributes(ModelAPI_AttributeSelection::typeId());
180 // if (anAttrs.size() > 0) {
181 // std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
182 // for(; anAttr != anAttrs.end(); anAttr++) {
184 // std::shared_ptr<ModelAPI_AttributeSelection> aRef =
185 // std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*anAttr);
186 // // check the object is already presented
187 // if (aRef->isInitialized() && aRef->context() == theObject) {
188 // if (theShape.get() != NULL) {
189 // if (aRef->value()->isEqual(theShape))
197 // // Check selection attributes
198 // anAttrs = theFeature->data()->attributes(ModelAPI_AttributeReference::typeId());
199 // if (anAttrs.size() > 0) {
200 // std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
201 // for(; anAttr != anAttrs.end(); anAttr++) {
203 // std::shared_ptr<ModelAPI_AttributeReference> aRef =
204 // std::dynamic_pointer_cast<ModelAPI_AttributeReference>(*anAttr);
205 // // check the object is already presented
206 // if (aRef->isInitialized() && aRef->value() == theObject)
208 // ======= end of todo
216 bool PartSet_DifferentObjectsValidator::featureHasReferences(const AttributePtr& theAttribute) const
217 // TODO(nds) v1.0.2 master
218 //bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature,
219 // const std::list<std::string>& theArguments,
220 // const AttributePtr& theAttribute) const
222 // if (PartSet_DifferentObjectsValidator::isValid(theAttribute, theArguments)) {
223 // std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
224 // theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
225 // std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
226 // for(; anAttr != anAttrs.end(); anAttr++) {
228 // std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
229 // std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
230 // // check the object is already presented
231 // if (!aRef->isObject() && aRef->attr() == theAttribute)
240 //bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute,
241 // const std::list<std::string>& theArguments) const
242 // ======= end of todo
244 std::list<std::pair<std::string, std::list<ObjectPtr> > > allRefs;
245 if (theAttribute->owner().get() && theAttribute->owner()->data().get())
246 theAttribute->owner()->data()->referencesToObjects(allRefs);
247 // collect object referenced by theAttribute
248 std::list<ObjectPtr>* anAttrObjs = 0;
249 std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRefIter = allRefs.begin();
250 for(; aRefIter != allRefs.end(); aRefIter++) {
251 if (theAttribute->id() == aRefIter->first)
252 anAttrObjs = &(aRefIter->second);
254 if (!anAttrObjs || anAttrObjs->empty())
255 return true; // theAttribute does not references to anything
256 // check with all others
257 for(aRefIter = allRefs.begin(); aRefIter != allRefs.end(); aRefIter++) {
258 if (theAttribute->id() == aRefIter->first)
259 continue; // do not check with myself
260 std::list<ObjectPtr>::iterator aReferenced = aRefIter->second.begin();
261 for(; aReferenced != aRefIter->second.end(); aReferenced++) {
262 std::list<ObjectPtr>::iterator aReferencedByMe = anAttrObjs->begin();
263 for(; aReferencedByMe != anAttrObjs->end(); aReferencedByMe++) {
264 if (*aReferenced == *aReferencedByMe) // found same objects!
272 bool PartSet_SketchEntityValidator::isValid(const AttributePtr& theAttribute,
273 const std::list<std::string>& theArguments) const
275 bool isSketchEntities = true;
276 std::set<std::string> anEntityKinds;
277 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
278 for (; anIt != aLast; anIt++) {
279 anEntityKinds.insert(*anIt);
282 std::string anAttributeType = theAttribute->attributeType();
283 if (anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
284 AttributeSelectionListPtr aSelectionListAttr =
285 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
286 // it filters only selection list attributes
287 std::string aType = aSelectionListAttr->selectionType().c_str();
288 // all context objects should be sketch entities
289 int aSize = aSelectionListAttr->size();
290 for (int i = 0; i < aSelectionListAttr->size() && isSketchEntities; i++) {
291 AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i);
292 ObjectPtr anObject = aSelectAttr->context();
293 FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
294 isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
297 if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
298 std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
299 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
300 isSketchEntities = false;
301 if (aRef->isObject()) {
302 ObjectPtr anObject = aRef->object();
303 if (anObject.get() != NULL) {
304 FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
305 if (aFeature.get() != NULL)
306 isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
311 return isSketchEntities;
316 bool PartSet_SameTypeAttrValidator::isValid(
317 const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
319 // there is a check whether the feature contains a point and a linear edge or two point values
320 std::string aParamA = theArguments.front();
321 SessionPtr aMgr = ModelAPI_Session::get();
322 ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
324 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
325 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
329 bool isObject = aRefAttr->isObject();
330 ObjectPtr anObject = aRefAttr->object();
331 if (isObject && anObject) {
332 FeaturePtr aRefFea = ModelAPI_Feature::feature(anObject);
334 AttributeRefAttrPtr aOtherAttr = aFeature->data()->refattr(aParamA);
335 ObjectPtr aOtherObject = aOtherAttr->object();
336 FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject);
337 return aRefFea->getKind() == aOtherFea->getKind();