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 // the type of validated attributes should be equal, attributes with different types are not validated
123 // Check RefAttr attributes
124 std::string anAttrType = theAttribute->attributeType();
125 std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs;
127 if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
128 AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
129 bool isObject = anAttr->isObject();
130 ObjectPtr anObject = anAttr->object();
131 AttributePtr anAttributeAttr = anAttr->attr();
133 anAttrs = aFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
134 if (anAttrs.size() > 0) {
135 std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
136 for(; anAttr != anAttrs.end(); anAttr++) {
137 if ((*anAttr).get() && (*anAttr)->id() != theAttribute->id()) {
138 std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
139 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
140 if (aRef->isObject() != isObject)
143 if (aRef->object() == anObject)
146 else { // the attribute reference
147 if (aRef->attr() == theAttribute)
154 else if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
155 AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
156 ResultPtr aContext = anAttr->context();
157 GeomShapePtr aShape = anAttr->value();
159 // Check selection attributes
160 anAttrs = aFeature->data()->attributes(ModelAPI_AttributeSelection::typeId());
161 if (anAttrs.size() > 0) {
162 std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
163 for(; anAttr != anAttrs.end(); anAttr++) {
164 if ((*anAttr).get() && (*anAttr)->id() != theAttribute->id()) {
165 std::shared_ptr<ModelAPI_AttributeSelection> aRef =
166 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*anAttr);
167 // check the object is already presented
168 if (aRef->context() == aContext) {
169 bool aHasShape = aShape.get() != NULL;
170 if (!aHasShape || aRef->value()->isEqual(aShape))
177 else if (anAttrType == ModelAPI_AttributeReference::typeId()) {
178 AttributeReferencePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
179 ObjectPtr anObject = anAttr->value();
180 // Check selection attributes
181 anAttrs = aFeature->data()->attributes(ModelAPI_AttributeReference::typeId());
182 if (anAttrs.size() > 0) {
183 std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
184 for(; anAttr != anAttrs.end(); anAttr++) {
185 if ((*anAttr).get() && (*anAttr)->id() != theAttribute->id()) {
186 std::shared_ptr<ModelAPI_AttributeReference> aRef =
187 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(*anAttr);
188 // check the object is already presented
189 if (aRef->value() == anObject)
196 return !featureHasReferences(theAttribute);
199 bool PartSet_DifferentObjectsValidator::featureHasReferences(const AttributePtr& theAttribute) const
201 std::list<std::pair<std::string, std::list<ObjectPtr> > > allRefs;
202 if (theAttribute->owner().get() && theAttribute->owner()->data().get())
203 theAttribute->owner()->data()->referencesToObjects(allRefs);
204 // collect object referenced by theAttribute
205 std::list<ObjectPtr>* anAttrObjs = 0;
206 std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRefIter = allRefs.begin();
207 for(; aRefIter != allRefs.end(); aRefIter++) {
208 if (theAttribute->id() == aRefIter->first)
209 anAttrObjs = &(aRefIter->second);
211 if (!anAttrObjs || anAttrObjs->empty())
212 return false; // theAttribute does not references to anything
213 // check with all others
214 for(aRefIter = allRefs.begin(); aRefIter != allRefs.end(); aRefIter++) {
215 if (theAttribute->id() == aRefIter->first)
216 continue; // do not check with myself
217 std::list<ObjectPtr>::iterator aReferenced = aRefIter->second.begin();
218 for(; aReferenced != aRefIter->second.end(); aReferenced++) {
219 std::list<ObjectPtr>::iterator aReferencedByMe = anAttrObjs->begin();
220 for(; aReferencedByMe != anAttrObjs->end(); aReferencedByMe++) {
221 if (*aReferenced == *aReferencedByMe) // found same objects!
229 bool PartSet_SketchEntityValidator::isValid(const AttributePtr& theAttribute,
230 const std::list<std::string>& theArguments) const
232 bool isSketchEntities = true;
233 std::set<std::string> anEntityKinds;
234 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
235 for (; anIt != aLast; anIt++) {
236 anEntityKinds.insert(*anIt);
239 std::string anAttributeType = theAttribute->attributeType();
240 if (anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
241 AttributeSelectionListPtr aSelectionListAttr =
242 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
243 // it filters only selection list attributes
244 std::string aType = aSelectionListAttr->selectionType().c_str();
245 // all context objects should be sketch entities
246 int aSize = aSelectionListAttr->size();
247 for (int i = 0; i < aSelectionListAttr->size() && isSketchEntities; i++) {
248 AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i);
249 ObjectPtr anObject = aSelectAttr->context();
250 FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
251 isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
254 if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
255 std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
256 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
257 isSketchEntities = false;
258 if (aRef->isObject()) {
259 ObjectPtr anObject = aRef->object();
260 if (anObject.get() != NULL) {
261 FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
262 if (aFeature.get() != NULL)
263 isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
268 return isSketchEntities;
273 bool PartSet_SameTypeAttrValidator::isValid(
274 const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
276 // there is a check whether the feature contains a point and a linear edge or two point values
277 std::string aParamA = theArguments.front();
278 SessionPtr aMgr = ModelAPI_Session::get();
279 ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
281 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
282 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
286 bool isObject = aRefAttr->isObject();
287 ObjectPtr anObject = aRefAttr->object();
288 if (isObject && anObject) {
289 FeaturePtr aRefFea = ModelAPI_Feature::feature(anObject);
291 AttributeRefAttrPtr aOtherAttr = aFeature->data()->refattr(aParamA);
292 ObjectPtr aOtherObject = aOtherAttr->object();
293 FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject);
294 return aRefFea->getKind() == aOtherFea->getKind();