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
TestRevolutionSketch.py
TestRevolutionCut.py
TestRevolutionFuse.py
+ TestCompositeFeaturesOnCompSolids.py
TestPartition.py
TestPlacement.py
TestTranslation.py
--- /dev/null
+#=========================================================================
+# 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)
+
<!-- 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>
myShape(new GeomAPI_Shape())
{
switch (myAlgoType) {
- case MakeShape:
- case MakePipe: {
+ case MakeShape: {
myShape->setImpl(new TopoDS_Shape(implPtr<BRepBuilderAPI_MakeShape>()->Shape()));
break;
}
}
}
-//=================================================================================================
-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
{
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);
}
}
/// Algo type enum
enum AlgoType {
MakeShape,
- MakePipe,
BOPAlgoBuilder
};
/// 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;
GeomValidators_Face.h
GeomValidators_Finite.h
GeomValidators_PartitionArguments.h
+ GeomValidators_Plugin.h
GeomValidators_Positive.h
GeomValidators_ShapeType.h
GeomValidators_Tools.h
GeomValidators_Face.cpp
GeomValidators_Finite.cpp
GeomValidators_PartitionArguments.cpp
+ GeomValidators_Plugin.cpp
GeomValidators_Positive.cpp
GeomValidators_ShapeType.cpp
GeomValidators_Tools.cpp
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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
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;
- }
-
}
/// \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
ModuleBase_FilterValidated.h
ModuleBase_IErrorMgr.h
ModuleBase_IModule.h
+ ModuleBase_IntSpinBox.h
ModuleBase_IPrefMgr.h
ModuleBase_IPropertyPanel.h
ModuleBase_ISelection.h
ModuleBase_FilterValidated.cpp
ModuleBase_IErrorMgr.cpp
ModuleBase_IModule.cpp
+ ModuleBase_IntSpinBox.cpp
ModuleBase_IPrefMgr.cpp
ModuleBase_IPropertyPanel.cpp
ModuleBase_ISelection.cpp
GeomAPI
GeomDataAPI
GeomAlgoAPI
- GeomValidators
${QT_LIBRARIES}
${CAS_VIEWER}
${CAS_KERNEL}
${CMAKE_SOURCE_DIR}/src/GeomDataAPI
${CMAKE_SOURCE_DIR}/src/GeomAPI
${CMAKE_SOURCE_DIR}/src/GeomAlgoAPI
- ${CMAKE_SOURCE_DIR}/src/GeomValidators
${SUIT_INCLUDE}
)
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:
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
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
if (aPropertyPanel)
aPropertyPanel->cleanContent();
- myFeature->setStable(true);
+ if (myFeature.get())
+ myFeature->setStable(true);
abortOperation();
stopOperation();
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
/// 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:
#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>
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
+
#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>
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
#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()
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;
}
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;
}
class QWidget;
class QLabel;
class QComboBox;
+class QButtonGroup;
/**
* \ingroup GUI
* 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
{
/// The control
QComboBox* myCombo;
+ QButtonGroup* myButtons;
};
#endif
/// 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:
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;
#include <ModuleBase_WidgetIntValue.h>
#include <ModuleBase_ParamSpinBox.h>
#include <ModuleBase_Tools.h>
+#include <ModuleBase_IntSpinBox.h>
#include <ModelAPI_AttributeInteger.h>
#include <ModelAPI_Data.h>
#include <QLabel>
#include <QEvent>
#include <QTimer>
-#include <QSpinBox>
#include <math.h>
if (!aLabelIcon.isEmpty())
myLabel->setPixmap(QPixmap(aLabelIcon));
- mySpinBox = new QSpinBox(this);
+ mySpinBox = new ModuleBase_IntSpinBox(this);
QString anObjName = QString::fromStdString(attributeID());
mySpinBox->setObjectName(anObjName);
aList.append(mySpinBox);
return aList;
}
+
+bool ModuleBase_WidgetIntValue::processEnter()
+{
+ bool isModified = mySpinBox->isModified();
+ if (isModified) {
+ emit valuesChanged();
+ mySpinBox->clearModified();
+ mySpinBox->selectAll();
+ }
+ return isModified;
+}
#include "ModuleBase.h"
#include "ModuleBase_ModelWidget.h"
+class ModuleBase_IntSpinBox;
class Config_WidgetAPI;
class QWidget;
class QLabel;
class QTimer;
-class QSpinBox;
/**
* \ingroup GUI
/// \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
QLabel* myLabel;
/// Input value control
- QSpinBox* mySpinBox;
+ ModuleBase_IntSpinBox* mySpinBox;
};
#endif
class QListWidget;
class QComboBox;
class ModuleBase_IWorkshop;
-class GeomValidators_ShapeType;
class QAction;
#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,
// 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);
}
}
#include <Events_Message.h>
#include <GeomAPI_Interface.h>
#include <GeomAPI_Shape.h>
-#include <GeomValidators_Tools.h>
#include <ModelAPI_AttributeReference.h>
#include <ModelAPI_Data.h>
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()) {
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));
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;
class QToolButton;
class ModuleBase_IWorkshop;
class ModelAPI_Validator;
-class GeomValidators_ShapeType;
/**
* \ingroup GUI
ModuleBase
Config
GeomAPI
- GeomValidators
GeomDataAPI
SketcherPrs
${QT_LIBRARIES}
${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})
#include <ModuleBase_IWorkshop.h>
#include <ModuleBase_IViewer.h>
-#include <GeomValidators_Tools.h>
-
#include <Config_PropManager.h>
#include <AIS_InteractiveContext.hxx>
// 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;
#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>
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()
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)
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.
#include <ModelAPI_Session.h>
#include <ModelAPI_ResultCompSolid.h>
-#include <GeomValidators_Tools.h>
-
#include <GeomAPI_IPresentable.h>
#include <StdPrs_WFDeflectionShape.hxx>
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:
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());
(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));
(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));
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)
{
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
#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>
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);
}
}
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.
// 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);
}
}
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 =
}
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;
+}
/// \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:
#include <QApplication>
#include <QVBoxLayout>
#include <QCheckBox>
+#include <QGroupBox>
+#include <QPushButton>
+#include <QStackedWidget>
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()
QList<QWidget*> PartSet_WidgetSketchLabel::getControls() const
{
QList<QWidget*> aResult;
- aResult << myLabel;
+ aResult << myStackWidget;
return aResult;
}
// 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
// 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
bool PartSet_WidgetSketchLabel::focusTo()
{
- myLabel->setFocus();
+ myStackWidget->setFocus();
return true;
}
void PartSet_WidgetSketchLabel::enableFocusProcessing()
{
- myLabel->installEventFilter(this);
+ myStackWidget->installEventFilter(this);
}
void PartSet_WidgetSketchLabel::storeAttributeValue()
{
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();
}
activateSelection(true);
- myLabel->setText(myText);
- myLabel->setToolTip(myTooltip);
+ //myLabel->setText(myText);
+ //myLabel->setToolTip(myTooltip);
connect(workshop()->selector(), SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
activateFilters(true);
// 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();
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.);
+ }
+}
class XGUI_OperationMgr;
class XGUI_Workshop;
class QCheckBox;
+class QStackedWidget;
/// the plane edge width
#define SKETCH_WIDTH "4"
/// 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
void showPreviewPlanes();
- QLabel* myLabel;
- QString myText;
- QString myTooltip;
-
AISObjectPtr myYZPlane;
AISObjectPtr myXZPlane;
AISObjectPtr myXYPlane;
bool myPreviewDisplayed;
QCheckBox* myShowConstraints;
+ QCheckBox* myViewInverted;
+
+ QStackedWidget* myStackWidget;
};
#endif
<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>
class PythonFeaturesPlugin(ModelAPI.ModelAPI_Plugin):
-"""Implementation of features plugin"""
+ """Implementation of features plugin"""
def __init__(self):
"""Constructor"""
return "height"
def getKind(self):
- """Returns ID of еру ауфегку"""
+ """Returns ID of the feature"""
return BoxFeature.ID()
Config
GeomAPI
GeomAlgoAPI
- GeomValidators
ModelAPI
SketcherPrs
GeomDataAPI
../GeomAPI
../GeomAlgoAPI
../GeomDataAPI
- ../GeomValidators
../SketcherPrs
)
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);
}
#include <Config_PropManager.h>
#include <Events_Loop.h>
+#define _USE_MATH_DEFINES
#include <math.h>
static const std::string PREVIOUS_VALUE("FilletPreviousRadius");
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);
}
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;
}
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)
aRefListOfFillet->remove(aNewFeatureA);
aRefListOfFillet->remove(aNewFeatureB);
aRefListOfFillet->remove(aNewArc);
+ aRefListOfBaseLines->clear();
return;
}
aFeatAttributes[2*i] = aStartAttr;
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);
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();
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);
}
}
// 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());
}
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;
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()));
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));
+ }
+ }
+ }
}
* 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
{
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
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
// Author: Artem ZHIDKOV
#include "SketchPlugin_MultiTranslation.h"
+#include "SketchPlugin_Tools.h"
#include <GeomAPI_XY.h>
#include <GeomDataAPI_Point2D.h>
#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());
}
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>(
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()));
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()));
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));
+ }
+ }
+ }
}
* 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
{
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
private:
ObjectPtr copyFeature(ObjectPtr theObject);
+
+private:
+ bool myBlockValue; /// a boolean state to avoid recusive value change in attributeChanged
};
#endif
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;
#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 {
}
}
-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());
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);
}
}
}
+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
#include <GeomAPI_Pnt2d.h>
#include <ModelAPI_Feature.h>
+#include <ModelAPI_Attribute.h>
namespace SketchPlugin_Tools {
/// \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
#include <ModelAPI_AttributeString.h>
#include <ModelAPI_Session.h>
-#include <GeomValidators_ShapeType.h>
-
#include <GeomDataAPI_Point2D.h>
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;
}
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;
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;
}
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>
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;
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;
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) {
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();
}
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
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) {
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();
}
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
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);
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 {
return;
FeaturePtr aFeature = anOperation->feature();
QString aFeatureId = QString::fromStdString(aFeature->getKind());
- setActionEnabled(aFeatureId, true);
+ //setActionEnabled(aFeatureId, true);
setNestedCommandsEnabled(true, aFeatureId);
setNestedStackEnabled(myOperationMgr->previousOperation(theOperation));
} else if (aDoc) {
// A folder under sub-document
if (aActiveDoc.get() != aDoc)
- return aDefaultFlag;
+ return aNullFlag;
}
return aEditingFlag;
}
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);
}
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);
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;
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();
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);
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
//aContext->ClearCurrents();
aContext->OpenLocalContext();
- deactivateTrihedron();
+ //deactivateTrihedron();
//aContext->NotUseDisplayedObjects();
//myUseExternalObjects = false;
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);
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);
}
// 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) {
isActivationChanged = true;
}
}
- }
+ //}
}
return isActivationChanged;
}
/// \param isEnabled a boolean value
bool enableUpdateViewer(const bool isEnabled);
+ /// Returns myEnableUpdateViewer flag
bool isUpdateEnabled() const { return myEnableUpdateViewer; }
/// Updates the viewer
/// \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
int aSize = aModel->rowCount(aParent);
for (int i = 0; i < aSize; i++) {
update(aModel->index(i, 0, aParent));
+ update(aModel->index(i, 1, aParent));
}
}
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)
#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:
#include <ModuleBase_PageBase.h>
#include <ModuleBase_PageWidget.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+
#include <QEvent>
#include <QFrame>
#include <QIcon>
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;
}
}
/// Constructor
/// \param theParent is a parent of the property panel
+ /// \param theMgr operation manager
XGUI_PropertyPanel(QWidget* theParent, XGUI_OperationMgr* theMgr);
virtual ~XGUI_PropertyPanel();
#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>
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);
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);
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"),