-void SketchPlugin_Sketch::attributeChanged() {
- static bool kIsUpdated = false; // to avoid infinitive cycle on attrubtes change
- static bool kIsAttrChanged = false;
- boost::shared_ptr<GeomAPI_Shape> aSelection =
- data()->selection(SketchPlugin_Feature::EXTERNAL_ID())->value();
- if (aSelection && !kIsUpdated) { // update arguments due to the selection value
- kIsUpdated = true;
- // update the sketch plane
- boost::shared_ptr<GeomAPI_Pln> aPlane = GeomAlgoAPI_FaceBuilder::plane(aSelection);
- if (aPlane) {
- double anA, aB, aC, aD;
- aPlane->coefficients(anA, aB, aC, aD);
-
- // calculate attributes of the sketch
- boost::shared_ptr<GeomAPI_Dir> aNormDir(new GeomAPI_Dir(anA, aB, aC));
- boost::shared_ptr<GeomAPI_XYZ> aCoords = aNormDir->xyz();
- boost::shared_ptr<GeomAPI_XYZ> aZero(new GeomAPI_XYZ(0, 0, 0));
- aCoords = aCoords->multiplied(-aD * aCoords->distance(aZero));
- boost::shared_ptr<GeomAPI_Pnt> anOrigPnt(new GeomAPI_Pnt(aCoords));
- // X axis is preferable to be dirX on the sketch
- static const double tol = 1.e-7;
- bool isX = fabs(anA - 1.0) < tol && fabs(aB) < tol && fabs(aC) < tol;
- boost::shared_ptr<GeomAPI_Dir> aTempDir(
- isX ? new GeomAPI_Dir(0, 1, 0) : new GeomAPI_Dir(1, 0, 0));
- boost::shared_ptr<GeomAPI_Dir> aYDir(new GeomAPI_Dir(aNormDir->cross(aTempDir)));
- boost::shared_ptr<GeomAPI_Dir> aXDir(new GeomAPI_Dir(aYDir->cross(aNormDir)));
-
- kIsAttrChanged = false; // track the attributes were really changed during the plane update
- boost::shared_ptr<GeomDataAPI_Point> anOrigin = boost::dynamic_pointer_cast
- <GeomDataAPI_Point>(data()->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
- anOrigin->setValue(anOrigPnt);
- boost::shared_ptr<GeomDataAPI_Dir> aNormal = boost::dynamic_pointer_cast<GeomDataAPI_Dir>(
- data()->attribute(SketchPlugin_Sketch::NORM_ID()));
- aNormal->setValue(aNormDir);
- boost::shared_ptr<GeomDataAPI_Dir> aDirX = boost::dynamic_pointer_cast<GeomDataAPI_Dir>(
- data()->attribute(SketchPlugin_Sketch::DIRX_ID()));
- aDirX->setValue(aXDir);
- boost::shared_ptr<GeomDataAPI_Dir> aDirY = boost::dynamic_pointer_cast<GeomDataAPI_Dir>(
- data()->attribute(SketchPlugin_Sketch::DIRY_ID()));
- aDirY->setValue(aYDir);
- boost::shared_ptr<GeomAPI_Dir> aDir = aPlane->direction();
-
- if (kIsAttrChanged) {
- // the plane was changed, so reexecute sub-elements to update shapes (located in new plane)
- ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
- list<ObjectPtr> aSubs = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->list();
- for(list<ObjectPtr>::iterator aSubIt = aSubs.begin(); aSubIt != aSubs.end(); aSubIt++) {
- boost::shared_ptr<SketchPlugin_Feature> aFeature =
- boost::dynamic_pointer_cast<SketchPlugin_Feature>(*aSubIt);
- if (aFeature && aFactory->validate(aFeature)) {
- aFeature->execute();
- }
- }
- kIsAttrChanged = false;
- }
- }
- kIsUpdated = false;
- } else if (kIsUpdated) { // other attributes are updated during the selection comupation
- kIsAttrChanged = true;
- }