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>
26 #include <GeomAPI_Edge.h>
33 int shapesNbPoints(const ModuleBase_ISelection* theSelection)
35 QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
37 foreach (ModuleBase_ViewerPrs aPrs, aList) {
38 const TopoDS_Shape& aShape = aPrs.shape();
39 if (!aShape.IsNull()) {
40 if (aShape.ShapeType() == TopAbs_VERTEX)
47 int shapesNbLines(const ModuleBase_ISelection* theSelection)
49 QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
51 foreach(ModuleBase_ViewerPrs aPrs, aList) {
52 const TopoDS_Shape& aShape = aPrs.shape();
53 if (!aShape.IsNull()) {
54 if (aShape.ShapeType() == TopAbs_EDGE) {
55 TopoDS_Edge aEdge = TopoDS::Edge(aShape);
56 Standard_Real aStart, aEnd;
57 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd);
58 GeomAdaptor_Curve aAdaptor(aCurve);
59 if (aAdaptor.GetType() == GeomAbs_Line)
67 bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelection) const
69 int aCount = shapesNbPoints(theSelection) + shapesNbLines(theSelection);
70 return (aCount > 0) && (aCount < 3);
73 bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection) const
75 int aCount = shapesNbLines(theSelection);
79 bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSelection) const
81 int aCount = shapesNbLines(theSelection);
82 return (aCount > 0) && (aCount < 3);
85 bool PartSet_ParallelSelection::isValid(const ModuleBase_ISelection* theSelection) const
87 int aCount = shapesNbLines(theSelection);
88 return (aCount > 0) && (aCount < 3);
91 bool PartSet_RadiusSelection::isValid(const ModuleBase_ISelection* theSelection) const
93 QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
94 ModuleBase_ViewerPrs aPrs;
96 foreach (ModuleBase_ViewerPrs aPrs, aList) {
97 const TopoDS_Shape& aShape = aPrs.shape();
98 if (!aShape.IsNull()) {
99 if (aShape.ShapeType() == TopAbs_EDGE) {
100 TopoDS_Edge aEdge = TopoDS::Edge(aShape);
101 Standard_Real aStart, aEnd;
102 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd);
103 GeomAdaptor_Curve aAdaptor(aCurve);
104 if (aAdaptor.GetType() == GeomAbs_Circle)
109 return (aCount == 1);
112 bool PartSet_RigidSelection::isValid(const ModuleBase_ISelection* theSelection) const
114 QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
115 return (aList.count() == 1);
119 bool PartSet_CoincidentSelection::isValid(const ModuleBase_ISelection* theSelection) const
121 int aCount = shapesNbPoints(theSelection);
122 return (aCount > 0) && (aCount < 3);
125 bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection) const
127 int aCount = shapesNbLines(theSelection);
128 return (aCount == 1);
131 bool PartSet_FilletSelection::isValid(const ModuleBase_ISelection* theSelection) const
133 int aCount = shapesNbLines(theSelection);
134 return (aCount > 0) && (aCount < 3);
137 bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection) const
139 QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
140 if ((aList.size() == 0) || (aList.size() > 2))
143 ModuleBase_ViewerPrs aPrs = aList.first();
144 const TopoDS_Shape& aShape = aPrs.shape();
148 if (aShape.ShapeType() != TopAbs_EDGE)
151 std::shared_ptr<GeomAPI_Shape> aShapePtr(new GeomAPI_Shape);
152 aShapePtr->setImpl(new TopoDS_Shape(aShape));
153 GeomAPI_Edge aEdge1(aShapePtr);
155 if (aEdge1.isLine() || aEdge1.isArc()) {
156 if (aList.size() == 2) {
157 // Check second selection
159 const TopoDS_Shape& aShape2 = aPrs.shape();
160 if (aShape2.IsNull())
163 if (aShape2.ShapeType() != TopAbs_EDGE)
166 std::shared_ptr<GeomAPI_Shape> aShapePtr2(new GeomAPI_Shape);
167 aShapePtr2->setImpl(new TopoDS_Shape(aShape2));
168 GeomAPI_Edge aEdge2(aShapePtr2);
169 if (aEdge1.isLine() && aEdge2.isArc())
171 else if (aEdge1.isArc() && aEdge2.isLine())
182 bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute,
183 const std::list<std::string>& theArguments) const
185 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
187 // the type of validated attributes should be equal, attributes with different types are not validated
188 // Check RefAttr attributes
189 std::string anAttrType = theAttribute->attributeType();
190 std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs;
192 if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
193 AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
194 bool isObject = anAttr->isObject();
195 ObjectPtr anObject = anAttr->object();
196 AttributePtr anAttributeAttr = anAttr->attr();
198 anAttrs = aFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
199 if (anAttrs.size() > 0) {
200 std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
201 for(; anAttr != anAttrs.end(); anAttr++) {
202 if ((*anAttr).get() && (*anAttr)->id() != theAttribute->id()) {
203 std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
204 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
205 if (aRef->isObject() != isObject)
208 if (aRef->object() == anObject)
211 else { // the attribute reference
212 if (aRef->attr() == theAttribute)
219 else if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
220 AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
221 ResultPtr aContext = anAttr->context();
222 GeomShapePtr aShape = anAttr->value();
224 // Check selection attributes
225 anAttrs = aFeature->data()->attributes(ModelAPI_AttributeSelection::typeId());
226 if (anAttrs.size() > 0) {
227 std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
228 for(; anAttr != anAttrs.end(); anAttr++) {
229 if ((*anAttr).get() && (*anAttr)->id() != theAttribute->id()) {
230 std::shared_ptr<ModelAPI_AttributeSelection> aRef =
231 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*anAttr);
232 // check the object is already presented
233 if (aRef->context() == aContext) {
234 bool aHasShape = aShape.get() != NULL;
235 if (!aHasShape || aRef->value()->isEqual(aShape))
242 else if (anAttrType == ModelAPI_AttributeReference::typeId()) {
243 AttributeReferencePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
244 ObjectPtr anObject = anAttr->value();
245 // Check selection attributes
246 anAttrs = aFeature->data()->attributes(ModelAPI_AttributeReference::typeId());
247 if (anAttrs.size() > 0) {
248 std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
249 for(; anAttr != anAttrs.end(); anAttr++) {
250 if ((*anAttr).get() && (*anAttr)->id() != theAttribute->id()) {
251 std::shared_ptr<ModelAPI_AttributeReference> aRef =
252 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(*anAttr);
253 // check the object is already presented
254 if (aRef->value() == anObject)
261 else if(anAttrType == ModelAPI_AttributeSelectionList::typeId()) {
262 std::shared_ptr<ModelAPI_AttributeSelectionList> aCurSelList =
263 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
264 anAttrs = aFeature->data()->attributes(ModelAPI_AttributeSelectionList::typeId());
265 if(anAttrs.size() > 0) {
266 std::list<std::shared_ptr<ModelAPI_Attribute>>::iterator anAttrItr = anAttrs.begin();
267 for(; anAttrItr != anAttrs.end(); anAttrItr++){
268 if ((*anAttrItr).get() && (*anAttrItr)->id() != theAttribute->id()){
269 std::shared_ptr<ModelAPI_AttributeSelectionList> aRefSelList =
270 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*anAttrItr);
271 for(int i = 0; i < aCurSelList->size(); i++) {
272 std::shared_ptr<ModelAPI_AttributeSelection> aCurSel = aCurSelList->value(i);
273 for(int j = 0; j < aRefSelList->size(); j++) {
274 std::shared_ptr<ModelAPI_AttributeSelection> aRefSel = aRefSelList->value(j);
275 if(aCurSel->context() == aRefSel->context()) {
276 if(aCurSel->value().get() == NULL || aRefSel->value().get() == NULL
277 || aCurSel->value()->isEqual(aRefSel->value())) {
287 return !featureHasReferences(theAttribute);
290 bool PartSet_DifferentObjectsValidator::featureHasReferences(const AttributePtr& theAttribute) const
292 std::list<std::pair<std::string, std::list<ObjectPtr> > > allRefs;
293 if (theAttribute->owner().get() && theAttribute->owner()->data()->isValid())
294 theAttribute->owner()->data()->referencesToObjects(allRefs);
295 // collect object referenced by theAttribute
296 std::list<ObjectPtr>* anAttrObjs = 0;
297 std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRefIter = allRefs.begin();
298 for(; aRefIter != allRefs.end(); aRefIter++) {
299 if (theAttribute->id() == aRefIter->first)
300 anAttrObjs = &(aRefIter->second);
302 if (!anAttrObjs || anAttrObjs->empty())
303 return false; // theAttribute does not references to anything
304 // check with all others
305 for(aRefIter = allRefs.begin(); aRefIter != allRefs.end(); aRefIter++) {
306 if (theAttribute->id() == aRefIter->first)
307 continue; // do not check with myself
308 std::list<ObjectPtr>::iterator aReferenced = aRefIter->second.begin();
309 for(; aReferenced != aRefIter->second.end(); aReferenced++) {
310 std::list<ObjectPtr>::iterator aReferencedByMe = anAttrObjs->begin();
311 for(; aReferencedByMe != anAttrObjs->end(); aReferencedByMe++) {
312 if (*aReferenced == *aReferencedByMe) // found same objects!
320 bool PartSet_SketchEntityValidator::isValid(const AttributePtr& theAttribute,
321 const std::list<std::string>& theArguments) const
323 bool isSketchEntities = true;
324 std::set<std::string> anEntityKinds;
325 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
326 for (; anIt != aLast; anIt++) {
327 anEntityKinds.insert(*anIt);
330 std::string anAttributeType = theAttribute->attributeType();
331 if (anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
332 AttributeSelectionListPtr aSelectionListAttr =
333 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
334 // it filters only selection list attributes
335 std::string aType = aSelectionListAttr->selectionType().c_str();
336 // all context objects should be sketch entities
337 int aSize = aSelectionListAttr->size();
338 for (int i = 0; i < aSelectionListAttr->size() && isSketchEntities; i++) {
339 AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i);
340 ObjectPtr anObject = aSelectAttr->context();
341 // a context of the selection attribute is a feature result. It can be a case when the result
342 // of the feature is null, e.g. the feature is modified and has not been executed yet.
343 // The validator returns an invalid result here. The case is an extrusion built on a sketch
344 // feature. A new sketch element creation leads to an empty result.
346 isSketchEntities = false;
348 FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
349 isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
353 if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
354 std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
355 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
356 isSketchEntities = false;
357 if (aRef->isObject()) {
358 ObjectPtr anObject = aRef->object();
359 if (anObject.get() != NULL) {
360 FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
361 if (aFeature.get() != NULL)
362 isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
367 return isSketchEntities;
372 bool PartSet_SameTypeAttrValidator::isValid(
373 const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
375 // there is a check whether the feature contains a point and a linear edge or two point values
376 std::string aParamA = theArguments.front();
377 SessionPtr aMgr = ModelAPI_Session::get();
378 ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
380 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
381 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
385 bool isObject = aRefAttr->isObject();
386 ObjectPtr anObject = aRefAttr->object();
387 if (isObject && anObject) {
388 FeaturePtr aRefFea = ModelAPI_Feature::feature(anObject);
390 AttributeRefAttrPtr aOtherAttr = aFeature->data()->refattr(aParamA);
391 ObjectPtr aOtherObject = aOtherAttr->object();
392 FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject);
393 return aRefFea->getKind() == aOtherFea->getKind();