]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Merge remote-tracking branch 'origin/BR_REENTRANCE_OPERATION' into origin_Dev_1.5.0
authornds <nds@opencascade.com>
Mon, 9 Nov 2015 11:34:57 +0000 (14:34 +0300)
committernds <nds@opencascade.com>
Mon, 9 Nov 2015 11:34:57 +0000 (14:34 +0300)
Conflicts:
src/Model/Model_Document.cpp

86 files changed:
doc/CMakeLists.txt
src/FeaturesPlugin/CMakeLists.txt
src/FeaturesPlugin/Test/TestCompositeFeaturesOnCompSolids.py [new file with mode: 0644]
src/FeaturesPlugin/boolean_widget.xml
src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp
src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.h
src/GeomValidators/CMakeLists.txt
src/GeomValidators/GeomValidators_Plugin.cpp [new file with mode: 0644]
src/GeomValidators/GeomValidators_Plugin.h [new file with mode: 0644]
src/GeomValidators/GeomValidators_Tools.cpp
src/GeomValidators/GeomValidators_Tools.h
src/Model/Model_Document.cpp [changed mode: 0644->0755]
src/ModuleBase/CMakeLists.txt
src/ModuleBase/ModuleBase_DoubleSpinBox.h
src/ModuleBase/ModuleBase_IntSpinBox.cpp [new file with mode: 0755]
src/ModuleBase/ModuleBase_IntSpinBox.h [new file with mode: 0755]
src/ModuleBase/ModuleBase_Operation.h
src/ModuleBase/ModuleBase_OperationFeature.cpp
src/ModuleBase/ModuleBase_OperationFeature.h
src/ModuleBase/ModuleBase_Preferences.h
src/ModuleBase/ModuleBase_Tools.cpp
src/ModuleBase/ModuleBase_Tools.h
src/ModuleBase/ModuleBase_WidgetChoice.cpp
src/ModuleBase/ModuleBase_WidgetChoice.h
src/ModuleBase/ModuleBase_WidgetExprEditor.h
src/ModuleBase/ModuleBase_WidgetFileSelector.h
src/ModuleBase/ModuleBase_WidgetIntValue.cpp
src/ModuleBase/ModuleBase_WidgetIntValue.h
src/ModuleBase/ModuleBase_WidgetMultiSelector.h
src/ModuleBase/ModuleBase_WidgetSelector.cpp
src/ModuleBase/ModuleBase_WidgetShapeSelector.cpp
src/ModuleBase/ModuleBase_WidgetShapeSelector.h
src/PartSet/CMakeLists.txt
src/PartSet/PartSet_CustomPrs.cpp
src/PartSet/PartSet_MenuMgr.cpp
src/PartSet/PartSet_Module.cpp
src/PartSet/PartSet_Module.h
src/PartSet/PartSet_OperationPrs.cpp
src/PartSet/PartSet_SketcherMgr.h
src/PartSet/PartSet_Tools.cpp
src/PartSet/PartSet_Tools.h
src/PartSet/PartSet_Validators.cpp
src/PartSet/PartSet_WidgetPoint2d.cpp
src/PartSet/PartSet_WidgetPoint2d.h
src/PartSet/PartSet_WidgetSketchLabel.cpp
src/PartSet/PartSet_WidgetSketchLabel.h
src/PartSet/PartSet_icons.qrc
src/PartSet/icons/angle_up_full_32x32.png [new file with mode: 0755]
src/PartSet/icons/bool_common.png [new file with mode: 0644]
src/PartSet/icons/bool_cut.png [new file with mode: 0644]
src/PartSet/icons/bool_fuse.png [new file with mode: 0644]
src/PartSet/icons/fillet.png
src/PartSet/icons/plane_view.png [new file with mode: 0644]
src/PartSet/icons/translate_32x32.png [new file with mode: 0755]
src/PartSet/icons/translate_full_32x32.png [new file with mode: 0755]
src/PythonAddons/addons_Features.py
src/PythonAddons/macros/box/feature.py
src/SketchPlugin/CMakeLists.txt
src/SketchPlugin/SketchPlugin_Arc.cpp
src/SketchPlugin/SketchPlugin_ConstraintFillet.cpp
src/SketchPlugin/SketchPlugin_MultiRotation.cpp
src/SketchPlugin/SketchPlugin_MultiRotation.h
src/SketchPlugin/SketchPlugin_MultiTranslation.cpp
src/SketchPlugin/SketchPlugin_MultiTranslation.h
src/SketchPlugin/SketchPlugin_SketchEntity.h
src/SketchPlugin/SketchPlugin_Tools.cpp
src/SketchPlugin/SketchPlugin_Tools.h
src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchPlugin/plugin-Sketch.xml
src/SketchSolver/SketchSolver_ConstraintMulti.cpp
src/SketchSolver/SketchSolver_ConstraintMulti.h
src/SketchSolver/SketchSolver_ConstraintMultiRotation.cpp
src/SketchSolver/SketchSolver_ConstraintMultiRotation.h
src/SketchSolver/SketchSolver_ConstraintMultiTranslation.cpp
src/SketchSolver/SketchSolver_ConstraintMultiTranslation.h
src/SketcherPrs/SketcherPrs_SymbolPrs.h
src/XGUI/XGUI_ActionsMgr.cpp
src/XGUI/XGUI_DataModel.cpp
src/XGUI/XGUI_Displayer.cpp
src/XGUI/XGUI_Displayer.h
src/XGUI/XGUI_ObjectsBrowser.cpp
src/XGUI/XGUI_ObjectsBrowser.h
src/XGUI/XGUI_PropertyPanel.cpp
src/XGUI/XGUI_PropertyPanel.h
src/XGUI/XGUI_Selection.cpp
src/XGUI/XGUI_Workshop.cpp

index d769b870848095ff68aa59008529a872db63076f..9cf05cb3f5cadd0108d9c999db6dab9bc7dad437 100644 (file)
@@ -9,7 +9,7 @@ ENDIF(WIN32)
 IF(HAVE_SALOME)
   SET(EXCLUDE_DOC_DIR "*/AppElements/* */OpenParts/*")
 ELSE(HAVE_SALOME)
-  SET(EXCLUDE_DOC_DIR "*/NewGeom/* */Shaper/*")
+  SET(EXCLUDE_DOC_DIR "*/Shaper/*")
 ENDIF(HAVE_SALOME)
 
 CONFIGURE_FILE(doxyfile.in
index 7338ddfb864e2874d370dfea9dc039afa7d45418..a2150fbebed3995f26471d4bcab925da2e96be19 100644 (file)
@@ -97,6 +97,7 @@ ADD_UNIT_TESTS(TestExtrusion.py
                TestRevolutionSketch.py
                TestRevolutionCut.py
                TestRevolutionFuse.py
+               TestCompositeFeaturesOnCompSolids.py
                TestPartition.py
                TestPlacement.py
                TestTranslation.py
diff --git a/src/FeaturesPlugin/Test/TestCompositeFeaturesOnCompSolids.py b/src/FeaturesPlugin/Test/TestCompositeFeaturesOnCompSolids.py
new file mode 100644 (file)
index 0000000..627423f
--- /dev/null
@@ -0,0 +1,219 @@
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+from ModelAPI import *
+from GeomDataAPI import *
+from GeomAlgoAPI import *
+from GeomAPI import *
+
+__updated__ = "2014-12-16"
+
+aSession = ModelAPI_Session.get()
+# Create a part for extrusions & boolean
+aSession.startOperation()
+aPartFeature = aSession.moduleDocument().addFeature("Part")
+aSession.finishOperation()
+aPart = aSession.activeDocument()
+
+#=========================================================================
+# Create a sketch with circle to extrude
+#=========================================================================
+aSession.startOperation()
+aCircleSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch"))
+origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+
+aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
+aCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
+aCircleRadius = aSketchCircle.real("CircleRadius")
+aCircleCentr.setValue(0, 0)
+aCircleRadius.setValue(50)
+
+aSketchLine = aCircleSketchFeature.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
+aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
+aLineStartPoint.setValue(0, -50)
+aLineEndPoint.setValue(0, 50)
+aSession.finishOperation()
+
+#=========================================================================
+# Make extrusion on circle
+#=========================================================================
+# Build shape from sketcher results
+aCircleSketchResult = aCircleSketchFeature.firstResult()
+aCircleSketchEdges = modelAPI_ResultConstruction(aCircleSketchResult).shape()
+origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin")).pnt()
+dirX = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX")).dir()
+norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm")).dir()
+aCircleSketchFaces = ShapeList()
+GeomAlgoAPI_SketchBuilder.createFaces(
+    origin, dirX, norm, aCircleSketchEdges, aCircleSketchFaces)
+assert (len(aCircleSketchFaces) > 0)
+assert (aCircleSketchFaces[0] is not None)
+# Create extrusion
+aSession.startOperation()
+anExtrusionFt = aPart.addFeature("Extrusion")
+assert (anExtrusionFt.getKind() == "Extrusion")
+# selection type FACE=4
+anExtrusionFt.selectionList("base").append(
+    aCircleSketchResult, None)
+anExtrusionFt.string("CreationMethod").setValue("BySizes")
+anExtrusionFt.real("to_size").setValue(50)
+anExtrusionFt.real("from_size").setValue(0)
+anExtrusionFt.real("to_offset").setValue(0) #TODO: remove
+anExtrusionFt.real("from_offset").setValue(0) #TODO: remove
+anExtrusionFt.execute()
+aSession.finishOperation()
+assert (anExtrusionFt.real("to_size").value() == 50.0)
+
+# Check extrusion results
+assert (len(anExtrusionFt.results()) > 0)
+anExtrusionResult = modelAPI_ResultBody(anExtrusionFt.firstResult())
+assert (anExtrusionResult is not None)
+
+#=========================================================================
+# Test extrusion cut between bounding planes
+#=========================================================================
+# Create from plane
+aSession.startOperation()
+aFromPlaneFeature = aPart.addFeature("Plane")
+aFromPlaneFeature.string("CreationMethod").setValue("PlaneByGeneralEquation")
+aFromPlaneFeature.real("A").setValue(0.)
+aFromPlaneFeature.real("B").setValue(0.)
+aFromPlaneFeature.real("C").setValue(1.)
+aFromPlaneFeature.real("D").setValue(-25.)
+aSession.finishOperation()
+
+# Create to plane
+aSession.startOperation()
+aToPlaneFeature = aPart.addFeature("Plane")
+aToPlaneFeature.string("CreationMethod").setValue("PlaneByGeneralEquation")
+aToPlaneFeature.real("A").setValue(0.)
+aToPlaneFeature.real("B").setValue(0.)
+aToPlaneFeature.real("C").setValue(1.)
+aToPlaneFeature.real("D").setValue(-60.)
+aSession.finishOperation()
+
+#=========================================================================
+# Make extrusion cut
+#=========================================================================
+aSession.startOperation()
+anExtrusionCutFt = featureToCompositeFeature(aPart.addFeature("ExtrusionCut"))
+assert (anExtrusionCutFt.getKind() == "ExtrusionCut")
+# selection type FACE=4
+aSession.startOperation()
+aCircleSketchFeature = featureToCompositeFeature(anExtrusionCutFt.addFeature("Sketch"))
+origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 50)
+dirx = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aCircleSketchFeature.selection("External").selectSubShape("face", "Extrusion_1/TopFace_1")
+aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
+aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr.setValue(0, 0)
+aCircleRadius.setValue(10)
+aSession.finishOperation()
+aSession.startOperation()
+anExtrusionCutFt.string("CreationMethod").setValue("ByPlanesAndOffsets")
+anExtrusionCutFt.real("to_size").setValue(0)
+anExtrusionCutFt.real("from_size").setValue(0)
+aToResult = aToPlaneFeature.firstResult()
+aToShape = modelAPI_ResultConstruction(aToResult).shape()
+anExtrusionCutFt.selection("to_object").setValue(aToResult, aToShape)
+anExtrusionCutFt.real("to_offset").setValue(0)
+aFromResult = aFromPlaneFeature.firstResult()
+aFromShape = modelAPI_ResultConstruction(aFromResult).shape()
+anExtrusionCutFt.selection("from_object").setValue(aFromResult, aFromShape)
+anExtrusionCutFt.real("from_offset").setValue(0)
+anExtrusionCutFt.selectionList("boolean_objects").append(modelAPI_ResultCompSolid(anExtrusionResult).subResult(1), None)
+anExtrusionCutFt.execute()
+aSession.finishOperation()
+aSession.finishOperation()
+
+#=========================================================================
+# Test results
+#=========================================================================
+aFactory = ModelAPI_Session.get().validators()
+assert (aFactory.validate(anExtrusionCutFt))
+assert (len(anExtrusionCutFt.results()) > 0)
+aCurrentResult = modelAPI_ResultBody(anExtrusionCutFt.firstResult())
+assert (aCurrentResult is not None)
+aSession.undo()
+
+#=========================================================================
+# Create a sketch line to revol
+#=========================================================================
+aSession.startOperation()
+aLineSketchFeature = featureToCompositeFeature(aPart.addFeature("Sketch"))
+origin = geomDataAPI_Point(aLineSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aLineSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+norm = geomDataAPI_Dir(aLineSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+
+aSketchLine = aLineSketchFeature.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
+aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
+aLineStartPoint.setValue(-50., 50.)
+aLineEndPoint.setValue(-50., -50.)
+aSession.finishOperation()
+
+# Build shape from sketcher results
+aLineSketchResult = aLineSketchFeature.firstResult()
+aLineSketchShape = modelAPI_ResultConstruction(aLineSketchResult).shape()
+aShapeExplorer = GeomAPI_ShapeExplorer(aLineSketchShape, GeomAPI_Shape.EDGE)
+aLineEdge = aShapeExplorer.current()
+
+#=========================================================================
+# Make revolution fuse
+#=========================================================================
+aSession.startOperation()
+anRevolutionFuseFt = featureToCompositeFeature(aPart.addFeature("RevolutionFuse"))
+assert (anRevolutionFuseFt.getKind() == "RevolutionFuse")
+# selection type FACE=4
+aSession.startOperation()
+aCircleSketchFeature = featureToCompositeFeature(anRevolutionFuseFt.addFeature("Sketch"))
+origin = geomDataAPI_Point(aCircleSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 50)
+dirx = geomDataAPI_Dir(aCircleSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+norm = geomDataAPI_Dir(aCircleSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aCircleSketchFeature.selection("External").selectSubShape("face", "Extrusion_1/TopFace_1")
+aSketchCircle = aCircleSketchFeature.addFeature("SketchCircle")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
+aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr.setValue(0, 0)
+aCircleRadius.setValue(10)
+aSession.finishOperation()
+aSession.startOperation()
+anRevolutionFuseFt.selection("axis_object").setValue(aLineSketchResult, aLineEdge)
+anRevolutionFuseFt.string("CreationMethod").setValue("ByPlanesAndOffsets")
+anRevolutionFuseFt.real("from_angle").setValue(0) #TODO: remove
+anRevolutionFuseFt.real("to_angle").setValue(0) #TODO: remove
+anRevolutionFuseFt.selection("to_object").setValue(aToResult, None)
+anRevolutionFuseFt.real("to_offset").setValue(0)
+anRevolutionFuseFt.selection("from_object").setValue(None, None)
+anRevolutionFuseFt.real("from_offset").setValue(0)
+anRevolutionFuseFt.selectionList("boolean_objects").append(modelAPI_ResultCompSolid(anExtrusionResult).subResult(1), None)
+anRevolutionFuseFt.execute()
+aSession.finishOperation()
+aSession.finishOperation()
+
+#=========================================================================
+# Test results
+#=========================================================================
+aFactory = ModelAPI_Session.get().validators()
+assert (aFactory.validate(anRevolutionFuseFt))
+assert (len(anRevolutionFuseFt.results()) > 0)
+aCurrentResult = modelAPI_ResultBody(anRevolutionFuseFt.firstResult())
+assert (aCurrentResult is not None)
+
index 8fc0925caf92ddcaa47fbb9ff07a5abfaf2a4230..cdf755b6c21010fecaf50b1413579a93c2ceea84 100644 (file)
@@ -1,9 +1,18 @@
 <!-- Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
 
 <source>
+  <choice id="bool_type"
+    widget_type="radiobuttons"
+    buttons_dir="horizontal"
+    label="Operation type" 
+    tooltip="Type of boolean operation"
+    string_list="Cut Fuse Common"
+    icons_list=":icons/bool_cut.png :icons/bool_fuse.png :icons/bool_common.png"
+    default="0"
+  />
   <multi_selector id="main_objects"
     label="Main objects"
-    icon=":icons/cut_shape.png"
+    icon=""
     tooltip="Select a solid objects"
     type_choice="Solids"
     concealment="true">
   </multi_selector>
   <multi_selector id="tool_objects" 
     label="Tool object" 
-    icon=":icons/cut_tool.png
+    icon="" 
     tooltip="Select a tool solid"
     type_choice="Solids"
     concealment="true" >
     <validator id="PartSet_DifferentObjects"/>
     <validator id="GeomValidators_ShapeType" parameters="empty,solid"/>
   </multi_selector>
-  <choice id="bool_type" 
-    label="Type" 
-    tooltip="Type of boolean operation"
-    string_list="Cut Fuse Common"
-    default="0"
-  />
   <validator id="GeomValidators_BooleanArguments" parameters="main_objects,tool_objects,bool_type"/>
 </source>
index f5e69c52fc1ef53430e26d4145a0427539ad6c3e..e608956c683b3d0556672c0bdc5c1f6381339b82 100644 (file)
@@ -20,8 +20,7 @@ GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape(void* theMkShape, const AlgoType th
   myShape(new GeomAPI_Shape())
 {
   switch (myAlgoType) {
-    case MakeShape:
-    case MakePipe: {
+    case MakeShape: {
       myShape->setImpl(new TopoDS_Shape(implPtr<BRepBuilderAPI_MakeShape>()->Shape()));
       break;
     }
@@ -32,19 +31,6 @@ GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape(void* theMkShape, const AlgoType th
   }
 }
 
-//=================================================================================================
-GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape(void* theMkShape,
-                                             const std::shared_ptr<GeomAPI_Shape> theWire,
-                                             const std::shared_ptr<GeomAPI_Shape> theBaseShape)
-: GeomAPI_Interface(theMkShape),
-  myAlgoType(MakePipe),
-  myShape(new GeomAPI_Shape()),
-  myWire(theWire),
-  myBaseShape(theBaseShape)
-{
-  myShape->setImpl(new TopoDS_Shape(implPtr<BRepOffsetAPI_MakePipe>()->Shape()));
-}
-
 //=================================================================================================
 const std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_MakeShape::shape() const
 {
@@ -55,52 +41,21 @@ const std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_MakeShape::shape() const
 void GeomAlgoAPI_MakeShape::generated(const std::shared_ptr<GeomAPI_Shape> theShape,
                                       ListOfShape& theHistory)
 {
-  if(myAlgoType == MakePipe) {
-    BRepOffsetAPI_MakePipe* aMakePipe = implPtr<BRepOffsetAPI_MakePipe>();
-    TopExp_Explorer aShapeExplorer(myWire->impl<TopoDS_Wire>(), TopAbs_EDGE);
-    for (; aShapeExplorer.More(); aShapeExplorer.Next ()) {
-      const TopoDS_Shape& aSpine = aShapeExplorer.Current();
-      const TopoDS_Shape& aProfile = theShape->impl<TopoDS_Shape>();
-      if(aProfile.ShapeType() != TopAbs_EDGE && aProfile.ShapeType() != TopAbs_VERTEX) {
-          return;
-      }
-      const TopoDS_Shape& aBaseShape = myBaseShape->impl<TopoDS_Shape>();
-      TopExp_Explorer anExp(aBaseShape, aProfile.ShapeType());
-      Standard_Boolean hasShape = Standard_False;
-      for(; anExp.More(); anExp.Next()) {
-        if(anExp.Current().IsSame(aProfile)) {
-          hasShape = Standard_True;
-          break;
-        }
-      }
-      if(!hasShape) {
-        return;
-      }
-      const TopoDS_Shape& aGeneratedShape = aMakePipe->Generated(aSpine, aProfile);
-      if(aGeneratedShape.IsNull()) {
-        continue;
-      }
-      std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
-      aShape->setImpl(new TopoDS_Shape(aGeneratedShape));
-      theHistory.push_back(aShape);
-    }
-  } else {
-    TopTools_ListOfShape aList;
-    if(myAlgoType == MakeShape) {
-      BRepBuilderAPI_MakeShape* aMakeShape = implPtr<BRepBuilderAPI_MakeShape>();
-      aList = aMakeShape->Generated(theShape->impl<TopoDS_Shape>());
-    } else if(myAlgoType == BOPAlgoBuilder) {
-      BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
-      aList = aBOPBuilder->Generated(theShape->impl<TopoDS_Shape>());
-    }
-    for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) {
-      if(anIt.Value().IsNull()) {
-        continue;
-      }
-      std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
-      aShape->setImpl(new TopoDS_Shape(anIt.Value()));
-      theHistory.push_back(aShape);
+  TopTools_ListOfShape aList;
+  if(myAlgoType == MakeShape) {
+    BRepBuilderAPI_MakeShape* aMakeShape = implPtr<BRepBuilderAPI_MakeShape>();
+    aList = aMakeShape->Generated(theShape->impl<TopoDS_Shape>());
+  } else if(myAlgoType == BOPAlgoBuilder) {
+    BOPAlgo_Builder* aBOPBuilder = implPtr<BOPAlgo_Builder>();
+    aList = aBOPBuilder->Generated(theShape->impl<TopoDS_Shape>());
+  }
+  for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) {
+    if(anIt.Value().IsNull()) {
+      continue;
     }
+    std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
+    aShape->setImpl(new TopoDS_Shape(anIt.Value()));
+    theHistory.push_back(aShape);
   }
 }
 
index b4e46e54a15d7e1c1fbc3263086ebcfcff148625..ea89fe89ede7807a76f8a2347c5cb96d53015ed8 100644 (file)
@@ -22,7 +22,6 @@ public:
   /// Algo type enum
   enum AlgoType {
     MakeShape,
-    MakePipe,
     BOPAlgoBuilder
   };
 
@@ -30,11 +29,6 @@ public:
   /// Constructor by the already stored builder in the interface
   GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape(void* theBuilder, const AlgoType theAlgoType = MakeShape);
 
-  /// Constructor by the builder and wire. Used for pipe builder.
-  GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeShape(void* theBuilder,
-                                           const std::shared_ptr<GeomAPI_Shape> theWire,
-                                           const std::shared_ptr<GeomAPI_Shape> theBaseShape);
-
   /// Returns a shape built by the shape construction algorithm
   GEOMALGOAPI_EXPORT virtual const std::shared_ptr<GeomAPI_Shape> shape() const;
 
index 2450cf38c23ba42dea837b6a252aedc2ac02f9e6..c9768eb39f606c33e5a82ccacd2673ad947869c6 100644 (file)
@@ -10,6 +10,7 @@ SET(PROJECT_HEADERS
     GeomValidators_Face.h
     GeomValidators_Finite.h
     GeomValidators_PartitionArguments.h
+    GeomValidators_Plugin.h
     GeomValidators_Positive.h
     GeomValidators_ShapeType.h
     GeomValidators_Tools.h
@@ -24,6 +25,7 @@ SET(PROJECT_SOURCES
     GeomValidators_Face.cpp
     GeomValidators_Finite.cpp
     GeomValidators_PartitionArguments.cpp
+    GeomValidators_Plugin.cpp
     GeomValidators_Positive.cpp
     GeomValidators_ShapeType.cpp
     GeomValidators_Tools.cpp
diff --git a/src/GeomValidators/GeomValidators_Plugin.cpp b/src/GeomValidators/GeomValidators_Plugin.cpp
new file mode 100644 (file)
index 0000000..e8f8574
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+#include <GeomValidators_Plugin.h>
+
+#include <GeomValidators_BooleanArguments.h>
+#include <GeomValidators_ConstructionComposite.h>
+#include <GeomValidators_Different.h>
+#include <GeomValidators_DifferentShapes.h>
+#include <GeomValidators_Face.h>
+#include <GeomValidators_Finite.h>
+#include <GeomValidators_PartitionArguments.h>
+#include <GeomValidators_ShapeType.h>
+#include <GeomValidators_ZeroOffset.h>
+
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
+// the only created instance of this plugin
+static GeomValidators_Plugin* MY_GEOMVALIDATORS_INSTANCE = new GeomValidators_Plugin();
+
+GeomValidators_Plugin::GeomValidators_Plugin()
+{
+  // register validators
+  SessionPtr aMgr = ModelAPI_Session::get();
+  ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+
+  aFactory->registerValidator("GeomValidators_BooleanArguments", new GeomValidators_BooleanArguments);
+  aFactory->registerValidator("GeomValidators_ConstructionComposite", new GeomValidators_ConstructionComposite);
+  aFactory->registerValidator("GeomValidators_Different", new GeomValidators_Different);
+  aFactory->registerValidator("GeomValidators_DifferentShapes", new GeomValidators_DifferentShapes);
+  aFactory->registerValidator("GeomValidators_Face", new GeomValidators_Face);
+  aFactory->registerValidator("GeomValidators_Finite", new GeomValidators_Finite);
+  aFactory->registerValidator("GeomValidators_PartitionArguments", new GeomValidators_PartitionArguments);
+  aFactory->registerValidator("GeomValidators_ShapeType", new GeomValidators_ShapeType);
+  aFactory->registerValidator("GeomValidators_ZeroOffset", new GeomValidators_ZeroOffset);
+
+  // register this plugin
+  ModelAPI_Session::get()->registerPlugin(this);
+}
+
+FeaturePtr GeomValidators_Plugin::createFeature(std::string theFeatureID)
+{
+  // feature of such kind is not found
+  return FeaturePtr();
+}
diff --git a/src/GeomValidators/GeomValidators_Plugin.h b/src/GeomValidators/GeomValidators_Plugin.h
new file mode 100644 (file)
index 0000000..3c428d9
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File:        GeomValidators_Plugin.h
+// Created:     28 Oct 2015
+// Author:      Sergey POKHODENKO
+
+#ifndef GEOMVALIDATORS_PLUGIN_H_
+#define GEOMVALIDATORS_PLUGIN_H_
+
+#include <GeomValidators.h>
+#include <ModelAPI_Plugin.h>
+#include <ModelAPI_Feature.h>
+
+/**\class GeomValidators_Plugin
+ * \ingroup Plugins
+ * \brief Interface common for any plugin: allows to use plugin by the plugins manager.
+ */
+class GEOMVALIDATORS_EXPORT GeomValidators_Plugin : public ModelAPI_Plugin
+{
+public:
+  /// Creates the feature object of this plugin by the feature string ID
+  virtual FeaturePtr createFeature(std::string theFeatureID);
+
+public:
+  GeomValidators_Plugin();
+};
+
+#endif
index 7f16f08144f74048798b6dd4a902d6fcf8d0be97..ef49c197d24bd69d48ae8108bb351b6c4509252e 100644 (file)
@@ -36,30 +36,4 @@ namespace GeomValidators_Tools {
     return anObject;
   }
 
-  TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape)
-  {
-    TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
-
-    // for compounds check sub-shapes: it may be compound of needed type:
-    // Booleans may produce compounds of Solids
-    if (aShapeType == TopAbs_COMPOUND) {
-      for(TopoDS_Iterator aSubs(theShape); aSubs.More(); aSubs.Next()) {
-        if (!aSubs.Value().IsNull()) {
-          TopAbs_ShapeEnum aSubType = aSubs.Value().ShapeType();
-          if (aSubType == TopAbs_COMPOUND) { // compound of compound(s)
-            aShapeType = TopAbs_COMPOUND;
-            break;
-          }
-          if (aShapeType == TopAbs_COMPOUND) {
-            aShapeType = aSubType;
-          } else if (aShapeType != aSubType) { // compound of shapes of different types
-            aShapeType = TopAbs_COMPOUND;
-            break;
-          }
-        }
-      }
-    }
-    return aShapeType;
-  }
-
 }
index 83a2c3f666b7d9681fb81078f7cc5a7e971f761e..3912db484c4dd4aa4616c65f785b81a9d4599b70 100644 (file)
@@ -20,10 +20,6 @@ namespace GeomValidators_Tools
   /// \param theObj an object 
   GEOMVALIDATORS_EXPORT ObjectPtr getObject(const AttributePtr& theAttribute);
 
-  // Returns the object from the attribute
-  /// \param theObj an object 
-  GEOMVALIDATORS_EXPORT TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape);
-
 };
 
 #endif
old mode 100644 (file)
new mode 100755 (executable)
index 3bd1fba4f2563e663d5d727db325e55cc0c45839..0969deb10369da48d4167659bbead1e36800e8da 100644 (file)
@@ -13,6 +13,7 @@ SET(PROJECT_HEADERS
   ModuleBase_FilterValidated.h
   ModuleBase_IErrorMgr.h
   ModuleBase_IModule.h
+  ModuleBase_IntSpinBox.h
   ModuleBase_IPrefMgr.h
   ModuleBase_IPropertyPanel.h
   ModuleBase_ISelection.h
@@ -64,6 +65,7 @@ SET(PROJECT_SOURCES
   ModuleBase_FilterValidated.cpp
   ModuleBase_IErrorMgr.cpp
   ModuleBase_IModule.cpp
+  ModuleBase_IntSpinBox.cpp
   ModuleBase_IPrefMgr.cpp
   ModuleBase_IPropertyPanel.cpp
   ModuleBase_ISelection.cpp
@@ -113,7 +115,6 @@ SET(PROJECT_LIBRARIES
        GeomAPI
        GeomDataAPI
        GeomAlgoAPI
-       GeomValidators
        ${QT_LIBRARIES}
        ${CAS_VIEWER}
        ${CAS_KERNEL}
@@ -141,7 +142,6 @@ INCLUDE_DIRECTORIES(
     ${CMAKE_SOURCE_DIR}/src/GeomDataAPI
     ${CMAKE_SOURCE_DIR}/src/GeomAPI
     ${CMAKE_SOURCE_DIR}/src/GeomAlgoAPI
-    ${CMAKE_SOURCE_DIR}/src/GeomValidators
     ${SUIT_INCLUDE}
 )
 
index e1fd8bd61f7341e2cb8419fbdd0b850e576ed73d..63e6a7bbe4610e50691e4c3b6c5bf3c85e6c592d 100644 (file)
@@ -63,11 +63,13 @@ Q_OBJECT
  protected slots:
    /// Called on text changed
   virtual void onTextChanged(const QString&);
+  /// Called on value changed
   void onValueChanged(const QString& theValue);
 
  protected:
    /// Removes extra trailing zero symbols
   QString removeTrailingZeroes(const QString&) const;
+  /// Called on key press event
   virtual void keyPressEvent(QKeyEvent* theEvent);
 
  private:
diff --git a/src/ModuleBase/ModuleBase_IntSpinBox.cpp b/src/ModuleBase/ModuleBase_IntSpinBox.cpp
new file mode 100755 (executable)
index 0000000..933cc84
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:      ModuleBase_IntSpinBox.cxx
+// Author:    Natalia ERMOLAEVA
+//
+#include "ModuleBase_IntSpinBox.h"
+
+#include <QKeyEvent>
+
+ModuleBase_IntSpinBox::ModuleBase_IntSpinBox(QWidget* theParent)
+: QSpinBox(theParent),
+  myIsModified(false)
+{
+  connect(this, SIGNAL(valueChanged(const QString&)), this, SLOT(onValueChanged(const QString&)));
+}
+
+void ModuleBase_IntSpinBox::onValueChanged(const QString& theValue)
+{
+  myIsModified = true;
+}
+
+bool ModuleBase_IntSpinBox::isModified() const
+{
+  return myIsModified;
+}
+
+void ModuleBase_IntSpinBox::clearModified()
+{
+  myIsModified = false;
+}
diff --git a/src/ModuleBase/ModuleBase_IntSpinBox.h b/src/ModuleBase/ModuleBase_IntSpinBox.h
new file mode 100755 (executable)
index 0000000..2e6d959
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File:      ModuleBase_IntSpinBox.h
+// Author:    Natalia ERMOLAEVA
+//
+#ifndef MODULEBASE_INT_SPINBOX_H_
+#define MODULEBASE_INT_SPINBOX_H_
+
+#include "ModuleBase.h"
+
+#include <QSpinBox>
+
+class QWidget;
+class QKeyEvent;
+
+/**
+  * \ingroup GUI
+  * Enhanced version of the Qt's int spin box.
+  * It allows to store modified state
+*/
+class MODULEBASE_EXPORT ModuleBase_IntSpinBox : public QSpinBox
+{
+Q_OBJECT
+
+public:
+  explicit ModuleBase_IntSpinBox(QWidget* theParent = 0);
+  virtual ~ModuleBase_IntSpinBox() {};
+
+  /// Returns true if the current value is modified by has not been applyed yet
+  virtual bool isModified() const;
+
+  /// Clears modified state
+  void clearModified();
+
+protected slots:
+  /// Called on value changed
+  void onValueChanged(const QString& theValue);
+
+ private:
+  /// Boolean value whether the spin box content is modified
+  bool myIsModified;
+};
+
+#endif
index 12e5ddb86a91ef2d4f581da500541337fb292c53..a7cf23c5b9942f074f1965ac722215e7686f667f 100644 (file)
@@ -92,14 +92,17 @@ Q_OBJECT
 signals:
   /// The operation is started
   void beforeStarted();
+  /// The operation is started
   void started();
 
   /// The operation is aborted
   void beforeAborted();
+  /// The operation is aborted
   void aborted();
 
   /// The operation is committed
   void beforeCommitted();
+  /// The operation is committed
   void committed();
 
   /// The operation is aborted or committed
index 20331230cdfa0a81dd52b88744c8b54a00ed2d79..da5ff1fcb2c3f5325ad25c0e63fbf2621719d138 100755 (executable)
@@ -247,7 +247,8 @@ void ModuleBase_OperationFeature::abort()
   if (aPropertyPanel)
     aPropertyPanel->cleanContent();
 
-  myFeature->setStable(true);
+  if (myFeature.get())
+    myFeature->setStable(true);
 
   abortOperation();
   stopOperation();
index 2cc3d2a3dfe4cb59292cda3244451cdef7f4ee03..32e648bd9b0fc96797cf4c76613e55984fcf857a 100755 (executable)
@@ -115,7 +115,7 @@ Q_OBJECT
   CompositeFeaturePtr parentFeature() const;
 
   /// Stores the previous to the operation current feature
-  /// \set theFeature a feature
+  /// \param theFeature a feature
   void setPreviousCurrentFeature(const FeaturePtr& theFeature);
 
   /// Returns the previous to the operation current feature
index 47d47206c76978573951536fd2350187bd8475ad..c3f31b76e732213e964ec3c049fcf64ef101b60a 100644 (file)
@@ -60,6 +60,7 @@ class MODULEBASE_EXPORT ModuleBase_Preferences
   /// Retrieve preferences of resource manage to default state
   static void resetResourcePreferences(SUIT_PreferenceMgr* thePref);
 
+  /// Retrieve preferences of config prop to default state
   static void resetConfigPropPreferences(SUIT_PreferenceMgr* thePref);
 
 private:
index d2009ac41fc63f31006a51439d9916eb51e71362..5d3643ab79a3b882a54a400c0a2f00b11c53dade 100755 (executable)
@@ -7,14 +7,18 @@
 #include "ModuleBase_Tools.h"
 #include <ModuleBase_ParamSpinBox.h>
 
-#include <ModelAPI_Result.h>
-#include <ModelAPI_Data.h>
 #include <ModelAPI_Attribute.h>
 #include <ModelAPI_AttributeRefAttr.h>
-#include <ModelAPI_ResultParameter.h>
+#include <ModelAPI_AttributeReference.h>
+#include <ModelAPI_AttributeSelection.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Result.h>
 #include <ModelAPI_ResultCompSolid.h>
+#include <ModelAPI_ResultParameter.h>
 #include <ModelAPI_Tools.h>
 
+#include <TopoDS_Iterator.hxx>
+
 #include <GeomDataAPI_Point2D.h>
 #include <Events_Error.h>
 
@@ -266,6 +270,54 @@ Quantity_Color color(const std::string& theSection,
   return Quantity_Color(aColor[0] / 255., aColor[1] / 255., aColor[2] / 255., Quantity_TOC_RGB);
 }
 
+ObjectPtr getObject(const AttributePtr& theAttribute)
+{
+  ObjectPtr anObject;
+  std::string anAttrType = theAttribute->attributeType();
+  if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
+    AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+    if (anAttr != NULL && anAttr->isObject())
+      anObject = anAttr->object();
+  }
+  if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
+    AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+    if (anAttr != NULL)
+      anObject = anAttr->context();
+  }
+  if (anAttrType == ModelAPI_AttributeReference::typeId()) {
+    AttributeReferencePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
+    if (anAttr.get() != NULL)
+      anObject = anAttr->value();
+  }
+  return anObject;
+}
+
+TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape)
+{
+  TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
+
+  // for compounds check sub-shapes: it may be compound of needed type:
+  // Booleans may produce compounds of Solids
+  if (aShapeType == TopAbs_COMPOUND) {
+    for(TopoDS_Iterator aSubs(theShape); aSubs.More(); aSubs.Next()) {
+      if (!aSubs.Value().IsNull()) {
+        TopAbs_ShapeEnum aSubType = aSubs.Value().ShapeType();
+        if (aSubType == TopAbs_COMPOUND) { // compound of compound(s)
+          aShapeType = TopAbs_COMPOUND;
+          break;
+        }
+        if (aShapeType == TopAbs_COMPOUND) {
+          aShapeType = aSubType;
+        } else if (aShapeType != aSubType) { // compound of shapes of different types
+          aShapeType = TopAbs_COMPOUND;
+          break;
+        }
+      }
+    }
+  }
+  return aShapeType;
 }
 
+} // namespace ModuleBase_Tools
+
 
index 600a5334f8852f5e34b3ecfe98e39821d0eed325..f78e9b7550a627306754dd9469fbf0aee16f67c5 100755 (executable)
@@ -10,7 +10,9 @@
 #include "ModuleBase.h"
 #include "ModuleBase_Definitions.h"
 
+#include <ModelAPI_Attribute.h>
 #include <ModelAPI_Feature.h>
+
 #include <TopAbs_ShapeEnum.hxx>
 #include <TopoDS_Shape.hxx>
 #include <Prs3d_Drawer.hxx>
@@ -120,6 +122,16 @@ MODULEBASE_EXPORT void setDefaultDeviationCoefficient(const TopoDS_Shape& theSha
 MODULEBASE_EXPORT Quantity_Color color(const std::string& theSection,
                                        const std::string& theName,
                                        const std::string& theDefault);
+
+
+// Returns the object from the attribute
+/// \param theObj an object
+MODULEBASE_EXPORT ObjectPtr getObject(const AttributePtr& theAttribute);
+
+// Returns the object from the attribute
+/// \param theObj an object
+MODULEBASE_EXPORT TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape);
+
 }
 
 #endif
index c89508324c86fb47807bb34de494e79ef99ac2f5..4b09ffab63f7f6fd637f3132ca66ebb2789934a4 100644 (file)
 #include <QLayout>
 #include <QLabel>
 #include <QComboBox>
+#include <QButtonGroup>
+#include <QGroupBox>
+#include <QRadioButton>
+#include <QToolButton>
+
 
 ModuleBase_WidgetChoice::ModuleBase_WidgetChoice(QWidget* theParent, 
                                                  const Config_WidgetAPI* theData, 
                                                  const std::string& theParentId)
-    : ModuleBase_ModelWidget(theParent, theData, theParentId)
+    : ModuleBase_ModelWidget(theParent, theData, theParentId), myCombo(0), myButtons(0)
 {
   QHBoxLayout* aLayout = new QHBoxLayout(this);
   ModuleBase_Tools::adjustMargins(aLayout);
 
   QString aLabelText = QString::fromStdString(theData->widgetLabel());
   QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
-  myLabel = new QLabel(aLabelText, this);
-  if (!aLabelIcon.isEmpty())
-    myLabel->setPixmap(QPixmap(aLabelIcon));
-  aLayout->addWidget(myLabel);
-
-  std::string aToolstr = theData->widgetTooltip();
-  if (!aToolstr.empty()) {
-    myLabel->setToolTip(QString::fromStdString(aToolstr));
-  }
-
-  myCombo = new QComboBox(this);
-  aLayout->addWidget(myCombo, 1);
   std::string aTypes = theData->getProperty("string_list");
   QStringList aList = QString(aTypes.c_str()).split(' ');
-  myCombo->addItems(aList);
 
-  connect(myCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
+  // Widget type can be combobox or radiobuttons
+  std::string aWgtType = theData->getProperty("widget_type");
+  if ((aWgtType.length() > 0) && (aWgtType == "radiobuttons")) {
+    myButtons = new QButtonGroup(this);
+    QGroupBox* aGroupBox = new QGroupBox(aLabelText, this);
+    aLayout->addWidget(aGroupBox);
+
+
+    QLayout* aBtnLayout = 0;
+    std::string aWgtDir = theData->getProperty("buttons_dir");
+    if (aWgtDir == "horizontal")
+      aBtnLayout = new QHBoxLayout(aGroupBox);
+    else 
+      aBtnLayout = new QVBoxLayout(aGroupBox);
+    ModuleBase_Tools::adjustMargins(aBtnLayout);
+
+    std::string aIcons = theData->getProperty("icons_list");
+    QStringList aIconList = QString(aIcons.c_str()).split(' ');
+    if (aIconList.length() == aList.length()) {
+      int aId = 0;
+      foreach(QString aBtnTxt, aList) {
+        QToolButton* aBtn = new QToolButton(aGroupBox);
+        aBtn->setCheckable(true);
+        aBtn->setToolTip(aBtnTxt);
+
+        QPixmap aIcon(aIconList.at(aId));
+        aBtn->setIcon(aIcon);
+        aBtn->setIconSize(aIcon.size());
+        
+        aBtnLayout->addWidget(aBtn);
+        myButtons->addButton(aBtn, aId++);
+      }
+
+    } else {
+      int aId = 0;
+      foreach(QString aBtnTxt, aList) {
+        QRadioButton* aBtn = new QRadioButton(aBtnTxt, aGroupBox);
+        aBtnLayout->addWidget(aBtn);
+        myButtons->addButton(aBtn, aId++);
+      }
+    }
+    myButtons->button(0)->setChecked(true);
+    connect(myButtons, SIGNAL(buttonClicked(int)), this, SLOT(onCurrentIndexChanged(int)));
+  } else {
+    myLabel = new QLabel(aLabelText, this);
+    if (!aLabelIcon.isEmpty())
+      myLabel->setPixmap(QPixmap(aLabelIcon));
+    aLayout->addWidget(myLabel);
+
+    std::string aToolstr = theData->widgetTooltip();
+    if (!aToolstr.empty()) {
+      myLabel->setToolTip(QString::fromStdString(aToolstr));
+    }
+
+    myCombo = new QComboBox(this);
+    aLayout->addWidget(myCombo, 1);
+    myCombo->addItems(aList);
+
+    connect(myCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
+  }
 }
 
 ModuleBase_WidgetChoice::~ModuleBase_WidgetChoice()
@@ -55,7 +106,10 @@ bool ModuleBase_WidgetChoice::storeValueCustom() const
   DataPtr aData = myFeature->data();
   std::shared_ptr<ModelAPI_AttributeInteger> aIntAttr = aData->integer(attributeID());
 
-  aIntAttr->setValue(myCombo->currentIndex());
+  if (myCombo)
+    aIntAttr->setValue(myCombo->currentIndex());
+  else
+    aIntAttr->setValue(myButtons->checkedId());
   updateObject(myFeature);
   return true;
 }
@@ -65,22 +119,39 @@ bool ModuleBase_WidgetChoice::restoreValueCustom()
   DataPtr aData = myFeature->data();
   std::shared_ptr<ModelAPI_AttributeInteger> aIntAttr = aData->integer(attributeID());
 
-  bool isBlocked = myCombo->blockSignals(true);
-  myCombo->setCurrentIndex(aIntAttr->value());
-  myCombo->blockSignals(isBlocked);
+  if (aIntAttr->value() != -1) {
+    if (myCombo) {
+      bool isBlocked = myCombo->blockSignals(true);
+      myCombo->setCurrentIndex(aIntAttr->value());
+      myCombo->blockSignals(isBlocked);
+    } else {
+      bool isBlocked = myButtons->blockSignals(true);
+      myButtons->button(aIntAttr->value())->setChecked(true);
+      myButtons->blockSignals(isBlocked);
+    }
+  }
   return true;
 }
 
 bool ModuleBase_WidgetChoice::focusTo()
 {
-  myCombo->setFocus();
+  if (myCombo)
+    myCombo->setFocus();
+  else
+    myButtons->button(0)->setFocus();
   return true;
 }
 
 QList<QWidget*> ModuleBase_WidgetChoice::getControls() const
 {
   QList<QWidget*> aControls;
-  aControls.append(myCombo);
+  if (myCombo)
+    aControls.append(myCombo);
+  //else {
+  //  //foreach(QAbstractButton* aBtn, myButtons->buttons())
+  //  //if (myButtons->checkedId() != -1)
+  //  //  aControls.append(myButtons->button(myButtons->checkedId()));
+  //}
   return aControls;
 }
 
index 72f6df4cd2e15eebbe100559cd7b8e4d6f7ba0d8..8e25ee1f935cee0b94ea01007976b923b3105328 100644 (file)
@@ -13,6 +13,7 @@
 class QWidget;
 class QLabel;
 class QComboBox;
+class QButtonGroup;
 
 /**
 * \ingroup GUI
@@ -25,6 +26,12 @@ class QComboBox;
 *     string_list="Cut Fuse Common"
 *   />
 * \endcode
+* Aditionally can be used: 
+* A key "widget_type". It can have values "combobox" or "radiobuttons".
+* By default it uses "combobox".
+* A key "buttons_dir" which is applicable only for "radiobuttons" mode.
+* It defines direction of radiobuttons layout. it can be "vertical" or "horizontal"
+* Default value is "vertical"
 */
 class MODULEBASE_EXPORT ModuleBase_WidgetChoice : public ModuleBase_ModelWidget
 {
@@ -62,6 +69,7 @@ private:
 
   /// The control
   QComboBox* myCombo;
+  QButtonGroup* myButtons;
 };
 
 #endif
index d51f45805992be503d90a6acff9363eefbbb9b2a..e05a1ecf4c9451e54a868055ef081c6464662a64 100644 (file)
@@ -45,10 +45,10 @@ class ExpressionEditor: public QPlainTextEdit
   /// Returns placeholder list
   QString placeHolderText() const;
 
-  // Returns true if the current value is modified by has not been applyed yet
+  /// Returns true if the current value is modified by has not been applyed yet
   bool isModified() const;
 
-  // Clears modified state
+  /// Clears modified state
   void clearModified();
 
  public slots:
index ba6a4e019f8506ab16a7ad734e30ffb142ae478f..b6f029fb088b9eda8c124d32a8c4617e4283b874 100644 (file)
@@ -103,7 +103,10 @@ protected:
   QString mySelectedFilter;
 
   /// A title of open file dialog box
-  enum { WFS_OPEN, WFS_SAVE } myType;
+  enum {
+    WFS_OPEN, ///< open file
+    WFS_SAVE ///< save file
+  } myType; ///< type of dialog
 
   /// Default path
   QString myDefaultPath;
index 02c1d6613fb44999865d3ad03d008cb5da622780..b92d5863f3a3d71ac9ac852bf6afcbe7a8b0bce9 100644 (file)
@@ -7,6 +7,7 @@
 #include <ModuleBase_WidgetIntValue.h>
 #include <ModuleBase_ParamSpinBox.h>
 #include <ModuleBase_Tools.h>
+#include <ModuleBase_IntSpinBox.h>
 
 #include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_Data.h>
@@ -22,7 +23,6 @@
 #include <QLabel>
 #include <QEvent>
 #include <QTimer>
-#include <QSpinBox>
 
 #include <math.h>
 
@@ -48,7 +48,7 @@ ModuleBase_WidgetIntValue::ModuleBase_WidgetIntValue(QWidget* theParent,
   if (!aLabelIcon.isEmpty())
     myLabel->setPixmap(QPixmap(aLabelIcon));
 
-  mySpinBox = new QSpinBox(this);
+  mySpinBox = new ModuleBase_IntSpinBox(this);
   QString anObjName = QString::fromStdString(attributeID());
   mySpinBox->setObjectName(anObjName);
 
@@ -139,3 +139,14 @@ QList<QWidget*> ModuleBase_WidgetIntValue::getControls() const
   aList.append(mySpinBox);
   return aList;
 }
+
+bool ModuleBase_WidgetIntValue::processEnter()
+{
+  bool isModified = mySpinBox->isModified();
+  if (isModified) {
+    emit valuesChanged();
+    mySpinBox->clearModified();
+    mySpinBox->selectAll();
+  }
+  return isModified;
+}
index 8fd1ef5d8ff01d2e35b8778a49e908a9292ec24a..ffc52d9f97271631e8f054b6860a69cc1f292c12 100644 (file)
 #include "ModuleBase.h"
 #include "ModuleBase_ModelWidget.h"
 
+class ModuleBase_IntSpinBox;
 class Config_WidgetAPI;
 class QWidget;
 class QLabel;
 class QTimer;
-class QSpinBox;
 
 /**
 * \ingroup GUI
@@ -41,6 +41,9 @@ Q_OBJECT
   /// \return a control list
   virtual QList<QWidget*> getControls() const;
 
+  /// Returns true if the event is processed.
+  virtual bool processEnter();
+
 protected:
   /// Saves the internal parameters to the given feature
   /// \return True in success
@@ -59,7 +62,7 @@ protected:
   QLabel* myLabel;
 
   /// Input value control
-  QSpinBox* mySpinBox;
+  ModuleBase_IntSpinBox* mySpinBox;
 };
 
 #endif
index d3a9b8a09d74e883d3b8f1c25d360e6f8be40fd1..d8df98aa3cb815bba77ee99f2ac008c45575a230 100755 (executable)
@@ -29,7 +29,6 @@ class QWidget;
 class QListWidget;
 class QComboBox;
 class ModuleBase_IWorkshop;
-class GeomValidators_ShapeType;
 class QAction;
 
 
index 6e1f9434926303756fe6faeebd26d828c125a415..99edfb890e390b33024d5a85b05baefa0aa2ed43 100755 (executable)
@@ -8,11 +8,10 @@
 
 #include <ModuleBase_ISelection.h>
 #include <ModuleBase_IWorkshop.h>
+#include <ModuleBase_Tools.h>
 
 #include <ModelAPI_ResultConstruction.h>
 
-#include <GeomValidators_Tools.h>
-
 #include <TopoDS_Iterator.hxx>
 
 ModuleBase_WidgetSelector::ModuleBase_WidgetSelector(QWidget* theParent,
@@ -90,7 +89,7 @@ bool ModuleBase_WidgetSelector::acceptSubShape(const GeomShapePtr& theShape,
     // for compounds check sub-shapes: it may be compound of needed type:
     // Booleans may produce compounds of Solids
     if (aShapeType == TopAbs_COMPOUND) {
-      aShapeType = GeomValidators_Tools::getCompoundSubType(aTopoShape);
+      aShapeType = ModuleBase_Tools::getCompoundSubType(aTopoShape);
     }
   }
 
index 1e60ec4049cb8c90ed12ac61673872be54419485..47fc4b44c12474b84c49673fab4988121f6ac93b 100644 (file)
@@ -18,7 +18,6 @@
 #include <Events_Message.h>
 #include <GeomAPI_Interface.h>
 #include <GeomAPI_Shape.h>
-#include <GeomValidators_Tools.h>
 
 #include <ModelAPI_AttributeReference.h>
 #include <ModelAPI_Data.h>
@@ -141,7 +140,7 @@ QList<ModuleBase_ViewerPrs> ModuleBase_WidgetShapeSelector::getAttributeSelectio
     DataPtr aData = myFeature->data();
     AttributePtr anAttribute = myFeature->attribute(attributeID());
 
-    ObjectPtr anObject = GeomValidators_Tools::getObject(anAttribute);
+    ObjectPtr anObject = ModuleBase_Tools::getObject(anAttribute);
     TopoDS_Shape aShape;
     std::shared_ptr<GeomAPI_Shape> aShapePtr = getShape();
     if (aShapePtr.get()) {
@@ -222,7 +221,7 @@ void ModuleBase_WidgetShapeSelector::updateSelectionName()
     isNameUpdated = true;
   }
   if (!isNameUpdated) {
-    ObjectPtr anObject = GeomValidators_Tools::getObject(myFeature->attribute(attributeID()));
+    ObjectPtr anObject = ModuleBase_Tools::getObject(myFeature->attribute(attributeID()));
     if (anObject.get() != NULL) {
       std::string aName = anObject->data()->name();
       myTextLine->setText(QString::fromStdString(aName));
@@ -252,7 +251,7 @@ void ModuleBase_WidgetShapeSelector::storeAttributeValue()
   DataPtr aData = myFeature->data();
   AttributePtr anAttribute = myFeature->attribute(attributeID());
 
-  myObject = GeomValidators_Tools::getObject(anAttribute);
+  myObject = ModuleBase_Tools::getObject(anAttribute);
   myShape = getShape();
   myRefAttribute = AttributePtr();
   myIsObject = false;
index 650d5b1e1848b617e314a13a33cf936c97da0eb5..2c8a10363e630fcade439ae6b895a0545e62459f 100644 (file)
@@ -27,7 +27,6 @@ class QLineEdit;
 class QToolButton;
 class ModuleBase_IWorkshop;
 class ModelAPI_Validator;
-class GeomValidators_ShapeType;
 
 /**
 * \ingroup GUI
index 86ba3a3a7ea64b9cc52fc51fa1cf4475144ab494..03f142b91cc28dcc8a6bd9953a87efb2950a9706 100644 (file)
@@ -68,7 +68,6 @@ SET(PROJECT_LIBRARIES
     ModuleBase
     Config
     GeomAPI
-    GeomValidators
     GeomDataAPI
        SketcherPrs
     ${QT_LIBRARIES}
@@ -106,10 +105,9 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/XGUI
                     ${CMAKE_SOURCE_DIR}/src/FeaturesPlugin
                     ${CMAKE_SOURCE_DIR}/src/PartSetPlugin
                     ${CMAKE_SOURCE_DIR}/src/GeomAPI
-                    ${CMAKE_SOURCE_DIR}/src/GeomValidators
                     ${CMAKE_SOURCE_DIR}/src/AppElements
                     ${CAS_INCLUDE_DIRS}
-                                       ${SUIT_INCLUDE}
+                    ${SUIT_INCLUDE}
 )
 
 ADD_DEFINITIONS(-DPARTSET_EXPORTS ${CAS_DEFINITIONS})
index ab7a858fb6b8f93ce4663815cfee12a14dd66ad1..ab96e5538938eebb6f9024a3ff652baf211002cd 100755 (executable)
@@ -15,8 +15,6 @@
 #include <ModuleBase_IWorkshop.h>
 #include <ModuleBase_IViewer.h>
 
-#include <GeomValidators_Tools.h>
-
 #include <Config_PropManager.h>
 
 #include <AIS_InteractiveContext.hxx>
index 28013c9df0d51abdfbe71b16c82de80c221718d2..b840d7b373f8a7b5d7aceeebcaec3ab49a5517a3 100644 (file)
@@ -149,28 +149,7 @@ bool PartSet_MenuMgr::addViewerMenu(QMenu* theMenu, const QMap<QString, QAction*
         // Find coincident in these coordinates
         ObjectPtr aObj = aPrsList.first().object();
         FeaturePtr aFeature = ModelAPI_Feature::feature(aObj);
-        const std::set<AttributePtr>& aRefsList = aFeature->data()->refsToMe();
-        std::set<AttributePtr>::const_iterator aIt;
-        FeaturePtr aCoincident;
-        for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
-          std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
-          FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
-          if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { 
-            std::shared_ptr<GeomAPI_Pnt2d> a2dPnt = 
-              PartSet_Tools::getPoint(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A());
-            if (a2dPnt.get() && aSelPnt->isEqual(a2dPnt)) { 
-              aCoincident = aConstrFeature;
-              break;
-            } else {
-              a2dPnt = PartSet_Tools::getPoint(aConstrFeature,
-                                               SketchPlugin_ConstraintCoincidence::ENTITY_B());
-              if (a2dPnt.get() && aSelPnt->isEqual(a2dPnt)) { 
-                aCoincident = aConstrFeature;
-                break;
-              }
-            }
-          }
-        }
+        FeaturePtr aCoincident = PartSet_Tools::findFirstCoincidence(aFeature, aSelPnt);
         // If we have coincidence then add Detach menu
         if (aCoincident.get() != NULL) {
           mySelectedFeature = aCoincident;
index 5358b23b1eb8df63241fd900b716c811c3fdc31e..abf7f605ff13e08c8fbe16039be43cbad8414bb1 100755 (executable)
 #include <ModuleBase_Tools.h>
 #include <ModuleBase_OperationFeature.h>
 
-#include <GeomValidators_ShapeType.h>
-#include <GeomValidators_Finite.h>
-#include <GeomValidators_Face.h>
-#include <GeomValidators_ConstructionComposite.h>
-#include <GeomValidators_ZeroOffset.h>
-#include <GeomValidators_BooleanArguments.h>
-#include <GeomValidators_Different.h>
-#include <GeomValidators_PartitionArguments.h>
-
-
 #include <ModelAPI_Object.h>
 #include <ModelAPI_Events.h>
 #include <ModelAPI_Validator.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Session.h>
-#include <GeomValidators_DifferentShapes.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_AttributeString.h>
 
@@ -203,29 +192,7 @@ void PartSet_Module::registerValidators()
   aFactory->registerValidator("PartSet_EqualSelection", new PartSet_EqualSelection);
   aFactory->registerValidator("PartSet_DifferentObjects", new PartSet_DifferentObjectsValidator);
   aFactory->registerValidator("PartSet_CoincidentAttr", new PartSet_CoincidentAttr);
-
-  aFactory->registerValidator("GeomValidators_DifferentShapes", new GeomValidators_DifferentShapes);
-  aFactory->registerValidator("GeomValidators_ShapeType", new GeomValidators_ShapeType);
-  aFactory->registerValidator("GeomValidators_Face", new GeomValidators_Face);
-  aFactory->registerValidator("GeomValidators_Finite", new GeomValidators_Finite);
-
-  aFactory->registerValidator("GeomValidators_ConstructionComposite",
-                              new GeomValidators_ConstructionComposite);
-
-  aFactory->registerValidator("GeomValidators_ZeroOffset",
-                              new GeomValidators_ZeroOffset);
-
-  aFactory->registerValidator("GeomValidators_BooleanArguments",
-                              new GeomValidators_BooleanArguments);
-
-  aFactory->registerValidator("PartSet_SketchEntityValidator",
-                              new PartSet_SketchEntityValidator);
-
-  aFactory->registerValidator("GeomValidators_Different",
-                              new GeomValidators_Different);
-
-  aFactory->registerValidator("GeomValidators_PartitionArguments",
-                              new GeomValidators_PartitionArguments);
+  aFactory->registerValidator("PartSet_SketchEntityValidator", new PartSet_SketchEntityValidator);
 }
 
 void PartSet_Module::registerFilters()
@@ -241,6 +208,8 @@ void PartSet_Module::registerProperties()
                                    PLANE_SIZE);
   Config_PropManager::registerProp("Sketch planes", "planes_thickness", "Thickness",
                                    Config_Prop::Integer, SKETCH_WIDTH);
+  Config_PropManager::registerProp("Sketch planes", "rotate_to_plane", "Rotate to plane when selected",
+    Config_Prop::Boolean, "false");
 }
 
 void PartSet_Module::connectToPropertyPanel(ModuleBase_ModelWidget* theWidget, const bool isToConnect)
index 1a726e21268a9fa4ccd3c95aa670ad92ca8308a5..26f7ace3431a7ec298888c5000ed51013a2e318f 100755 (executable)
@@ -212,7 +212,7 @@ public:
   virtual void grantedOperationIds(ModuleBase_Operation* theOperation, QStringList& theIds) const;
 
   /// Validates the current operation and send the state change to sketch manager
-  /// \thePrevState the previous widget value state
+  /// \param thePreviousState the previous widget value state
   virtual void widgetStateChanged(int thePreviousState);
 
   /// Returns true if the event is processed. It gives the reentrance manager to process the enter.
index 58b5a53f50a2d1d93972b8bb9adc0cc63b19a013..9f52a502d035ba62e4f290737138cb6ee668b189 100755 (executable)
@@ -25,8 +25,6 @@
 #include <ModelAPI_Session.h>
 #include <ModelAPI_ResultCompSolid.h>
 
-#include <GeomValidators_Tools.h>
-
 #include <GeomAPI_IPresentable.h>
 
 #include <StdPrs_WFDeflectionShape.hxx>
index c815b9c0c85afe2d5eed8b7e65ae31aaab450397..b7e7ffd6e5333d5a0bfd5c5aa716f2a04284a99f 100644 (file)
@@ -198,7 +198,7 @@ public:
   void connectToPropertyPanel(ModuleBase_ModelWidget* theWidget, const bool isToConnect);
 
   /// Visualize the operation feature if the previous state is modified value in property panel
-  /// \thePrevState the previous widget value state
+  /// \param thePreviousState the previous widget value state
   void widgetStateChanged(int thePreviousState);
 
 public slots:
index 57df4e0032216effdd48ec53d3f34061b4a73ba9..f9dfb6c0b4bb4b847906bd3207bafa9586045eb6 100755 (executable)
@@ -431,12 +431,44 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShap
 
     Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(theShape), aStart, aEnd);
     GeomAdaptor_Curve aAdaptor(aCurve);
+    std::shared_ptr<GeomAPI_Edge> anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge);
+    anEdge->setImpl(new TopoDS_Shape(theShape));
     if (aAdaptor.GetType() == GeomAbs_Line) {
       // Create line
       aMyFeature = theSketch->addFeature(SketchPlugin_Line::ID());
+      if (!theObject.get()) {
+        // There is no selected result
+        std::shared_ptr<GeomAPI_Pnt> aPnt1 = anEdge->firstPoint();
+        std::shared_ptr<GeomAPI_Pnt> aPnt2 = anEdge->lastPoint();
+        std::shared_ptr<GeomAPI_Pnt2d> aPnt2d1 = convertTo2D(theSketch, aPnt1);
+        std::shared_ptr<GeomAPI_Pnt2d> aPnt2d2 = convertTo2D(theSketch, aPnt2);
+
+        std::shared_ptr<ModelAPI_Data> aData = aMyFeature->data();
+        std::shared_ptr<GeomDataAPI_Point2D> aPoint1 = 
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Line::START_ID()));
+        std::shared_ptr<GeomDataAPI_Point2D> aPoint2 = 
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Line::END_ID()));
+
+        aPoint1->setValue(aPnt2d1);
+        aPoint2->setValue(aPnt2d2);
+
+        // If this is an axis then its name has to be changed correspondently
+        std::string aSuffix = "";
+        bool aXdir = fabs(aPnt1->x() - aPnt2->x()) > Precision::Confusion();
+        bool aYdir = fabs(aPnt1->y() - aPnt2->y()) > Precision::Confusion();
+        bool aZdir = fabs(aPnt1->z() - aPnt2->z()) > Precision::Confusion();
+        if (aXdir && (!aYdir) && (!aZdir))
+          aSuffix = "X";
+        else if ((!aXdir) && aYdir && (!aZdir))
+          aSuffix = "Y";
+        else if ((!aXdir) && (!aYdir) && aZdir)
+          aSuffix = "Z";
+        if (aSuffix.length() > 0)
+          aData->setName("Axis_" + aSuffix);
+        aMyFeature->execute();
+
+      }
     } else if (aAdaptor.GetType() == GeomAbs_Circle) {
-      std::shared_ptr<GeomAPI_Edge> anEdge = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge);
-      anEdge->setImpl(new TopoDS_Shape(theShape));
       if (anEdge->isArc()) {
         // Create arc
         aMyFeature = theSketch->addFeature(SketchPlugin_Arc::ID());
@@ -453,7 +485,10 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShap
         (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
 
       ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
-      if (anAttr && aRes) {
+      if (!aRes.get()) {
+        aRes = aMyFeature->firstResult();
+      }
+      if (anAttr.get() && aRes.get()) {
         std::shared_ptr<GeomAPI_Shape> anEdge(new GeomAPI_Shape);
         anEdge->setImpl(new TopoDS_Shape(theShape));
 
@@ -480,7 +515,29 @@ ResultPtr PartSet_Tools::createFixedObjectByExternal(const TopoDS_Shape& theShap
         (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
 
       ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
-      if (anAttr && aRes) {
+      if (!aRes.get()) {
+        // If the point is selected not from Result object
+        std::shared_ptr<GeomAPI_Shape> aShape = 
+          std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
+        aShape->setImpl(new TopoDS_Shape(theShape));
+
+        std::shared_ptr<GeomAPI_Vertex> aVertex = 
+          std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(aShape));
+        std::shared_ptr<GeomAPI_Pnt> aPnt = aVertex->point();
+
+        std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = convertTo2D(theSketch, aPnt);
+        std::shared_ptr<GeomDataAPI_Point2D> aPoint = 
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(SketchPlugin_Point::COORD_ID()));
+        aPoint->setValue(aPnt2d);
+        if ((aPnt->x() < Precision::Confusion()) && 
+            (aPnt->y() < Precision::Confusion()) &&
+            (aPnt->z() < Precision::Confusion()))
+          aData->setName("Origin");
+
+        aMyFeature->execute();
+        aRes = aMyFeature->firstResult();
+      }
+      if (anAttr.get() && aRes.get()) {
         std::shared_ptr<GeomAPI_Shape> aVert(new GeomAPI_Shape);
         aVert->setImpl(new TopoDS_Shape(theShape));
 
@@ -671,6 +728,35 @@ std::shared_ptr<GeomAPI_Pnt2d> PartSet_Tools::getPoint(std::shared_ptr<ModelAPI_
   return std::shared_ptr<GeomAPI_Pnt2d>();
 }
 
+FeaturePtr PartSet_Tools::findFirstCoincidence(const FeaturePtr& theFeature,
+                                               std::shared_ptr<GeomAPI_Pnt2d> thePoint)
+{
+  FeaturePtr aCoincident;
+
+  const std::set<AttributePtr>& aRefsList = theFeature->data()->refsToMe();
+  std::set<AttributePtr>::const_iterator aIt;
+  for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
+    std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
+    FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
+    if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { 
+      std::shared_ptr<GeomAPI_Pnt2d> a2dPnt = 
+        PartSet_Tools::getPoint(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A());
+      if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { 
+        aCoincident = aConstrFeature;
+        break;
+      } else {
+        a2dPnt = PartSet_Tools::getPoint(aConstrFeature,
+                                          SketchPlugin_ConstraintCoincidence::ENTITY_B());
+        if (a2dPnt.get() && thePoint->isEqual(a2dPnt)) { 
+          aCoincident = aConstrFeature;
+          break;
+        }
+      }
+    }
+  }
+  return aCoincident;
+}
+
 void PartSet_Tools::findCoincidences(FeaturePtr theStartCoin, QList<FeaturePtr>& theList,
                                      std::string theAttr)
 {
index 438135840c698b4fcb7aac3faefe039fa99d38fd..195de10b5f74e976c244a721d36a37559771d38c 100755 (executable)
@@ -199,6 +199,15 @@ class PARTSET_EXPORT PartSet_Tools
   static std::shared_ptr<GeomAPI_Pnt2d> getPoint(std::shared_ptr<ModelAPI_Feature>& theFeature,
                                                  const std::string& theAttribute);
 
+  /**
+  * Gets all references to the feature, take coincidence constraint features, get point 2d attributes
+  * and compare the point value to be equal with the given. Returns the first feature, which has
+  * equal points.
+  * \return the coincidence feature or null
+  */
+  static FeaturePtr findFirstCoincidence(const FeaturePtr& theFeature,
+                                         std::shared_ptr<GeomAPI_Pnt2d> thePoint);
+
   /**
   * Returns list of features connected in a councedence feature point
   * \param theStartCoin the coincidence feature
index 5047a04789c7148aa1ad5df4b6fa59db2aad05bf..9b4aa471db355d9369f04e6c83e2a6526a7b91be 100755 (executable)
@@ -14,7 +14,6 @@
 #include <BRep_Tool.hxx>
 #include <GeomAdaptor_Curve.hxx>
 #include <GeomAbs_CurveType.hxx>
-#include <GeomValidators_Tools.h>
 #include <ModuleBase_ISelection.h>
 #include <ModuleBase_WidgetShapeSelector.h>
 #include <ModuleBase_OperationFeature.h>
index 97c5b1c4e88888c0b5477d8c5b456a4a61ee8f12..ebfe32e00530ccc34534908a0970a667f7910d6b 100644 (file)
@@ -370,8 +370,10 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous
         else {
           if (getPoint2d(aView, aShape, aX, aY))
             setPoint(aX, aY);
+          bool anOrphanPoint = isOrphanPoint(aSelectedFeature, mySketch);
           setConstraintWith(aObject);
-          emit vertexSelected();
+          if (!anOrphanPoint)
+            emit vertexSelected();
           emit focusOutWidget(this);
         }
       }
@@ -385,6 +387,7 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous
         setPoint(aX, aY);
       }
       else {
+        bool anOrphanPoint = isOrphanPoint(aSelectedFeature, mySketch);
         // do not set a coincidence constraint in the attribute if the feature contains a point
         // with the same coordinates. It is important for line creation in order to do not set
         // the same constraints for the same points, oterwise the result line has zero length.
@@ -403,7 +406,8 @@ void PartSet_WidgetPoint2D::onMouseRelease(ModuleBase_IViewWindow* theWnd, QMous
         // points of the line becomes less than the tolerance. Validator of the line returns
         // false, the line will be aborted, but sketch stays valid.
         updateObject(feature());
-        emit vertexSelected();
+        if (!anOrphanPoint)
+          emit vertexSelected();
         emit focusOutWidget(this);
       }
     }
@@ -470,6 +474,10 @@ bool PartSet_WidgetPoint2D::isFeatureContainsPoint(const FeaturePtr& theFeature,
                                                    double theX, double theY)
 {
   bool aPointIsFound = false;
+
+  if (feature()->getKind() != SketchPlugin_Line::ID())
+    return aPointIsFound;
+
   AttributePtr aWidgetAttribute = myFeature->attribute(attributeID());
 
   std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = 
@@ -510,3 +518,43 @@ bool PartSet_WidgetPoint2D::processEnter()
   }
   return isModified;
 }
+
+bool PartSet_WidgetPoint2D::isOrphanPoint(const FeaturePtr& theFeature,
+                                          const CompositeFeaturePtr& theSketch)
+{
+  bool anOrphanPoint = false;
+  if (theFeature.get()) {
+    std::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
+    std::string aFeatureKind = theFeature->getKind();
+    if (aFeatureKind == SketchPlugin_Point::ID())
+      aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                       theFeature->attribute(SketchPlugin_Point::COORD_ID()));
+    else if (aFeatureKind == SketchPlugin_Circle::ID())
+      aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                       theFeature->attribute(SketchPlugin_Circle::CENTER_ID()));
+
+    else if (aFeatureKind == SketchPlugin_Arc::ID())
+      aPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+                                       theFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
+
+    if (aPointAttr.get()) {
+      std::shared_ptr<GeomAPI_Pnt2d> aPoint = aPointAttr->pnt();
+      FeaturePtr aCoincidence = PartSet_Tools::findFirstCoincidence(theFeature, aPoint);
+      anOrphanPoint = true;
+      // if there is at least one concident line to the point, the point is not an orphant
+      if (aCoincidence.get()) {
+        QList<FeaturePtr> aCoinsideLines;
+        PartSet_Tools::findCoincidences(aCoincidence, aCoinsideLines,
+                                        SketchPlugin_ConstraintCoincidence::ENTITY_A());
+        PartSet_Tools::findCoincidences(aCoincidence, aCoinsideLines,
+                                        SketchPlugin_ConstraintCoincidence::ENTITY_B());
+        QList<FeaturePtr>::const_iterator anIt = aCoinsideLines.begin(),
+                                          aLast = aCoinsideLines.end();
+        for (; anIt != aLast && anOrphanPoint; anIt++) {
+          anOrphanPoint = (*anIt)->getKind() != SketchPlugin_Line::ID();
+        }
+      }
+    }
+  }
+  return anOrphanPoint;
+}
index e5e540f57d122b8af428c6427a6033651973aeeb..9a54efa4b14075d1837a79361d29260632fa5008 100755 (executable)
@@ -147,8 +147,15 @@ protected:
    /// \theObject a result object
    void setConstraintWith(const ObjectPtr& theObject);
 
+   /// Returns if the feature is an orphan point, circle or an arc. Returns true if it
+   /// has no a coincident to other lines. In Circle and arc only center points are processed.
+   /// \param theFeature a checked feature
+   /// \param theSketch a sketch
+   /// \return boolean result
+   static bool isOrphanPoint(const FeaturePtr& theFeature, const CompositeFeaturePtr& theSketch);
+
 protected:
-  ModuleBase_IWorkshop* myWorkshop;
+  ModuleBase_IWorkshop* myWorkshop; ///< workshop
 
 private:
 
index 18324da4ddb37eb4173ec5ed36732eddd8888f81..ff3808fb4752027f3d2c75a40c8a0b9548fd7b10 100644 (file)
@@ -48,6 +48,9 @@
 #include <QApplication>
 #include <QVBoxLayout>
 #include <QCheckBox>
+#include <QGroupBox>
+#include <QPushButton>
+#include <QStackedWidget>
 
 
 PartSet_WidgetSketchLabel::PartSet_WidgetSketchLabel(QWidget* theParent,
@@ -58,23 +61,53 @@ PartSet_WidgetSketchLabel::PartSet_WidgetSketchLabel(QWidget* theParent,
 : ModuleBase_WidgetValidated(theParent, theWorkshop, theData, theParentId),
   myPreviewDisplayed(false)
 {
-  myText = QString::fromStdString(theData->getProperty("title"));
-  myLabel = new QLabel("", theParent);
-  myLabel->setWordWrap(true);
-  myTooltip = QString::fromStdString(theData->getProperty("tooltip"));
-  myLabel->setToolTip("");
-  myLabel->setIndent(5);
-
   QVBoxLayout* aLayout = new QVBoxLayout(this);
   ModuleBase_Tools::zeroMargins(aLayout);
-  aLayout->addWidget(myLabel);
 
-  myShowConstraints = new QCheckBox(tr("Show constraints"), this);
-  aLayout->addWidget(myShowConstraints);
+  myStackWidget = new QStackedWidget(this);
+  myStackWidget->setContentsMargins(0,0,0,0);
+  aLayout->addWidget(myStackWidget);
+
+  // Define label for plane selection
+  QWidget* aFirstWgt = new QWidget(this);
+
+  QString aText = QString::fromStdString(theData->getProperty("title"));
+  QLabel* aLabel = new QLabel(aText, aFirstWgt);
+  aLabel->setWordWrap(true);
+  QString aTooltip = QString::fromStdString(theData->getProperty("tooltip"));
+  aLabel->setToolTip(aTooltip);
+  aLabel->setIndent(5);
+
+  aLayout = new QVBoxLayout(aFirstWgt);
+  ModuleBase_Tools::zeroMargins(aLayout);
+  aLayout->addWidget(aLabel);
+
+  myStackWidget->addWidget(aFirstWgt);
+
+  // Define widget for sketch manmagement
+  QWidget* aSecondWgt = new QWidget(this);
+  aLayout = new QVBoxLayout(aSecondWgt);
+  ModuleBase_Tools::zeroMargins(aLayout);
+
+  QGroupBox* aViewBox = new QGroupBox(tr("Sketcher plane"), this);
+  QVBoxLayout* aViewLayout = new QVBoxLayout(aViewBox);
+
+  myViewInverted = new QCheckBox(tr("Reversed"), aViewBox);
+  aViewLayout->addWidget(myViewInverted);
+
+  QPushButton* aSetViewBtn = new QPushButton(QIcon(":icons/plane_view.png"), tr("Set plane view"), aViewBox);
+  connect(aSetViewBtn, SIGNAL(clicked(bool)), this, SLOT(onSetPlaneView()));
+  aViewLayout->addWidget(aSetViewBtn);
 
-  setLayout(aLayout);
+  aLayout->addWidget(aViewBox);
+
+  myShowConstraints = new QCheckBox(tr("Show constraints"), this);
   connect(myShowConstraints, SIGNAL(toggled(bool)), this, SIGNAL(showConstraintToggled(bool)));
   myShowConstraints->setChecked(toShowConstraints);
+  aLayout->addWidget(myShowConstraints);
+
+  myStackWidget->addWidget(aSecondWgt);
+  //setLayout(aLayout);
 }
 
 PartSet_WidgetSketchLabel::~PartSet_WidgetSketchLabel()
@@ -101,7 +134,7 @@ bool PartSet_WidgetSketchLabel::setSelection(QList<ModuleBase_ViewerPrs>& theVal
 QList<QWidget*> PartSet_WidgetSketchLabel::getControls() const
 {
   QList<QWidget*> aResult;
-  aResult << myLabel;
+  aResult << myStackWidget;
   return aResult;
 }
 
@@ -161,13 +194,14 @@ void PartSet_WidgetSketchLabel::updateByPlaneSelected(const ModuleBase_ViewerPrs
 
     // Rotate view if the sketcher plane is selected only from preview planes
     // Preview planes are created only if there is no any shape
-    if (myYZPlane.get()) {
+    bool aRotate = Config_PropManager::boolean("Sketch planes", "rotate_to_plane", "false");
+    if (aRotate)
       myWorkshop->viewer()->setViewProjection(aXYZ.X(), aXYZ.Y(), aXYZ.Z(), aTwist);
-    }
   }
   // 3. Clear text in the label
-  myLabel->setText("");
-  myLabel->setToolTip("");
+  myStackWidget->setCurrentIndex(1);
+  //myLabel->setText("");
+  //myLabel->setToolTip("");
   disconnect(workshop()->selector(), SIGNAL(selectionChanged()), 
               this, SLOT(onSelectionChanged()));
   // 4. deactivate face selection filter
@@ -185,7 +219,7 @@ void PartSet_WidgetSketchLabel::updateByPlaneSelected(const ModuleBase_ViewerPrs
   // 6. Update sketcher actions
   XGUI_ActionsMgr* anActMgr = workshop()->actionsMgr();
   anActMgr->update();
-  //VSV myWorkshop->viewer()->update();
+  myWorkshop->viewer()->update();
 }
 
 std::shared_ptr<GeomAPI_Pln> PartSet_WidgetSketchLabel::plane() const
@@ -196,13 +230,13 @@ std::shared_ptr<GeomAPI_Pln> PartSet_WidgetSketchLabel::plane() const
 
 bool PartSet_WidgetSketchLabel::focusTo()
 {
-  myLabel->setFocus();
+  myStackWidget->setFocus();
   return true;
 }
 
 void PartSet_WidgetSketchLabel::enableFocusProcessing()
 {
-  myLabel->installEventFilter(this);
+  myStackWidget->installEventFilter(this);
 }
 
 void PartSet_WidgetSketchLabel::storeAttributeValue()
@@ -265,10 +299,12 @@ void PartSet_WidgetSketchLabel::activateCustom()
 {
   std::shared_ptr<GeomAPI_Pln> aPlane = plane();
   if (aPlane.get()) {
+    myStackWidget->setCurrentIndex(1);
     activateSelection(true);
     return;
   }
 
+  myStackWidget->setCurrentIndex(0);
   bool aBodyIsVisualized = false;
   XGUI_Displayer* aDisp = workshop()->displayer();
   QObjectPtrList aDisplayed = aDisp->displayedObjects();
@@ -287,8 +323,8 @@ void PartSet_WidgetSketchLabel::activateCustom()
   }
   activateSelection(true);
 
-  myLabel->setText(myText);
-  myLabel->setToolTip(myTooltip);
+  //myLabel->setText(myText);
+  //myLabel->setToolTip(myTooltip);
 
   connect(workshop()->selector(), SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
   activateFilters(true);
@@ -394,6 +430,8 @@ std::shared_ptr<GeomAPI_Dir> PartSet_WidgetSketchLabel::setSketchPlane(const Top
 
   // get plane parameters
   std::shared_ptr<GeomAPI_Pln> aPlane = GeomAlgoAPI_FaceBuilder::plane(aGShape);
+  if (!aPlane.get())
+    return std::shared_ptr<GeomAPI_Dir>();
 
   // set plane parameters to feature
   std::shared_ptr<ModelAPI_Data> aData = feature()->data();
@@ -438,3 +476,16 @@ XGUI_Workshop* PartSet_WidgetSketchLabel::workshop() const
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
   return aConnector->workshop();
 }
+
+
+void PartSet_WidgetSketchLabel::onSetPlaneView()
+{
+  std::shared_ptr<GeomAPI_Pln> aPlane = plane();
+  if (aPlane.get()) {
+    std::shared_ptr<GeomAPI_Dir> aDirection = aPlane->direction();
+    gp_Dir aDir = aDirection->impl<gp_Dir>();
+    if (myViewInverted->isChecked())
+      aDir.Reverse();
+    myWorkshop->viewer()->setViewProjection(aDir.X(), aDir.Y(), aDir.Z(), 0.);
+  }
+}
index 25807c81b0dc1010ece814373eaaf325a66ec03a..709c57efa0f7ce68d0c78c5215b7bd855d3ec6d6 100644 (file)
@@ -22,6 +22,7 @@ class QLabel;
 class XGUI_OperationMgr;
 class XGUI_Workshop;
 class QCheckBox;
+class QStackedWidget;
 
 /// the plane edge width
 #define SKETCH_WIDTH        "4"
@@ -128,6 +129,9 @@ protected:
    /// Slot on change selection
   void onSelectionChanged();
 
+  /// A slot called on set sketch plane view
+  void onSetPlaneView();
+
  private:
    /// Create preview of planes for sketch plane selection
    /// \param theOrigin an origin of the plane
@@ -151,16 +155,15 @@ protected:
   void showPreviewPlanes();
 
 
-  QLabel* myLabel;
-  QString myText;
-  QString myTooltip;
-
   AISObjectPtr myYZPlane;
   AISObjectPtr myXZPlane;
   AISObjectPtr myXYPlane;
   bool myPreviewDisplayed;
 
   QCheckBox* myShowConstraints;
+  QCheckBox* myViewInverted;
+
+  QStackedWidget* myStackWidget;
 };
 
 #endif
index 8361c656e4ada29214b55946577fd15b02731319..13a0a428f642010af71cabe5ad3d5f44370fd615 100644 (file)
@@ -55,6 +55,8 @@
      <file>icons/coincedence.png</file>
      <file>icons/mirror.png</file>
      <file>icons/translate.png</file>
+     <file>icons/translate_32x32.png</file>
+     <file>icons/translate_full_32x32.png</file>
      <file>icons/rotate.png</file>
      <file>icons/exec_state_failed.png</file>
      <file>icons/exec_state_invalid_parameters.png</file>
      <file>icons/angle_up_32x32.png</file>
      <file>icons/angle_up_down.png</file>
      <file>icons/angle_up_down_32x32.png</file>
+     <file>icons/angle_up_full_32x32.png</file>
      <file>icons/dimension_up_down.png</file>
      <file>icons/dimension_up_down_32x32.png</file>
      <file>icons/by_two_points_32x32.png</file>
      <file>icons/cylindrical_face_32x32.png</file>
      <file>icons/dimension_vert_32x32.png</file>
+     <file>icons/bool_cut.png</file>
+     <file>icons/bool_fuse.png</file>
+     <file>icons/bool_common.png</file>
+     <file>icons/plane_view.png</file>
  </qresource>
  </RCC>
diff --git a/src/PartSet/icons/angle_up_full_32x32.png b/src/PartSet/icons/angle_up_full_32x32.png
new file mode 100755 (executable)
index 0000000..fdcde01
Binary files /dev/null and b/src/PartSet/icons/angle_up_full_32x32.png differ
diff --git a/src/PartSet/icons/bool_common.png b/src/PartSet/icons/bool_common.png
new file mode 100644 (file)
index 0000000..99812c5
Binary files /dev/null and b/src/PartSet/icons/bool_common.png differ
diff --git a/src/PartSet/icons/bool_cut.png b/src/PartSet/icons/bool_cut.png
new file mode 100644 (file)
index 0000000..dd494d7
Binary files /dev/null and b/src/PartSet/icons/bool_cut.png differ
diff --git a/src/PartSet/icons/bool_fuse.png b/src/PartSet/icons/bool_fuse.png
new file mode 100644 (file)
index 0000000..5369a50
Binary files /dev/null and b/src/PartSet/icons/bool_fuse.png differ
index c3e77fe2bf7f07f57162b6629a7d319f43372120..05e9b2abd1765659360ecdea1d5a61071bcc7200 100644 (file)
Binary files a/src/PartSet/icons/fillet.png and b/src/PartSet/icons/fillet.png differ
diff --git a/src/PartSet/icons/plane_view.png b/src/PartSet/icons/plane_view.png
new file mode 100644 (file)
index 0000000..431f71a
Binary files /dev/null and b/src/PartSet/icons/plane_view.png differ
diff --git a/src/PartSet/icons/translate_32x32.png b/src/PartSet/icons/translate_32x32.png
new file mode 100755 (executable)
index 0000000..28f064b
Binary files /dev/null and b/src/PartSet/icons/translate_32x32.png differ
diff --git a/src/PartSet/icons/translate_full_32x32.png b/src/PartSet/icons/translate_full_32x32.png
new file mode 100755 (executable)
index 0000000..2f87688
Binary files /dev/null and b/src/PartSet/icons/translate_full_32x32.png differ
index 0c92f1be1b77f1f6bb466e7a0625e92adf1b791e..d53755595a96af63074ba78b340932aa23cc9aee 100644 (file)
@@ -6,7 +6,7 @@ from macros.box.feature      import BoxFeature
 
 
 class PythonFeaturesPlugin(ModelAPI.ModelAPI_Plugin):
-"""Implementation of features plugin"""
+    """Implementation of features plugin"""
 
     def __init__(self):
         """Constructor"""
index 1f581be4aafb04b7d0ae67871f1469c18c08749c..208c408e877dda93247641bb28d9c4ef35608f77 100644 (file)
@@ -37,7 +37,7 @@ class BoxFeature(modeler.Feature):
     return "height"
 
   def getKind(self):
-    """Returns ID of еру ауфегку"""
+    """Returns ID of the feature"""
     return BoxFeature.ID()
 
        
index 508a7404906528307802a8a2607e85752352078c..2ef3a06b4e76bc02489d58bb1f68d325937a45af 100644 (file)
@@ -72,7 +72,6 @@ SET(PROJECT_LIBRARIES
     Config
     GeomAPI
     GeomAlgoAPI
-    GeomValidators
     ModelAPI
     SketcherPrs
     GeomDataAPI
@@ -93,7 +92,6 @@ INCLUDE_DIRECTORIES(
   ../GeomAPI
   ../GeomAlgoAPI
   ../GeomDataAPI
-  ../GeomValidators
   ../SketcherPrs
 )
 
index 22898f95ee77310535f117643b59137e85b2299d..07e9b1a784176ae4117a6335d25f24a17537a07e 100644 (file)
@@ -272,33 +272,33 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID)
         new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
     std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
     if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance) {
-      // issue #855: trying to update only not-updated coordinate if it is possible
-      /*
-      if (abs(myXEndBefore - anEndAttr->x()) < 1.e-10) { // keep Y unchanged
-        double aVy = aCenterAttr->y() - anEndAttr->y();
-        double aVy2 = aVy * aVy;
-        double aR2 = aCircleForArc->radius() * aCircleForArc->radius();
-        if (aVy2 <= aR2) {
-          double aDX = sqrt(aR2 - aVy * aVy);
-          if (anEndAttr->x() > aCenterAttr->x())
-            aProjection->setX(aCenterAttr->x() + aDX);
-          else 
-            aProjection->setX(aCenterAttr->x() - aDX);
-          aProjection->setY(anEndAttr->y());
-        }
-      } else if (abs(myYEndBefore - anEndAttr->y()) < 1.e-10) { // keep X unchanged
-        double aVx = aCenterAttr->x() - anEndAttr->x();
-        double aVx2 = aVx * aVx;
-        double aR2 = aCircleForArc->radius() * aCircleForArc->radius();
-        if (aVx2 <= aR2) {
-          double aDY = sqrt(aR2 - aVx * aVx);
-          if (anEndAttr->y() > aCenterAttr->y())
-            aProjection->setY(aCenterAttr->y() + aDY);
-          else 
-            aProjection->setY(aCenterAttr->y() - aDY);
-          aProjection->setX(anEndAttr->x());
+      if (!isStable()) { // issue #855: trying to update only not-updated coordinate if it is possible
+        if (abs(myXEndBefore - anEndAttr->x()) < 1.e-10) { // keep Y unchanged
+          double aVy = aCenterAttr->y() - anEndAttr->y();
+          double aVy2 = aVy * aVy;
+          double aR2 = aCircleForArc->radius() * aCircleForArc->radius();
+          if (aVy2 <= aR2) {
+            double aDX = sqrt(aR2 - aVy * aVy);
+            if (anEndAttr->x() > aCenterAttr->x())
+              aProjection->setX(aCenterAttr->x() + aDX);
+            else 
+              aProjection->setX(aCenterAttr->x() - aDX);
+            aProjection->setY(anEndAttr->y());
+          }
+        } else if (abs(myYEndBefore - anEndAttr->y()) < 1.e-10) { // keep X unchanged
+          double aVx = aCenterAttr->x() - anEndAttr->x();
+          double aVx2 = aVx * aVx;
+          double aR2 = aCircleForArc->radius() * aCircleForArc->radius();
+          if (aVx2 <= aR2) {
+            double aDY = sqrt(aR2 - aVx * aVx);
+            if (anEndAttr->y() > aCenterAttr->y())
+              aProjection->setY(aCenterAttr->y() + aDY);
+            else 
+              aProjection->setY(aCenterAttr->y() - aDY);
+            aProjection->setX(anEndAttr->x());
+          }
         }
-      }*/
+      }
 
       anEndAttr->setValue(aProjection);
     }
index 25d2daf2af090750355b50942a450f4bafe543ed..f55e46ceb68c9143a12c42a612c2462dac9e7870 100644 (file)
@@ -33,6 +33,7 @@
 #include <Config_PropManager.h>
 #include <Events_Loop.h>
 
+#define _USE_MATH_DEFINES
 #include <math.h>
 
 static const std::string PREVIOUS_VALUE("FilletPreviousRadius");
@@ -57,9 +58,12 @@ void SketchPlugin_ConstraintFillet::initAttributes()
   data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId());
   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
   data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId());
+  // This attribute used to store base edges
+  data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::typeId());
   data()->addAttribute(PREVIOUS_VALUE, ModelAPI_AttributeDouble::typeId());
   // initialize attribute not applicable for user
   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_B());
+  ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SketchPlugin_Constraint::ENTITY_C());
   data()->attribute(PREVIOUS_VALUE)->setInitialized();
   std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(data()->attribute(PREVIOUS_VALUE))->setValue(0.0);
 }
@@ -89,62 +93,18 @@ void SketchPlugin_ConstraintFillet::execute()
       aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
   bool needNewObjects = aRefListOfFillet->size() == 0;
 
-  // Obtain base features
-  AttributePtr anAttrBase = aBaseA->attr();
-  const std::set<AttributePtr>& aRefsList = anAttrBase->owner()->data()->refsToMe();
-  std::set<AttributePtr>::const_iterator aIt;
-  FeaturePtr aCoincident;
-  for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
-    std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
-    FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
-    if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
-      AttributeRefAttrPtr anAttrRefA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-        aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_A()));
-      AttributeRefAttrPtr anAttrRefB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
-        aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_B()));
-      if(anAttrRefA.get() && !anAttrRefA->isObject()) {
-        AttributePtr anAttrA = anAttrRefA->attr();
-        if(anAttrBase == anAttrA) {
-          aCoincident = aConstrFeature;
-          break;
-        }
-      }
-      if(anAttrRefA.get() && !anAttrRefB->isObject()) {
-        AttributePtr anAttrB = anAttrRefB->attr();
-        if(anAttrBase == anAttrB) {
-          aCoincident = aConstrFeature;
-          break;
-        }
-      }
-    }
-  }
+  AttributeRefListPtr aRefListOfBaseLines = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+      aData->attribute(SketchPlugin_Constraint::ENTITY_C()));
 
-  if(!aCoincident.get()) {
-    setError("No coincident edges at selected vertex");
-    return;
-  }
+  // Obtain base features
+  FeaturePtr anOldFeatureA, anOldFeatureB;
+  std::list<ObjectPtr> aNewFeatList = aRefListOfBaseLines->list();
+  std::list<ObjectPtr>::iterator aFeatIt = aNewFeatList.begin();
+  anOldFeatureA = ModelAPI_Feature::feature(*aFeatIt++);
+  anOldFeatureB = ModelAPI_Feature::feature(*aFeatIt);
 
-  std::set<FeaturePtr> aCoinsideLines;
-  SketchPlugin_Tools::findCoincidences(aCoincident,
-                                       SketchPlugin_ConstraintCoincidence::ENTITY_A(),
-                                       aCoinsideLines);
-  SketchPlugin_Tools::findCoincidences(aCoincident,
-                                       SketchPlugin_ConstraintCoincidence::ENTITY_B(),
-                                       aCoinsideLines);
-  if(aCoinsideLines.size() != 2) {
-    setError("At selected vertex should be two coincident lines");
-    return;
-  }
 
-  std::set<FeaturePtr>::iterator aLinesIt = aCoinsideLines.begin();
-  FeaturePtr anOldFeatureA = *aLinesIt;
-  if(!anOldFeatureA) {
-    setError("One of the edges is empty");
-    return;
-  }
-  aLinesIt++;
-  FeaturePtr anOldFeatureB = *aLinesIt;
-  if(!anOldFeatureB) {
+  if(!anOldFeatureA.get() || !anOldFeatureB.get()) {
     setError("One of the edges is empty");
     return;
   }
@@ -153,7 +113,7 @@ void SketchPlugin_ConstraintFillet::execute()
   if (needNewObjects) {
     // Create list of objects composing a fillet
     // copy aFeatureA
-    aNewFeatureA = SketchPlugin_Sketch::addUniqueNamedCopiedFeature(anOldFeatureB, sketch());
+    aNewFeatureA = SketchPlugin_Sketch::addUniqueNamedCopiedFeature(anOldFeatureA, sketch());
     // copy aFeatureB
     aNewFeatureB = SketchPlugin_Sketch::addUniqueNamedCopiedFeature(anOldFeatureB, sketch());
     // create filleting arc (it will be attached to the list later)
@@ -187,6 +147,7 @@ void SketchPlugin_ConstraintFillet::execute()
       aRefListOfFillet->remove(aNewFeatureA);
       aRefListOfFillet->remove(aNewFeatureB);
       aRefListOfFillet->remove(aNewArc);
+      aRefListOfBaseLines->clear();
       return;
     }
     aFeatAttributes[2*i] = aStartAttr;
@@ -276,6 +237,10 @@ void SketchPlugin_ConstraintFillet::execute()
     aRefListOfFillet->append(aNewFeatureB->lastResult());
     aRefListOfFillet->append(aNewArc->lastResult());
 
+    // attach base lines to the list
+    aRefListOfBaseLines->append(anOldFeatureA);
+    aRefListOfBaseLines->append(anOldFeatureB);
+
     myProducedFeatures.push_back(aNewFeatureA);
     myProducedFeatures.push_back(aNewFeatureB);
     myProducedFeatures.push_back(aNewArc);
@@ -411,6 +376,11 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
         data()->attribute(SketchPlugin_Constraint::ENTITY_B()));
     aRefListOfFillet->clear();
 
+    // clear the list of base features
+    AttributeRefListPtr aRefListOfBaseLines = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+        data()->attribute(SketchPlugin_Constraint::ENTITY_C()));
+      aRefListOfBaseLines->clear();
+
     // remove all produced objects and constraints
     DocumentPtr aDoc = sketch()->document();
     std::list<FeaturePtr>::iterator aCIt = myProducedFeatures.begin();
@@ -422,6 +392,108 @@ void SketchPlugin_ConstraintFillet::attributeChanged(const std::string& theID)
     for (aCIt = myBaseObjects.begin(); aCIt != myBaseObjects.end(); ++aCIt)
       (*aCIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->setValue(false);
     myBaseObjects.clear();
+
+    AttributeRefAttrPtr aBaseA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+        data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
+    if(!aBaseA->isInitialized() || aBaseA->isObject()) {
+      return;
+    }
+
+    AttributePtr anAttrBase = aBaseA->attr();
+    const std::set<AttributePtr>& aRefsList = anAttrBase->owner()->data()->refsToMe();
+    std::set<AttributePtr>::const_iterator aIt;
+    FeaturePtr aCoincident;
+    for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
+      std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
+      FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
+      if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
+        AttributeRefAttrPtr anAttrRefA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+          aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_A()));
+        AttributeRefAttrPtr anAttrRefB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+          aConstrFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_B()));
+        if(anAttrRefA.get() && !anAttrRefA->isObject()) {
+          AttributePtr anAttrA = anAttrRefA->attr();
+          if(anAttrBase == anAttrA) {
+            aCoincident = aConstrFeature;
+            break;
+          }
+        }
+        if(anAttrRefA.get() && !anAttrRefB->isObject()) {
+          AttributePtr anAttrB = anAttrRefB->attr();
+          if(anAttrBase == anAttrB) {
+            aCoincident = aConstrFeature;
+            break;
+          }
+        }
+      }
+    }
+
+    if(!aCoincident.get()) {
+      setError("No coincident edges at selected vertex");
+      return;
+    }
+
+    std::set<FeaturePtr> aCoinsideLines;
+    SketchPlugin_Tools::findCoincidences(aCoincident,
+                                         SketchPlugin_ConstraintCoincidence::ENTITY_A(),
+                                         aCoinsideLines);
+    SketchPlugin_Tools::findCoincidences(aCoincident,
+                                         SketchPlugin_ConstraintCoincidence::ENTITY_B(),
+                                         aCoinsideLines);
+
+    // Remove auxilary lines
+    if(aCoinsideLines.size() > 2) {
+      std::set<FeaturePtr> aNewLines;
+      for(std::set<FeaturePtr>::iterator anIt = aCoinsideLines.begin(); anIt != aCoinsideLines.end(); ++anIt) {
+        if(!(*anIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value()) {
+          aNewLines.insert(*anIt);
+        }
+      }
+      aCoinsideLines = aNewLines;
+    }
+
+
+    if(aCoinsideLines.size() != 2) {
+      setError("At selected vertex should be two coincident lines");
+      return;
+    }
+
+    FeaturePtr anOldFeatureA, anOldFeatureB;
+    std::set<FeaturePtr>::iterator aLinesIt = aCoinsideLines.begin();
+    anOldFeatureA = *aLinesIt++;
+    anOldFeatureB = *aLinesIt;
+    aRefListOfBaseLines->append(anOldFeatureA);
+    aRefListOfBaseLines->append(anOldFeatureB);
+
+
+    // Set default value equal to 1/3 of the smallest line sharing the point.
+    static const int aNbFeatures = 2;
+    FeaturePtr aFeature[aNbFeatures] = {anOldFeatureA, anOldFeatureB};
+    double aLength = 0;
+
+    double aLengths[aNbFeatures];
+    for (int i = 0; i < aNbFeatures; i++) {
+      std::shared_ptr<GeomAPI_Pnt2d> aStartPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aFeature[i]->attribute(
+        aFeature[i]->getKind() == SketchPlugin_Line::ID() ? SketchPlugin_Line::START_ID() : SketchPlugin_Arc::START_ID()))->pnt();
+      std::shared_ptr<GeomAPI_Pnt2d> anEndPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aFeature[i]->attribute(
+        aFeature[i]->getKind() == SketchPlugin_Line::ID() ? SketchPlugin_Line::END_ID() : SketchPlugin_Arc::END_ID()))->pnt();
+      if(aFeature[i]->getKind() == SketchPlugin_Line::ID()) {
+        aLengths[i] = aStartPnt->distance(anEndPnt);
+      } else {
+        std::shared_ptr<GeomAPI_Pnt2d> anArcCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aFeature[i]->attribute(
+          SketchPlugin_Arc::CENTER_ID()))->pnt();
+        std::shared_ptr<GeomAPI_Dir2d> aStartDir(new GeomAPI_Dir2d(aStartPnt->xy()->decreased(anArcCenter->xy())));
+        std::shared_ptr<GeomAPI_Dir2d> anEndDir(new GeomAPI_Dir2d(anEndPnt->xy()->decreased(anArcCenter->xy())));
+        double aRadius = aStartPnt->distance(anArcCenter);
+        double anAngle = aStartDir->angle(anEndDir);
+        aLengths[i] = aRadius * abs(anAngle);
+      }
+    }
+    aLength = aLengths[0];
+    for(int i = 1; i < aNbFeatures; i++) {
+      if(aLengths[i] < aLength) aLength = aLengths[i];
+    }
+    std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(data()->attribute(SketchPlugin_Constraint::VALUE()))->setValue(aLength / 3.0);
   }
 }
 
index 726ffe4dd5e847feac88b6994b2baf7b182645fc..274f8d64a03c6346e99f83a3999891b88e407775 100755 (executable)
@@ -5,9 +5,11 @@
 // Author:  Artem ZHIDKOV
 
 #include "SketchPlugin_MultiRotation.h"
+#include "SketchPlugin_Tools.h"
 
 #include <GeomDataAPI_Point2D.h>
 #include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeString.h>
 #include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_Data.h>
 #include <ModelAPI_ResultConstruction.h>
 #define PI 3.1415926535897932
 
 SketchPlugin_MultiRotation::SketchPlugin_MultiRotation()
+: myBlockAngle(false)
 {
 }
 
 void SketchPlugin_MultiRotation::initAttributes()
 {
   data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId());
+
+  data()->addAttribute(ANGLE_TYPE(),   ModelAPI_AttributeString::typeId());
   data()->addAttribute(ANGLE_ID(), ModelAPI_AttributeDouble::typeId());
-  data()->addAttribute(NUMBER_OF_COPIES_ID(), ModelAPI_AttributeInteger::typeId());
+  data()->addAttribute(ANGLE_FULL_ID(), ModelAPI_AttributeDouble::typeId());
+  data()->addAttribute(NUMBER_OF_OBJECTS_ID(), ModelAPI_AttributeInteger::typeId());
   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefList::typeId());
   data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId());
   data()->addAttribute(ROTATION_LIST_ID(), ModelAPI_AttributeRefList::typeId());
@@ -50,18 +56,29 @@ void SketchPlugin_MultiRotation::execute()
   }
 
   AttributeRefListPtr aRotationObjectRefs = reflist(ROTATION_LIST_ID());
-  int aNbCopies = integer(NUMBER_OF_COPIES_ID())->value();
+  int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value() - 1;
+  if (aNbCopies <= 0)
+    return;
 
   // Obtain center and angle of rotation
   std::shared_ptr<GeomDataAPI_Point2D> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       attribute(CENTER_ID()));
   if (!aCenter || !aCenter->isInitialized())
     return;
+
+  if (attribute(ANGLE_ID())->isInitialized() && !attribute(ANGLE_FULL_ID())->isInitialized()) {
+    myBlockAngle = true;
+    SketchPlugin_Tools::updateMultiAttribute(attribute(ANGLE_ID()), attribute(ANGLE_FULL_ID()),
+                                             aNbCopies, true);
+    myBlockAngle = false;
+  }
+
   // make a visible points
   SketchPlugin_Sketch::createPoint2DResult(this, sketch(), CENTER_ID(), 0);
 
   double anAngle = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
-      attribute(ANGLE_ID()))->value();
+                                                             attribute(ANGLE_ID()))->value();
+
   // Convert angle to radians
   anAngle *= PI / 180.0;
 
@@ -279,7 +296,10 @@ void SketchPlugin_MultiRotation::attributeChanged(const std::string& theID)
   if (theID == ROTATION_LIST_ID()) {
     AttributeRefListPtr aRotationObjectRefs = reflist(ROTATION_LIST_ID());
     if (aRotationObjectRefs->size() == 0) {
-      int aNbCopies = integer(NUMBER_OF_COPIES_ID())->value();
+      int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value()-1;
+      if (aNbCopies <= 0)
+        return;
+
       // Clear list of objects
       AttributeRefListPtr aRefListOfRotated = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
           data()->attribute(SketchPlugin_Constraint::ENTITY_B()));
@@ -305,4 +325,45 @@ void SketchPlugin_MultiRotation::attributeChanged(const std::string& theID)
         data()->attribute(SketchPlugin_Constraint::ENTITY_B()))->clear();
     }
   }
+  else if (theID == ANGLE_ID() && !myBlockAngle) {
+    int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value() - 1;
+    if (aNbCopies > 0) {
+      myBlockAngle = true;
+      SketchPlugin_Tools::updateMultiAttribute(attribute(ANGLE_ID()), attribute(ANGLE_FULL_ID()),
+                                               aNbCopies, true);
+      myBlockAngle = false;
+      Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+    }
+  }
+  else if (theID == ANGLE_FULL_ID() && !myBlockAngle) {
+    int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value() - 1;
+    if (aNbCopies > 0) {
+      myBlockAngle = true;
+      SketchPlugin_Tools::updateMultiAttribute(attribute(ANGLE_FULL_ID()), attribute(ANGLE_ID()),
+                                               aNbCopies, false);
+      myBlockAngle = false;
+      Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+    }
+  }
+  else if (theID == NUMBER_OF_OBJECTS_ID()) {
+    if (attribute(NUMBER_OF_OBJECTS_ID())->isInitialized() &&
+        attribute(ANGLE_ID())->isInitialized() &&
+        attribute(ANGLE_TYPE())->isInitialized()) {
+      AttributeStringPtr aMethodTypeAttr = string(ANGLE_TYPE());
+      std::string aMethodType = aMethodTypeAttr->value();
+      int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value() - 1;
+      if (aNbCopies > 0) {
+        myBlockAngle = true;
+        if (aMethodType == "SingleAngle")
+          SketchPlugin_Tools::updateMultiAttribute(attribute(ANGLE_ID()), attribute(ANGLE_FULL_ID()),
+                                                   aNbCopies, true);
+        else {
+          SketchPlugin_Tools::updateMultiAttribute(attribute(ANGLE_FULL_ID()), attribute(ANGLE_ID()),
+                                                   aNbCopies, false);
+        }
+        myBlockAngle = false;
+        Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+      }
+    }
+  }
 }
index 245ffb980bc37de56e07cd4483de659950a771d1..416f477b14ef26bfe20fb94fbb89ad319e53dbd5 100644 (file)
  *  SketchPlugin_Constraint::ENTITY_A() for initial list of objects and
  *  SketchPlugin_Constraint::ENTITY_B() for the list of created objects
  *
- *  The list of created objects contains a number of copies of each object given in
- *  the NUMBER_OF_COPIES_ID() attribute plus 1 (the initial objects are stored into this
- *  attribute too). At the start of the list, there are collected N copies
- *  of first object from initial list, then N copies of second object etc.
+ *  The list of created objects contains initial and copied objects of each object given. The
+ *  number copies is the NUMBER_OF_OBJECTS_ID() minus 1. At the start of the list, there are
+ * collected N copies of first object from initial list, then N copies of second object etc.
  */
 class SketchPlugin_MultiRotation : public SketchPlugin_ConstraintBase
 {
@@ -53,17 +52,31 @@ class SketchPlugin_MultiRotation : public SketchPlugin_ConstraintBase
     static const std::string MY_CENTER_ID("MultiRotationCenter");
     return MY_CENTER_ID;
   }
+  /// attribute name for first point
+  inline static const std::string& ANGLE_TYPE()
+  {
+    static const std::string ANGLE_TYPE_ATTR("AngleType");
+    return ANGLE_TYPE_ATTR;
+  }
+
   /// End point of translation
   inline static const std::string& ANGLE_ID()
   {
     static const std::string MY_ANGLE_ID("MultiRotationAngle");
     return MY_ANGLE_ID;
   }
-  /// Number of translated objects
-  inline static const std::string& NUMBER_OF_COPIES_ID()
+  /// End point of translation
+  inline static const std::string& ANGLE_FULL_ID()
+  {
+    static const std::string MY_ANGLE_FULL_ID("MultiRotationFullAngle");
+    return MY_ANGLE_FULL_ID;
+  }
+
+  /// Total number of objects, initial and translated objects
+  inline static const std::string& NUMBER_OF_OBJECTS_ID()
   {
-    static const std::string MY_NUMBER_OF_COPIES_ID("MultiRotationCopies");
-    return MY_NUMBER_OF_COPIES_ID;
+    static const std::string MY_NUMBER_OF_OBJECTS_ID("MultiRotationObjects");
+    return MY_NUMBER_OF_OBJECTS_ID;
   }
 
   /// \brief Creates a new part document if needed
@@ -86,6 +99,11 @@ private:
   ObjectPtr copyFeature(ObjectPtr theObject);
   void rotateFeature(ObjectPtr theInitial, ObjectPtr theTarget,
                      double theCenterX, double theCenterY, double theAngle);
+
+  bool updateFullAngleValue();
+
+private:
+  bool myBlockAngle; /// a boolean state to avoid recusive angle change in attributeChanged
 };
 
 #endif
index 3e6a702b6ae1ee350584a72fbaf2997206785781..c94ae2dca77d3b18156a408b641293167339aa0b 100755 (executable)
@@ -5,6 +5,7 @@
 // Author:  Artem ZHIDKOV
 
 #include "SketchPlugin_MultiTranslation.h"
+#include "SketchPlugin_Tools.h"
 
 #include <GeomAPI_XY.h>
 #include <GeomDataAPI_Point2D.h>
@@ -13,6 +14,7 @@
 #include <ModelAPI_Data.h>
 #include <ModelAPI_ResultConstruction.h>
 #include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_AttributeString.h>
 #include <ModelAPI_Events.h>
 #include <ModelAPI_Session.h>
 #include <ModelAPI_Validator.h>
 #include <SketcherPrs_Factory.h>
 
 SketchPlugin_MultiTranslation::SketchPlugin_MultiTranslation()
+: myBlockValue(false)
 {
 }
 
 void SketchPlugin_MultiTranslation::initAttributes()
 {
+  data()->addAttribute(VALUE_TYPE(),   ModelAPI_AttributeString::typeId());
+
   data()->addAttribute(START_POINT_ID(), GeomDataAPI_Point2D::typeId());
+  data()->addAttribute(START_FULL_POINT_ID(), GeomDataAPI_Point2D::typeId());
   data()->addAttribute(END_POINT_ID(), GeomDataAPI_Point2D::typeId());
-  data()->addAttribute(NUMBER_OF_COPIES_ID(), ModelAPI_AttributeInteger::typeId());
+  data()->addAttribute(END_FULL_POINT_ID(), GeomDataAPI_Point2D::typeId());
+  data()->addAttribute(NUMBER_OF_OBJECTS_ID(), ModelAPI_AttributeInteger::typeId());
   data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefList::typeId());
   data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId());
   data()->addAttribute(TRANSLATION_LIST_ID(), ModelAPI_AttributeRefList::typeId());
@@ -44,7 +51,9 @@ void SketchPlugin_MultiTranslation::execute()
   }
 
   AttributeRefListPtr aTranslationObjectRefs = reflist(TRANSLATION_LIST_ID());
-  int aNbCopies = integer(NUMBER_OF_COPIES_ID())->value();
+  int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value()-1;
+  if (aNbCopies <= 0)
+    return;
 
   // Calculate shift vector
   std::shared_ptr<GeomDataAPI_Point2D> aStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
@@ -54,9 +63,23 @@ void SketchPlugin_MultiTranslation::execute()
   if (!aStart || !aEnd || !aStart->isInitialized() || !aEnd->isInitialized())
     return;
 
+  if (attribute(END_POINT_ID())->isInitialized() && !attribute(END_FULL_POINT_ID())->isInitialized()) {
+    myBlockValue = true;
+    SketchPlugin_Tools::updateMultiAttribute(attribute(START_POINT_ID()), attribute(END_POINT_ID()),
+                                             attribute(END_FULL_POINT_ID()), aNbCopies, true);
+    myBlockValue = false;
+  }
+
+
   // make a visible points
   SketchPlugin_Sketch::createPoint2DResult(this, sketch(), START_POINT_ID(), 0);
-  SketchPlugin_Sketch::createPoint2DResult(this, sketch(), END_POINT_ID(), 1);
+
+  std::string aSecondPointAttributeID = END_POINT_ID();
+  AttributeStringPtr aMethodTypeAttr = string(VALUE_TYPE());
+  std::string aMethodType = aMethodTypeAttr->value();
+  if (aMethodType != "SingleValue")
+    aSecondPointAttributeID = END_FULL_POINT_ID();
+  SketchPlugin_Sketch::createPoint2DResult(this, sketch(), aSecondPointAttributeID, 1);
 
   std::shared_ptr<GeomAPI_XY> aShiftVec(new GeomAPI_XY(aEnd->x() - aStart->x(), aEnd->y() - aStart->y()));
 
@@ -222,7 +245,9 @@ void SketchPlugin_MultiTranslation::attributeChanged(const std::string& theID)
   if (theID == TRANSLATION_LIST_ID()) {
     AttributeRefListPtr aTranslationObjectRefs = reflist(TRANSLATION_LIST_ID());
     if (aTranslationObjectRefs->size() == 0) {
-      int aNbCopies = integer(NUMBER_OF_COPIES_ID())->value();
+      int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value()-1;
+      if (aNbCopies <= 0)
+        return;
       // Clear list of objects
       AttributeRefListPtr aRefListOfTranslated = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
           data()->attribute(SketchPlugin_Constraint::ENTITY_B()));
@@ -248,4 +273,63 @@ void SketchPlugin_MultiTranslation::attributeChanged(const std::string& theID)
         data()->attribute(SketchPlugin_Constraint::ENTITY_B()))->clear();
     }
   }
+  else if (theID == START_POINT_ID() && !myBlockValue) {
+    myBlockValue = true;
+    std::shared_ptr<GeomDataAPI_Point2D> aStartPoint = 
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_POINT_ID()));
+    std::shared_ptr<GeomDataAPI_Point2D> aStartFullPoint = 
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_FULL_POINT_ID()));
+    aStartFullPoint->setValue(aStartPoint->pnt());
+    myBlockValue = false;
+  }
+  else if (theID == START_FULL_POINT_ID() && !myBlockValue) {
+    myBlockValue = true;
+    std::shared_ptr<GeomDataAPI_Point2D> aStartPoint = 
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_POINT_ID()));
+    std::shared_ptr<GeomDataAPI_Point2D> aStartFullPoint = 
+        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_FULL_POINT_ID()));
+    aStartPoint->setValue(aStartFullPoint->pnt());
+    myBlockValue = false;
+  }
+  else if (theID == END_POINT_ID() && !myBlockValue) {
+    int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value() - 1;
+    if (aNbCopies > 0) {
+      myBlockValue = true;
+      SketchPlugin_Tools::updateMultiAttribute(attribute(START_POINT_ID()), attribute(END_POINT_ID()),
+                                               attribute(END_FULL_POINT_ID()), aNbCopies, true);
+      myBlockValue = false;
+      Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+    }
+  }
+  else if (theID == END_FULL_POINT_ID() && !myBlockValue) {
+    int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value() - 1;
+    if (aNbCopies > 0) {
+      myBlockValue = true;
+      SketchPlugin_Tools::updateMultiAttribute(attribute(START_POINT_ID()), attribute(END_FULL_POINT_ID()),
+                                               attribute(END_POINT_ID()), aNbCopies, false);
+      myBlockValue = false;
+      Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+    }
+  }
+  else if (theID == NUMBER_OF_OBJECTS_ID()) {
+    if (attribute(NUMBER_OF_OBJECTS_ID())->isInitialized() &&
+        attribute(END_POINT_ID())->isInitialized() &&
+        attribute(VALUE_TYPE())->isInitialized()) {
+      AttributeStringPtr aMethodTypeAttr = string(VALUE_TYPE());
+      std::string aMethodType = aMethodTypeAttr->value();
+      int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value() - 1;
+      if (aNbCopies > 0) {
+        myBlockValue = true;
+        if (aMethodType == "SingleValue")
+          SketchPlugin_Tools::updateMultiAttribute(attribute(START_POINT_ID()), attribute(END_POINT_ID()),
+                                                   attribute(END_FULL_POINT_ID()), aNbCopies, true);
+        else {
+          SketchPlugin_Tools::updateMultiAttribute(attribute(START_POINT_ID()), attribute(END_FULL_POINT_ID()),
+                                                   attribute(END_POINT_ID()), aNbCopies, false);
+        }
+        myBlockValue = false;
+        Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
+      }
+    }
+  }
 }
index 5bebd18825b6a04e5a4d511c70cc74981417b33e..b9d44214d7f980837841a29d2d67c69928de0600 100644 (file)
  *  SketchPlugin_Constraint::ENTITY_A() for initial list of objects and
  *  SketchPlugin_Constraint::ENTITY_B() for the list of created objects
  *
- *  The list of created objects contains a number of copies of each object given in
- *  the NUMBER_OF_COPIES_ID() attribute plus 1 (the initial objects are stored into this
- *  attribute too). At the start of the list, there are collected N copies
- *  of first object from initial list, then N copies of second object etc.
+ *  The list of created objects contains initial and copied objects of each object given. The
+ *  number copies is the NUMBER_OF_OBJECTS_ID() minus 1. At the start of the list, there are
+ *  collected N copies of first object from initial list, then N copies of second object etc.
  */
 class SketchPlugin_MultiTranslation : public SketchPlugin_ConstraintBase
 {
@@ -47,23 +46,44 @@ class SketchPlugin_MultiTranslation : public SketchPlugin_ConstraintBase
     return MY_TRANSLATION_LIST_ID;
   }
 
+  /// attribute name for first point
+  inline static const std::string& VALUE_TYPE()
+  {
+    static const std::string VALUE_TYPE_ATTR("ValueType");
+    return VALUE_TYPE_ATTR;
+  }
+
   /// Start point of translation
   inline static const std::string& START_POINT_ID()
   {
     static const std::string MY_START_POINT_ID("MultiTranslationStartPoint");
     return MY_START_POINT_ID;
   }
+  /// Start point of translation
+  inline static const std::string& START_FULL_POINT_ID()
+  {
+    static const std::string MY_START_FULL_POINT_ID("MultiTranslationFullStartPoint");
+    return MY_START_FULL_POINT_ID;
+  }
+
   /// End point of translation
   inline static const std::string& END_POINT_ID()
   {
     static const std::string MY_END_POINT_ID("MultiTranslationEndPoint");
     return MY_END_POINT_ID;
   }
-  /// Number of translated objects
-  inline static const std::string& NUMBER_OF_COPIES_ID()
+  /// End point of translation
+  inline static const std::string& END_FULL_POINT_ID()
+  {
+    static const std::string MY_END_FULL_POINT_ID("MultiTranslationFullEndPoint");
+    return MY_END_FULL_POINT_ID;
+  }
+
+  /// Total number of objects, initial and translated objects
+  inline static const std::string& NUMBER_OF_OBJECTS_ID()
   {
-    static const std::string MY_NUMBER_OF_COPIES_ID("MultiTranslationCopies");
-    return MY_NUMBER_OF_COPIES_ID;
+    static const std::string MY_NUMBER_OF_OBJECTS_ID("MultiTranslationObjects");
+    return MY_NUMBER_OF_OBJECTS_ID;
   }
 
   /// \brief Creates a new part document if needed
@@ -84,6 +104,9 @@ class SketchPlugin_MultiTranslation : public SketchPlugin_ConstraintBase
 
 private:
   ObjectPtr copyFeature(ObjectPtr theObject);
+
+private:
+  bool myBlockValue; /// a boolean state to avoid recusive value change in attributeChanged
 };
 
 #endif
index a26ef9aa4d227147f22305412f32d33f381d00c3..b56992b893ccb06b8e398e3c0f64da326096e8fe 100644 (file)
@@ -101,7 +101,7 @@ class SketchPlugin_SketchEntity : public SketchPlugin_Feature, public GeomAPI_IC
     else if (aShapeType == 7) { // otherwise this is a vertex
       // The width value do not have effect on the point presentation.
       // It is defined in order to extend selection area of the object.
-      thePrs->setWidth(13);
+      thePrs->setWidth(17);
     //  thePrs->setPointMarker(1, 1.); // Set point as a '+' symbol
     }
     return isCustomized;
index 297649e623deb03cdd26d518dad8e5788fe2fc3c..a9aa9d90c9227f17193f72ea945b42141ec2fd42 100644 (file)
@@ -9,8 +9,9 @@
 #include <GeomDataAPI_Point.h>
 #include <GeomDataAPI_Point2D.h>
 #include <ModelAPI_AttributeDouble.h>
-#include <SketchPlugin_ConstraintCoincidence.h>
 #include <SketcherPrs_Tools.h>
+#include <SketchPlugin_ConstraintCoincidence.h>
+#include <SketchPlugin_SketchEntity.h>
 
 namespace SketchPlugin_Tools {
 
@@ -60,7 +61,7 @@ void clearExpressions(FeaturePtr theFeature)
   }
 }
 
-std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(FeaturePtr theStartCoin)
+std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(const FeaturePtr theStartCoin)
 {
   std::shared_ptr<GeomAPI_Pnt2d> aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), 
                                                                     SketchPlugin_Constraint::ENTITY_A());
@@ -69,26 +70,29 @@ std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(FeaturePtr theStartCoin)
   return aPnt;
 }
 
-void findCoincidences(FeaturePtr theStartCoin,
-                      std::string theAttr,
+void findCoincidences(const FeaturePtr theStartCoin,
+                      const std::string& theAttr,
                       std::set<FeaturePtr>& theList)
 {
   AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr);
-  if (!aPnt) return;
+  if(!aPnt) {
+    return;
+  }
   FeaturePtr aObj = ModelAPI_Feature::feature(aPnt->object());
-  if (theList.find(aObj) == theList.end()) {
+  if(theList.find(aObj) == theList.end()) {
     std::shared_ptr<GeomAPI_Pnt2d> aOrig = getCoincidencePoint(theStartCoin);
-    if (aOrig.get() == NULL)
+    if(aOrig.get() == NULL) {
       return;
+    }
     theList.insert(aObj);
     const std::set<AttributePtr>& aRefsList = aObj->data()->refsToMe();
     std::set<AttributePtr>::const_iterator aIt;
-    for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
+    for(aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
       std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
       FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
-      if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) { 
+      if(aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
         std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincidencePoint(aConstrFeature);
-        if (aPnt.get() && aOrig->isEqual(aPnt)) {
+        if(aPnt.get() && aOrig->isEqual(aPnt)) {
           findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theList);
           findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(), theList);
         }
@@ -97,4 +101,57 @@ void findCoincidences(FeaturePtr theStartCoin,
   }
 }
 
+void updateMultiAttribute(const AttributePtr& theFirstAngleAttribute,
+                          const AttributePtr& theSecondAngleAttribute,
+                          const int& theValue,
+                          const bool toMultiply)
+{
+  if (theValue == 0 || !theFirstAngleAttribute->isInitialized())
+    return;
+
+  AttributeDoublePtr aDoubleFirstAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
+                                                                theFirstAngleAttribute);
+  double aValue = aDoubleFirstAttr->value();
+
+  AttributeDoublePtr aDoubleSecondAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
+                                                                theSecondAngleAttribute);
+  if (toMultiply)
+    aDoubleSecondAttr->setValue(aValue*theValue);
+  else
+    aDoubleSecondAttr->setValue(aValue/theValue);
+}
+
+void updateMultiAttribute(const AttributePtr& theFirstAttribute,
+                          const AttributePtr& theSecondAttribute,
+                          const AttributePtr& theModifiedAttribute,
+                          const int& theValue,
+                          const bool toMultiply)
+{
+  if (theValue == 0 || !theFirstAttribute->isInitialized()
+                    || !theSecondAttribute->isInitialized())
+    return;
+
+  std::shared_ptr<GeomDataAPI_Point2D> aFirstPoint = 
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theFirstAttribute);
+  std::shared_ptr<GeomDataAPI_Point2D> aSecondPoint = 
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theSecondAttribute);
+  std::shared_ptr<GeomDataAPI_Point2D> aModifiedPoint = 
+          std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theModifiedAttribute);
+
+  if (!aFirstPoint.get() || !aSecondPoint.get() || !aModifiedPoint.get())
+    return;
+
+  if (aFirstPoint->pnt()->isEqual(aSecondPoint->pnt()))
+    aModifiedPoint->setValue(aFirstPoint->pnt());
+  else {
+    double aDx = aSecondPoint->x() - aFirstPoint->x();
+    double aDy = aSecondPoint->y() - aFirstPoint->y();
+
+    double aX  = toMultiply ? aDx * theValue : aDx / theValue;
+    double anY = toMultiply ? aDy * theValue : aDy / theValue;
+
+    aModifiedPoint->setValue(aFirstPoint->x() + aX, aFirstPoint->y() + anY);
+  }
+}
+
 } // namespace SketchPlugin_Tools
index 9123cab7a29d450b0cd8550fd411839574f4ef24..6b242532bb74ce7fdd5e443d9a42336c074f0ccc 100644 (file)
@@ -10,6 +10,7 @@
 #include <GeomAPI_Pnt2d.h>
 
 #include <ModelAPI_Feature.h>
+#include <ModelAPI_Attribute.h>
 
 namespace SketchPlugin_Tools {
 
@@ -18,16 +19,37 @@ void clearExpressions(FeaturePtr theFeature);
 
 /// \return coincidence point
 /// \param[in] theStartCoin coincidence feature
-std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(FeaturePtr theStartCoin);
+std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(const FeaturePtr theStartCoin);
 
 /// Finds lines coincident at point
 /// \param[in] theStartCoin coincidence feature
 /// \param[in] theAttr attribute name
 /// \param[out] theList list of lines
-void findCoincidences(FeaturePtr theStartCoin,
-                      std::string theAttr,
+void findCoincidences(const FeaturePtr theStartCoin,
+                      const std::string& theAttr,
                       std::set<FeaturePtr>& theList);
 
+/// Changes the second attribute value to be multiplied or divided by the given value.
+/// \param theFirstAngleAttribute the source attribute
+/// \param theSecondAngleAttribute the changed attribute
+/// \param theValue a value for modification
+/// \param toMultiply a type of modification
+void updateMultiAttribute(const AttributePtr& theFirstAngleAttribute,
+                          const AttributePtr& theSecondAngleAttribute,
+                          const int& theValue,
+                          const bool toMultiply);
+
+/// Changes the second attribute value to be multiplied or divided by the given value.
+/// \param theFirstAngleAttribute the source attribute
+/// \param theSecondAngleAttribute the changed attribute
+/// \param theValue a value for modification
+/// \param toMultiply a type of modification
+void updateMultiAttribute(const AttributePtr& theFirstAttribute,
+                          const AttributePtr& theSecondAttribute,
+                          const AttributePtr& theModifiedAttribute,
+                          const int& theValue,
+                          const bool toMultiply);
+
 }; // namespace SketchPlugin_Tools
 
 #endif // SKETCHPLUGIN_TOOLS_H_
\ No newline at end of file
index 9c8dd5809a2bc112ab80c535cc17ba3365fec1eb..a432becdaa31f84efa7cf8f0a641362b45d96310 100755 (executable)
@@ -27,8 +27,6 @@
 #include <ModelAPI_AttributeString.h>
 #include <ModelAPI_Session.h>
 
-#include <GeomValidators_ShapeType.h>
-
 #include <GeomDataAPI_Point2D.h>
 
 
@@ -56,7 +54,7 @@ bool SketchPlugin_DistanceAttrValidator::isValid(const AttributePtr& theAttribut
     ObjectPtr anObject = aRefAttr->object();
 
     const ModelAPI_AttributeValidator* aShapeValidator = 
-      dynamic_cast<const GeomValidators_ShapeType*>(aFactory->validator("GeomValidators_ShapeType"));
+      dynamic_cast<const ModelAPI_AttributeValidator*>(aFactory->validator("GeomValidators_ShapeType"));
     std::list<std::string> anArguments;
     anArguments.push_back("circle");
     std::string aCircleError;
@@ -408,10 +406,18 @@ bool SketchPlugin_FilletVertexValidator::isValid(const AttributePtr& theAttribut
   }
 
   AttributeRefAttrPtr aBase = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
-  if (aBase->isObject()) {
+  if(aBase->isObject()) {
     return false;
   }
 
+  // If we alredy have some result then all ok
+  FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+  AttributePtr aBaseLinesAttribute = aFeature->attribute(SketchPlugin_Constraint::ENTITY_C());
+  AttributeRefListPtr aRefListOfBaseLines = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(aBaseLinesAttribute);
+  if(aRefListOfBaseLines->list().size() == 2) {
+    return true;
+  }
+
   AttributePtr anAttrBase = aBase->attr();
   const std::set<AttributePtr>& aRefsList = anAttrBase->owner()->data()->refsToMe();
   std::set<AttributePtr>::const_iterator aIt;
@@ -452,9 +458,45 @@ bool SketchPlugin_FilletVertexValidator::isValid(const AttributePtr& theAttribut
   SketchPlugin_Tools::findCoincidences(aCoincident,
                                        SketchPlugin_ConstraintCoincidence::ENTITY_B(),
                                        aCoinsideLines);
+  if(aCoinsideLines.size() < 2) {
+    return false;
+  }
+
+  // Remove auxilary lines
+  if(aCoinsideLines.size() > 2) {
+    std::set<FeaturePtr> aNewLines;
+    for(std::set<FeaturePtr>::iterator anIt = aCoinsideLines.begin(); anIt != aCoinsideLines.end(); ++anIt) {
+      if(!(*anIt)->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID())->value()) {
+        aNewLines.insert(*anIt);
+      }
+    }
+    aCoinsideLines = aNewLines;
+  }
+
   if(aCoinsideLines.size() != 2) {
     return false;
   }
 
+  // Check that lines not collinear
+  std::set<FeaturePtr>::iterator anIt = aCoinsideLines.begin();
+  FeaturePtr aFirstFeature = *anIt++;
+  FeaturePtr aSecondFeature = *anIt;
+  if(aFirstFeature->getKind() == SketchPlugin_Line::ID() && aSecondFeature->getKind() == SketchPlugin_Line::ID()) {
+    std::string aStartAttr = SketchPlugin_Line::START_ID();
+    std::string anEndAttr = SketchPlugin_Line::END_ID();
+    std::shared_ptr<GeomAPI_Pnt2d> aFirstStartPnt, aFirstEndPnt, aSecondStartPnt, aSecondEndPnt;
+    aFirstStartPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aFirstFeature->attribute(aStartAttr))->pnt();
+    aFirstEndPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aFirstFeature->attribute(anEndAttr))->pnt();
+    aSecondStartPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aSecondFeature->attribute(aStartAttr))->pnt();
+    aSecondEndPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aSecondFeature->attribute(anEndAttr))->pnt();
+    double aCheck1 = abs((aFirstEndPnt->x() - aFirstStartPnt->x()) * (aSecondStartPnt->y() - aFirstStartPnt->y()) -
+      (aSecondStartPnt->x() - aFirstStartPnt->x()) * (aFirstEndPnt->y() - aFirstStartPnt->y()));
+    double aCheck2 = abs((aFirstEndPnt->x() - aFirstStartPnt->x()) * (aSecondEndPnt->y() - aFirstStartPnt->y()) -
+      (aSecondEndPnt->x() - aFirstStartPnt->x()) * (aFirstEndPnt->y() - aFirstStartPnt->y()));
+    if(aCheck1 < 1.e-7 && aCheck2 < 1.e-7) {
+      return false;
+    }
+  }
+
   return true;
 }
index 3891315ef09cb141d9000fe39864c018da3bee43..a1986c159bced41d5679d563f392655c91257338 100644 (file)
             use_external="true">
           <validator id="SketchPlugin_CopyValidator" />
         </sketch_multi_selector>
-        <groupbox title="Direction">
-          <sketch-2dpoint_selector
-              id="MultiTranslationStartPoint"
-              title="Start point"
-              tooltip="Start point of translation"/>
-          <sketch-2dpoint_selector
-              id="MultiTranslationEndPoint"
-              title="End point"
-              tooltip="Final point of translation"/>
-        </groupbox>
-        <integervalue id="MultiTranslationCopies"
-            label="Number of copies"
-            tooltip="Number of copies" 
-            default="1" min="1" use_reset="false">
+        <toolbox id="ValueType">
+          <box id="SingleValue" title="Single value" icon=":icons/translate_32x32.png">
+            <groupbox title="Direction">
+              <sketch-2dpoint_selector
+                  id="MultiTranslationStartPoint"
+                  title="Start point"
+                  tooltip="Start point of translation"/>
+              <sketch-2dpoint_selector
+                  id="MultiTranslationEndPoint"
+                  title="End point"
+                  tooltip="Final point of translation"/>
+            </groupbox>
+          </box>
+          <box id="FullValue" title="Full value" icon=":icons/translate_full_32x32.png">
+            <groupbox title="Direction">
+              <sketch-2dpoint_selector
+                  id="MultiTranslationFullStartPoint"
+                  title="Start point"
+                  tooltip="Start point of translation"/>
+              <sketch-2dpoint_selector
+                  id="MultiTranslationFullEndPoint"
+                  title="End point"
+                  tooltip="Final point of translation"/>
+            </groupbox>
+          </box>
+        </toolbox>
+        <integervalue id="MultiTranslationObjects"
+            label="Total number of objects"
+            tooltip="Total number of objects" 
+            default="2" min="2" use_reset="false">
           <validator id="GeomValidators_Positive"/>
         </integervalue>
       </feature>
             title="Center of rotation"
             tooltip="Center of rotation"
             default="0"/>
-        <point2dangle id="MultiRotationAngle"
+        <toolbox id="AngleType">
+          <box id="SingleAngle" title="Single angle" icon=":icons/angle_up_32x32.png">
+            <point2dangle id="MultiRotationAngle"
                          first_point="MultiRotationCenter"
                          label="Angle"
                          icon=":icons/angle.png"
                          tooltip="Rotation angle"
                          default="90"/>
-        <integervalue id="MultiRotationCopies"
-            label="Number of copies"
-            tooltip="Number of copies" 
-            default="1" min="1" use_reset="false">
+          </box>
+          <box id="FullAngle" title="Full angle" icon=":icons/angle_up_full_32x32.png">
+            <point2dangle id="MultiRotationFullAngle"
+                         first_point="MultiRotationCenter"
+                         label="Full angle"
+                         icon=":icons/angle.png"
+                         tooltip="Rotation angle"/>
+          </box>
+        </toolbox>
+        <integervalue id="MultiRotationObjects"
+            label="Total number of objects"
+            tooltip="Total number of objects" 
+            default="2" min="2" use_reset="false">
           <validator id="GeomValidators_Positive"/>
         </integervalue>
       </feature>
index b1de57dc2be113102af4cd23996fe4b35382a1dd..5be0d2fe596ce718db4c4217312f6c009b6d74f9 100644 (file)
@@ -64,8 +64,8 @@ void SketchSolver_ConstraintMulti::update(ConstraintPtr theConstraint)
   if (!theConstraint || theConstraint == myBaseConstraint) {
     AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
         myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
-    AttributeIntegerPtr aNbCopies = myBaseConstraint->integer(nameNbCopies());
-    if (anInitialRefList->size() != myNumberOfObjects || aNbCopies->value() != myNumberOfCopies) {
+    AttributeIntegerPtr aNbObjects = myBaseConstraint->integer(nameNbObjects());
+    if (anInitialRefList->size() != myNumberOfObjects || aNbObjects->value()-1 != myNumberOfCopies) {
       remove(myBaseConstraint);
       process();
       return;
index 8d30da0e630a580b67fae2a6dcb5e736a9c69693..4786ee430436040987a5dfe405366e9d8eff4892 100644 (file)
@@ -72,8 +72,8 @@ protected:
   virtual void updateLocal() = 0;
 
   /// \brief Returns name of NUMBER_OF_COPIES parameter for corresponding feature
-  virtual const std::string& nameNbCopies() = 0;
-
+  virtual const std::string& nameNbObjects() = 0;
+  
 protected:
   /// \brief Convert absolute coordinates to relative coordinates
   virtual void getRelative(double theAbsX, double theAbsY, double& theRelX, double& theRelY) = 0;
index ed1550d41e10ba1c740b3678f8e4956467aa3d11..7608460c47d37f5bdcb2261f02843b2e92b8d08a 100644 (file)
@@ -40,7 +40,9 @@ void SketchSolver_ConstraintMultiRotation::getAttributes(
   AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
       aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
   myNumberOfObjects = anInitialRefList->size();
-  myNumberOfCopies = (size_t) aData->integer(SketchPlugin_MultiRotation::NUMBER_OF_COPIES_ID())->value();
+  myNumberOfCopies = (size_t) aData->integer(SketchPlugin_MultiRotation::NUMBER_OF_OBJECTS_ID())->value() - 1;
+  if (myNumberOfCopies <= 0)
+    return;
   AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
       myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
   if (!aRefList) {
@@ -205,7 +207,7 @@ void SketchSolver_ConstraintMultiRotation::transformRelative(double& theX, doubl
   theX = aTemp;
 }
 
-const std::string& SketchSolver_ConstraintMultiRotation::nameNbCopies()
+const std::string& SketchSolver_ConstraintMultiRotation::nameNbObjects()
 {
-  return SketchPlugin_MultiRotation::NUMBER_OF_COPIES_ID();
+  return SketchPlugin_MultiRotation::NUMBER_OF_OBJECTS_ID();
 }
index 5206c6b9f0fc74e40d579a39484dd05b1e003fa2..86966e522110d56d67cc83212aa824b9c77779be 100644 (file)
@@ -54,7 +54,7 @@ private:
 
 private:
   /// \brief Returns name of NUMBER_OF_COPIES parameter for corresponding feature
-  virtual const std::string& nameNbCopies();
+  virtual const std::string& nameNbObjects();
 
 private:
   Slvs_hEntity myRotationCenter; ///< ID of center of rotation
index 381c8641b71770392680a17696b53140416e1c85..02b872c6e549527f2bbdd56cb85c4a87707b5e9a 100644 (file)
@@ -46,7 +46,10 @@ void SketchSolver_ConstraintMultiTranslation::getAttributes(
   AttributeRefListPtr anInitialRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
       aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
   myNumberOfObjects = anInitialRefList->size();
-  myNumberOfCopies = (size_t) aData->integer(SketchPlugin_MultiTranslation::NUMBER_OF_COPIES_ID())->value();
+  myNumberOfCopies = (size_t) aData->integer(SketchPlugin_MultiTranslation::NUMBER_OF_OBJECTS_ID())->value() - 1;
+  if (myNumberOfCopies <= 0)
+    return;
+
   AttributeRefListPtr aRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
       myBaseConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
   if (!aRefList) {
@@ -199,7 +202,7 @@ void SketchSolver_ConstraintMultiTranslation::transformRelative(double& theX, do
   theY += myDelta[1];
 }
 
-const std::string& SketchSolver_ConstraintMultiTranslation::nameNbCopies()
+const std::string& SketchSolver_ConstraintMultiTranslation::nameNbObjects()
 {
-  return SketchPlugin_MultiTranslation::NUMBER_OF_COPIES_ID();
+  return SketchPlugin_MultiTranslation::NUMBER_OF_OBJECTS_ID();
 }
index c3188afa30ee70f781da06ce862b3ec148fca708..c9f10147def434dcc90e67d1937686b2e1bcf17b 100644 (file)
@@ -56,7 +56,7 @@ private:
 
 private:
   /// \brief Returns name of NUMBER_OF_COPIES parameter for corresponding feature
-  virtual const std::string& nameNbCopies();
+  virtual const std::string& nameNbObjects();
 
 private:
   Slvs_hEntity myTranslationLine; ///< ID of translation line
index baf7a928f1219450b08d400e38f17aa3f2bc4a3b..ee88f55bc82818ef0b99e6f3c566274440d7446d 100644 (file)
@@ -82,6 +82,8 @@ protected:
     const Handle(Prs3d_Presentation)& thePresentation, const Standard_Integer theMode = 0);
 
   /// Redefinition of virtual function
+  /// \param aSelection selection
+  /// \param aMode compute mode
   Standard_EXPORT virtual void ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
     const Standard_Integer aMode);
 
index 968457ffe19d1e90074e8f6158a4f4b5223ab051..b25a6fb75ab96ed4e140ea528f1a6bbb6a904a68 100644 (file)
@@ -108,8 +108,8 @@ void XGUI_ActionsMgr::update()
       anActiveFeature = aFOperation->feature();
       if(anActiveFeature.get()) {
         setAllEnabled(false);
-        QString aFeatureId = QString::fromStdString(anActiveFeature->getKind());
-        setActionEnabled(aFeatureId, true);
+        //QString aFeatureId = QString::fromStdString(anActiveFeature->getKind());
+        //setActionEnabled(aFeatureId, true);
       }
       setNestedStackEnabled(aFOperation);
     } else {
@@ -306,7 +306,7 @@ void XGUI_ActionsMgr::setNestedStackEnabled(ModuleBase_Operation* theOperation)
     return;
   FeaturePtr aFeature = anOperation->feature();
   QString aFeatureId = QString::fromStdString(aFeature->getKind());
-  setActionEnabled(aFeatureId, true);
+  //setActionEnabled(aFeatureId, true);
   setNestedCommandsEnabled(true, aFeatureId);
 
   setNestedStackEnabled(myOperationMgr->previousOperation(theOperation));
index afb0aba04ebb6ce375f7c87fe9ceb85e4d8a4b61..009da57c60a8bd076f6b23b7bd6e2feb63d10503 100644 (file)
@@ -735,7 +735,7 @@ Qt::ItemFlags XGUI_DataModel::flags(const QModelIndex& theIndex) const
   } else if (aDoc) {
     // A folder under sub-document
     if (aActiveDoc.get() != aDoc)
-      return aDefaultFlag;
+      return aNullFlag;
   }
   return aEditingFlag;
 }
index a3a39a870eb319cfe2c893686865c2036c01eb8d..59e99f4c7ccf2dccdfd54361c3dbc3dd95f0fb8b 100644 (file)
@@ -221,7 +221,7 @@ bool XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS,
     if(anAISIO->Width() > 1) {
       for(int aModeIdx = 0; aModeIdx < myActiveSelectionModes.length(); ++aModeIdx) {
         int aMode = myActiveSelectionModes.value(aModeIdx);
-        double aPrecision = (aMode == getSelectionMode(TopAbs_VERTEX))? 15 : 
+        double aPrecision = (aMode == getSelectionMode(TopAbs_VERTEX))? 20 : 
                                                     (anAISIO->Width() + 2);
         aContext->SetSelectionSensitivity(anAISIO, aMode, aPrecision);
       }
@@ -364,6 +364,10 @@ void XGUI_Displayer::deactivate(ObjectPtr theObject, const bool theUpdateViewer)
 void XGUI_Displayer::deactivateObjects(const QObjectPtrList& theObjList,
                                        const bool theUpdateViewer)
 {
+  //Handle(AIS_InteractiveObject) aTriehedron = getTrihedron();
+  //if (!aTriehedron.IsNull())
+  //  deactivateAIS(aTriehedron);
+
   QObjectPtrList::const_iterator anIt = theObjList.begin(), aLast = theObjList.end();
   for (; anIt != aLast; anIt++) {
     deactivate(*anIt, false);
@@ -438,14 +442,22 @@ void XGUI_Displayer::activateObjects(const QIntList& theModes, const QObjectPtrL
 
   Handle(AIS_InteractiveObject) anAISIO;
   AIS_ListOfInteractive aPrsList;
-  if (theObjList.isEmpty())
-    return;
-  else {
-    foreach(ObjectPtr aObj, theObjList) {
-      if (myResult2AISObjectMap.contains(aObj))
-        aPrsList.Append(myResult2AISObjectMap[aObj]->impl<Handle(AIS_InteractiveObject)>());
-    }
+  //if (aObjList.isEmpty())
+  //  return;
+  //else {
+  foreach(ObjectPtr aObj, theObjList) {
+    if (myResult2AISObjectMap.contains(aObj))
+      aPrsList.Append(myResult2AISObjectMap[aObj]->impl<Handle(AIS_InteractiveObject)>());
   }
+  //}
+
+  // Add trihedron because it has to partisipate in selection
+  Handle(AIS_InteractiveObject) aTrihedron = getTrihedron();
+  if (!aTrihedron.IsNull())
+    aPrsList.Append(aTrihedron);
+
+  if (aPrsList.Extent() == 0)
+    return;
 
   AIS_ListIteratorOfListOfInteractive aLIt(aPrsList);
   bool isActivationChanged = false;
@@ -454,6 +466,10 @@ void XGUI_Displayer::activateObjects(const QIntList& theModes, const QObjectPtrL
     if (activate(anAISIO, myActiveSelectionModes, false))
       isActivationChanged = true;
   }
+  if (!aTrihedron.IsNull()) {
+    foreach(int aMode, myActiveSelectionModes)
+      aContext->SetSelectionSensitivity(aTrihedron, aMode, 8);
+  }
   // VSV It seems that there is no necessity to update viewer on activation
   //if (theUpdateViewer && isActivationChanged)
   //  updateViewer();
@@ -556,7 +572,16 @@ bool XGUI_Displayer::eraseAll(const bool theUpdateViewer)
 
 void XGUI_Displayer::deactivateTrihedron() const
 {
-  Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
+  Handle(AIS_InteractiveObject) aTrihedron = getTrihedron();
+  if (!aTrihedron.IsNull()) {
+    Handle(AIS_InteractiveContext) aContext = AISContext();
+    aContext->Deactivate(aTrihedron);
+  }
+}
+
+Handle(AIS_InteractiveObject) XGUI_Displayer::getTrihedron() const
+{
+  Handle(AIS_InteractiveContext) aContext = AISContext();
   if (!aContext.IsNull()) {
     AIS_ListOfInteractive aList;
     aContext->DisplayedObjects(aList, true);
@@ -564,15 +589,16 @@ void XGUI_Displayer::deactivateTrihedron() const
     for (aIt.Initialize(aList); aIt.More(); aIt.Next()) {
       Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(aIt.Value());
       if (!aTrihedron.IsNull()) {
-        aContext->Deactivate(aTrihedron);
+        return aTrihedron;
       }
     }
   }
+  return Handle(AIS_InteractiveObject)();
 }
 
 void XGUI_Displayer::openLocalContext()
 {
-  Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
+  Handle(AIS_InteractiveContext) aContext = AISContext();
   // Open local context if there is no one
   if (!aContext.IsNull() && !aContext->HasOpenedContext()) {
     // Preserve selected objects
@@ -590,7 +616,7 @@ void XGUI_Displayer::openLocalContext()
 
     //aContext->ClearCurrents();
     aContext->OpenLocalContext();
-    deactivateTrihedron();
+    //deactivateTrihedron();
     //aContext->NotUseDisplayedObjects();
 
     //myUseExternalObjects = false;
@@ -732,7 +758,7 @@ void XGUI_Displayer::activateAIS(const Handle(AIS_InteractiveObject)& theIO,
 
 void XGUI_Displayer::deactivateAIS(const Handle(AIS_InteractiveObject)& theIO, const int theMode) const
 {
-  Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
+  Handle(AIS_InteractiveContext) aContext = AISContext();
   if (!aContext.IsNull()) {
     if (theMode == -1)
       aContext->Deactivate(theIO);
@@ -752,7 +778,7 @@ Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
   if (!aContext.IsNull() && !aContext->HasOpenedContext()) {
     aContext->OpenLocalContext();
-    deactivateTrihedron();
+    //deactivateTrihedron();
     aContext->DefaultDrawer()->VIsoAspect()->SetNumber(0);
     aContext->DefaultDrawer()->UIsoAspect()->SetNumber(0);
   }
@@ -1007,8 +1033,8 @@ bool XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO,
 
   // trihedron AIS check should be after the AIS loading.
   // If it is not loaded, it is steel selectable in the viewer.
-  Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(theIO);
-  if (aTrihedron.IsNull()) {
+  //Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(theIO);
+  //if (aTrihedron.IsNull()) {
       //aContext->Load(anAISIO, -1, true);
       // In order to clear active modes list
     if (theModes.size() == 0) {
@@ -1022,7 +1048,7 @@ bool XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO,
           isActivationChanged = true;
         }
       }
-    }
+    //}
   }
   return isActivationChanged;
 }
index 91129ece67f03f84afbd3061cf923fd09e96a8ac..3739668835a4591ee383e78cc81243bf8ded5d46 100644 (file)
@@ -141,6 +141,7 @@ class XGUI_EXPORT XGUI_Displayer: public QObject
   /// \param isEnabled a boolean value
   bool enableUpdateViewer(const bool isEnabled);
 
+  /// Returns myEnableUpdateViewer flag
   bool isUpdateEnabled() const { return myEnableUpdateViewer; }
 
   /// Updates the viewer
@@ -226,6 +227,9 @@ class XGUI_EXPORT XGUI_Displayer: public QObject
   /// \param theUpdateViewer update viewer flag
   /// \return previously defined color on the object
   QColor setObjectColor(ObjectPtr theObject, const QColor& theColor, bool theUpdateViewer = true);
+
+  /// Returns Trihedron object if it is displayed
+  Handle(AIS_InteractiveObject) getTrihedron() const;
   
   /// Converts shape type (TopAbs_ShapeEnum) to selection mode
   /// \param theShapeType a shape type from TopAbs_ShapeEnum
index 3dccaf732679a81b3b00dcd5e219d0201bb2bb86..6612e32887d3f2ecd7a218e001f20ce54a27b7d1 100644 (file)
@@ -182,6 +182,7 @@ void XGUI_DataTree::onDoubleClick(const QModelIndex& theIndex)
   int aSize = aModel->rowCount(aParent);
   for (int i = 0; i < aSize; i++) {
     update(aModel->index(i, 0, aParent));
+    update(aModel->index(i, 1, aParent));
   }
 }
 
index 22b45c08aca2c5ce8fb78ff846d83f4fffdac55c..b80a51c12ab388b54adfde507b0fe479417e606f 100644 (file)
@@ -25,11 +25,15 @@ class XGUI_ActiveDocLbl: public QLineEdit
 Q_OBJECT
  public:
    /// Constructor
+   /// \param theText a text
    /// \param theParent a parent widget
    XGUI_ActiveDocLbl(const QString& theText, QWidget* theParent );
 
+   /// Sets tree view
+   /// \param theView a view
    void setTreeView(QTreeView* theView);
 
+   /// Returns tree view
    QTreeView* treePalette() const { return myTreeView;}
 
 #if (!defined HAVE_SALOME) && (defined WIN32)
@@ -37,11 +41,14 @@ Q_OBJECT
 #endif
 
 public slots:
+  /// On unselect
   void unselect();
 
 protected:
+  /// On mouse release
   virtual void mouseReleaseEvent( QMouseEvent* e);
 
+  /// Filter event
   bool eventFilter(QObject* theObj, QEvent* theEvent);
 
 private:
index d44c7d1d589f78060a93bb8a1dddd7a12be493d8..57f55e9d9c7a1becebae3622b9248a86c3768726 100755 (executable)
@@ -16,6 +16,9 @@
 #include <ModuleBase_PageBase.h>
 #include <ModuleBase_PageWidget.h>
 
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
 #include <QEvent>
 #include <QFrame>
 #include <QIcon>
@@ -154,12 +157,19 @@ void XGUI_PropertyPanel::activateNextWidget(ModuleBase_ModelWidget* theWidget)
     activateWidget(NULL);
     return;
   }
+  ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators();
+
   QList<ModuleBase_ModelWidget*>::const_iterator anIt = myWidgets.begin(), aLast = myWidgets.end();
   bool isFoundWidget = false;
   activateWindow();
   for (; anIt != aLast; anIt++) {
+    ModuleBase_ModelWidget* aCurrentWidget = *anIt;
     if (isFoundWidget || !theWidget) {
-      if ((*anIt)->focusTo()) {
+
+      if (!aValidators->isCase(aCurrentWidget->feature(), aCurrentWidget->attributeID()))
+        continue; // this attribute is not participated in the current case
+
+      if (aCurrentWidget->focusTo()) {
         return;
       }
     }
index 374ea5efc1e12b50a47af91bddca079ee9d523ba..2d2b8e29ca59a749c29c8bd07fb656bd24c421b0 100644 (file)
@@ -47,6 +47,7 @@ Q_OBJECT
 
   /// Constructor
   /// \param theParent is a parent of the property panel
+  /// \param theMgr operation manager
   XGUI_PropertyPanel(QWidget* theParent, XGUI_OperationMgr* theMgr);
 
   virtual ~XGUI_PropertyPanel();
index edc1136839354ccbd72ab41671ae32acd2e2f885..49b69883083fb7b99c9857aea76db05c680dc0ad 100644 (file)
 #include <ModelAPI_Feature.h>
 
 #include <AIS_InteractiveContext.hxx>
+#include <AIS_Axis.hxx>
+#include <AIS_Point.hxx>
+#include <Geom_Line.hxx>
+#include <BRep_Builder.hxx>
+#include <TopoDS_Edge.hxx>
+#include <Geom_Point.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <Prs3d_DatumAspect.hxx>
 
 #include <TColStd_ListIteratorOfListOfInteger.hxx>
 #include <StdSelect_BRepOwner.hxx>
@@ -120,7 +128,33 @@ void XGUI_Selection::fillPresentation(ModuleBase_ViewerPrs& thePrs,
     TopoDS_Shape aShape = aBRO->Shape().Located (aBRO->Location() * aBRO->Shape().Location());
     if (!aShape.IsNull())
       thePrs.setShape(aShape);
-  }      
+  } else {
+    // Fill by trihedron shapes
+    Handle(AIS_Axis) aAxis = Handle(AIS_Axis)::DownCast(anIO);
+    if (!aAxis.IsNull()) {
+      // an Axis from Trihedron
+      Handle(Geom_Line) aLine = aAxis->Component();
+      Handle(Prs3d_DatumAspect) DA = aAxis->Attributes()->DatumAspect();
+      Handle(Geom_TrimmedCurve) aTLine = new Geom_TrimmedCurve(aLine, 0, DA->FirstAxisLength());
+
+      BRep_Builder aBuilder;      
+      TopoDS_Edge aEdge;
+      aBuilder.MakeEdge(aEdge, aTLine, Precision::Confusion());
+      if (!aEdge.IsNull())
+        thePrs.setShape(aEdge);
+    } else {
+      Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast(anIO);
+      if (!aPoint.IsNull()) {
+        // A point from trihedron
+        Handle(Geom_Point) aPnt = aPoint->Component();
+        BRep_Builder aBuilder;
+        TopoDS_Vertex aVertex;
+        aBuilder.MakeVertex(aVertex, aPnt->Pnt(), Precision::Confusion());
+        if (!aVertex.IsNull())
+          thePrs.setShape(aVertex);
+      }
+    }
+  }
      
   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
   ObjectPtr aFeature = aDisplayer->getObject(anIO);
index b38f5e4f84dfba7647ec1d11af113d320348bd0a..25ed50fd39464097d6644633235e667595e9f337 100755 (executable)
@@ -310,6 +310,10 @@ void XGUI_Workshop::initMenu()
   aCommand->connectTo(this, SLOT(onSave()));
   //aCommand->disable();
 
+  aCommand = aGroup->addFeature("SAVEAS_CMD", tr("Save as..."), tr("Save the document into a file"),
+                                QIcon(":pictures/save.png"), QKeySequence());
+  aCommand->connectTo(this, SLOT(onSaveAs()));
+
   QString aUndoId = "UNDO_CMD";
   aCommand = aGroup->addFeature(aUndoId, tr("Undo"), tr("Undo last command"),
                                 QIcon(":pictures/undo.png"), QKeySequence::Undo);
@@ -328,13 +332,10 @@ void XGUI_Workshop::initMenu()
                  SIGNAL(updateRedoHistory(const QList<ActionInfo>&)),
                  SLOT(onRedo(int)));
 
-  aCommand = aGroup->addFeature("REBUILD_CMD", tr("Rebuild"), tr("Rebuild data objects"),
-    QIcon(":pictures/rebuild.png"), QKeySequence());
-  aCommand->connectTo(this, SLOT(onRebuild()));
+  //aCommand = aGroup->addFeature("REBUILD_CMD", tr("Rebuild"), tr("Rebuild data objects"),
+  //  QIcon(":pictures/rebuild.png"), QKeySequence());
+  //aCommand->connectTo(this, SLOT(onRebuild()));
 
-  aCommand = aGroup->addFeature("SAVEAS_CMD", tr("Save as..."), tr("Save the document into a file"),
-                                QIcon(":pictures/save.png"), QKeySequence());
-  aCommand->connectTo(this, SLOT(onSaveAs()));
   //aCommand->disable();
 
   aCommand = aGroup->addFeature("OPEN_CMD", tr("Open..."), tr("Open a new document"),