return myDescription;
}
+bool ModuleBase_IOperation::canBeCommitted() const
+{
+ return true;
+}
+
bool ModuleBase_IOperation::isGranted(ModuleBase_IOperation* /*theOperation*/) const
{
return false;
document()->finishOperation();
emit stopped();
+
+ afterCommitOperation();
}
void ModuleBase_IOperation::setRunning(bool theState)
/// /returns the instance of the description class
ModuleBase_OperationDescription* getDescription() const;
+ /// Verifies whether this operator can be commited.
+ /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled
+ virtual bool canBeCommitted() const;
+
/// Verifies whether this operator can be always started above any already running one
/// \return Returns TRUE if current operation must not be checked for ActiveOperation->IsValid( this )
/// This method must be redefined in derived operation if operation of derived class
virtual void abortOperation() = 0;
/// Virtual method called when operation committed (see commit() method for more description)
virtual void commitOperation() = 0;
+ /// Virtual method called after operation committed (see commit() method for more description)
+ /// it is important that the method is called after the stop() signal is emitted
+ virtual void afterCommitOperation() = 0;
/// Returns pointer to the root document.
boost::shared_ptr<ModelAPI_Document> document() const;
if (myFeature) myFeature->execute();
}
+void ModuleBase_Operation::afterCommitOperation()
+{
+}
+
void ModuleBase_Operation::flushUpdated()
{
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_FEATURE_UPDATED));
virtual void abortOperation();
/// Virtual method called when operation committed (see commit() method for more description)
virtual void commitOperation();
+ /// Virtual method called after operation committed (see commit() method for more description)
+ virtual void afterCommitOperation();
/// Send update message by loop
void flushUpdated();
bool ModuleBase_WidgetPoint2D::storeValue(boost::shared_ptr<ModelAPI_Feature> theFeature)
{
boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
- if (!aData) {
- ObjectPtr anObj = boost::dynamic_pointer_cast<ModelAPI_Object>(theFeature);
- if (anObj) aData = anObj->featureRef()->data();
- }
boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(myFeatureAttributeID));
bool ModuleBase_WidgetPoint2D::restoreValue(boost::shared_ptr<ModelAPI_Feature> theFeature)
{
boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
- if (!aData) {
- ObjectPtr anObj = boost::dynamic_pointer_cast<ModelAPI_Object>(theFeature);
- if (anObj) aData = anObj->featureRef()->data();
- }
boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(myFeatureAttributeID));
#include <PartSet_TestOCC.h>
#include <ModuleBase_Operation.h>
+#include <ModelAPI_Object.h>
#include <XGUI_MainWindow.h>
#include <XGUI_Displayer.h>
#include <XGUI_ViewerProxy.h>
#include <XGUI_ContextMenuMgr.h>
#include <XGUI_PropertyPanel.h>
+#include <XGUI_Tools.h>
#include <Config_PointerMessage.h>
#include <Config_ModuleReader.h>
return;
if (theFeature->getKind() == "Sketch") {
- onLaunchOperation(theFeature->getKind(), theFeature);
- updateCurrentPreview(theFeature->getKind());
+ FeaturePtr aFeature = theFeature;
+ if (XGUI_Tools::isModelObject(aFeature)) {
+ ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature);
+ aFeature = aObject->featureRef();
+ }
+
+ if (aFeature) {
+ onLaunchOperation(aFeature->getKind(), aFeature);
+ updateCurrentPreview(aFeature->getKind());
+ }
}
}
emit setSelection(aSelected);
}
else if (aFeature) {
- emit launchOperation(PartSet_OperationEditLine::Type(), aFeature);
+ restartOperation(PartSet_OperationEditLine::Type(), aFeature);
}
}
}
moveLinePoint(aFeature, aDeltaX, aDeltaY, LINE_ATTR_END);
}
}
- flushUpdated();
sendFeatures();
myCurPoint.setPoint(aPoint);
Events_Loop::loop()->send(aMessage);
}
Events_Loop::loop()->flush(anEvent);
+ flushUpdated();
}
if (theHighlighted.size() == 1) {
boost::shared_ptr<ModelAPI_Feature> aFeature = theHighlighted.front().feature();
if (aFeature)
- emit launchOperation(PartSet_OperationEditLine::Type(), aFeature);
+ restartOperation(PartSet_OperationEditLine::Type(), aFeature);
}
else
myFeatures = theHighlighted;
boost::shared_ptr<ModelAPI_Feature> aFeature = PartSet_Tools::NearestFeature(theEvent->pos(),
theView, feature(), myFeatures);
if (aFeature)
- emit launchOperation(PartSet_OperationEditLine::Type(), aFeature);
+ restartOperation(PartSet_OperationEditLine::Type(), aFeature);
}
}
#include <PartSet_OperationSketchBase.h>
#include <SketchPlugin_Feature.h>
-#include <ModelAPI_Object.h>
#include <V3d_View.hxx>
{
boost::shared_ptr<SketchPlugin_Feature> aFeature =
boost::dynamic_pointer_cast<SketchPlugin_Feature>(theFeature);
- if (!aFeature) { // if it is reference to a object feature
- boost::shared_ptr<ModelAPI_Object> anObj =
- boost::dynamic_pointer_cast<ModelAPI_Object>(theFeature);
- if (anObj)
- aFeature = boost::dynamic_pointer_cast<SketchPlugin_Feature>(anObj->featureRef());
- }
if (!aFeature)
return boost::shared_ptr<GeomAPI_Shape>();
return aFeature->preview();
{
keyReleased(theEvent->key());
}
+
+void PartSet_OperationSketchBase::restartOperation(const std::string& theType,
+ boost::shared_ptr<ModelAPI_Feature> theFeature)
+{
+ emit launchOperation(theType, theFeature);
+}
virtual void keyReleased(std::string theName, QKeyEvent* theEvent);
+ /// Emits a signal about the operation start. This signal has an information about the feature.
+ /// If the provided feature is empty, the current operation feature is used.
+ /// \param theType a type of an operation started
+ /// theFeature the operation argument
+ void restartOperation(const std::string& theType,
+ boost::shared_ptr<ModelAPI_Feature> theFeature = boost::shared_ptr<ModelAPI_Feature>());
+
signals:
/// signal about the request to launch operation
/// theName the operation name
{
}
+bool PartSet_OperationSketchLine::canBeCommitted() const
+{
+ return myPointSelectionMode == SM_DonePoint;
+}
+
bool PartSet_OperationSketchLine::isGranted(ModuleBase_IOperation* theOperation) const
{
return theOperation->getDescription()->operationId().toStdString() == PartSet_OperationSketch::Type();
const std::list<XGUI_ViewerPrs>& theSelected,
const std::list<XGUI_ViewerPrs>& /*theHighlighted*/)
{
+ if (myPointSelectionMode == SM_DonePoint)
+ {
+ // if the point creation is finished, the next mouse release should commit the modification
+ // the next release can happens by double click in the viewer
+ commit();
+ restartOperation(PartSet_OperationSketchLine::Type(), feature());
+ return;
+ }
+
double aX, anY;
bool isFoundPoint = false;
}
}
}
- //if (!isFoundPoint)
- // return;
switch (myPointSelectionMode)
{
case SM_DonePoint:
{
commit();
- emit featureConstructed(feature(), FM_Deactivation);
- emit launchOperation(PartSet_OperationSketchLine::Type(), feature());
+ restartOperation(PartSet_OperationSketchLine::Type(), feature());
}
default:
break;
if (myPointSelectionMode == SM_DonePoint)
{
commit();
- emit featureConstructed(feature(), FM_Deactivation);
- emit launchOperation(PartSet_OperationSketchLine::Type(), boost::shared_ptr<ModelAPI_Feature>());
+ restartOperation(PartSet_OperationSketchLine::Type(), feature());
}
//else
// abort();
if (myPointSelectionMode == SM_DonePoint)
{
commit();
- emit featureConstructed(feature(), FM_Deactivation);
}
else
abort();
emit multiSelectionEnabled(true);
}
+void PartSet_OperationSketchLine::afterCommitOperation()
+{
+ PartSet_OperationSketchBase::afterCommitOperation();
+ emit featureConstructed(feature(), FM_Deactivation);
+}
+
boost::shared_ptr<ModelAPI_Feature> PartSet_OperationSketchLine::createFeature(const bool theFlushMessage)
{
boost::shared_ptr<ModelAPI_Feature> aNewFeature = ModuleBase_Operation::createFeature(false);
case SM_SecondPoint:
aPointArg = LINE_ATTR_END;
break;
+ default:
+ break;
}
+ boost::shared_ptr<ModelAPI_Feature> aSkFeature = feature();
+
boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
(aData->attribute(aPointArg));
/// Destructor
virtual ~PartSet_OperationSketchLine();
- /// Returns that this operator can be started above already running one.
+ /// Verifies whether this operator can be commited.
+ /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled
+ virtual bool canBeCommitted() const;
+
+ /// Returns that this operator can be started above already running one.
/// The runned operation should be the sketch feature modified operation
/// \param theOperation the previous running operation
virtual bool isGranted(ModuleBase_IOperation* theOperation) const;
/// Restore the multi selection state
virtual void stopOperation();
+ /// Virtual method called after operation committed (see commit() method for more description)
+ virtual void afterCommitOperation();
+
/// Creates an operation new feature
/// In addition to the default realization it appends the created line feature to
/// the sketch feature
SketchPlugin_Constraint.h
SketchPlugin_ConstraintCoincidence.h
SketchPlugin_ConstraintDistance.h
- SketchPlugin_ConstraintDiameter.h
+ SketchPlugin_ConstraintLength.h
SketchPlugin_ConstraintParallel.h
SketchPlugin_ConstraintPerpendicular.h
+ SketchPlugin_ConstraintRadius.h
)
SET(PROJECT_SOURCES
SketchPlugin_Arc.cpp
SketchPlugin_ConstraintCoincidence.cpp
SketchPlugin_ConstraintDistance.cpp
- SketchPlugin_ConstraintDiameter.cpp
+ SketchPlugin_ConstraintLength.cpp
SketchPlugin_ConstraintParallel.cpp
SketchPlugin_ConstraintPerpendicular.cpp
+ SketchPlugin_ConstraintRadius.cpp
)
SET(PROJECT_LIBRARIES
+++ /dev/null
-// File: SketchPlugin_ConstraintDiameter.cpp
-// Created: 26 May 2014
-// Author: Artem ZHIDKOV
-
-#include "SketchPlugin_ConstraintDiameter.h"
-
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_Data.h>
-#include <SketchPlugin_Point.h>
-
-SketchPlugin_ConstraintDiameter::SketchPlugin_ConstraintDiameter()
-{
-}
-
-void SketchPlugin_ConstraintDiameter::initAttributes()
-{
- data()->addAttribute(CONSTRAINT_ATTR_VALUE, ModelAPI_AttributeDouble::type());
- data()->addAttribute(CONSTRAINT_ATTR_ENTITY_A, ModelAPI_AttributeRefAttr::type());
-}
-
-void SketchPlugin_ConstraintDiameter::execute()
-{
-}
-
-const boost::shared_ptr<GeomAPI_Shape>& SketchPlugin_ConstraintDiameter::preview()
-{
- /// \todo Preview for diameter constraint
- return getPreview();
-}
-
+++ /dev/null
-// File: SketchPlugin_ConstraintDiameter.h
-// Created: 26 May 2014
-// Author: Artem ZHIDKOV
-
-#ifndef SketchPlugin_ConstraintDiameter_HeaderFile
-#define SketchPlugin_ConstraintDiameter_HeaderFile
-
-#include "SketchPlugin.h"
-#include "SketchPlugin_Constraint.h"
-
-
-/** \class SketchPlugin_ConstraintDiameter
- * \ingroup DataModel
- * \brief Feature for creation of a new constraint which defines a diameter of a circle
- *
- * These constraint has two attributes:
- * CONSTRAINT_ATTR_VALUE (diameter), CONSTRAINT_ATTR_ENTITY_A (a circle)
- */
-class SketchPlugin_ConstraintDiameter: public SketchPlugin_Constraint
-{
-public:
- /// \brief Returns the kind of a feature
- SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
- {static std::string MY_KIND = "SketchConstraintDiameter"; return MY_KIND;}
-
- /// \brief Returns to which group in the document must be added feature
- SKETCHPLUGIN_EXPORT virtual const std::string& getGroup()
- {static std::string MY_GROUP = "Sketch"; return MY_GROUP;}
-
- /// \brief Creates a new part document if needed
- SKETCHPLUGIN_EXPORT virtual void execute();
-
- /// \brief Request for initialization of data model of the feature: adding all attributes
- SKETCHPLUGIN_EXPORT virtual void initAttributes();
-
- /// \brief Returns the sketch preview
- SKETCHPLUGIN_EXPORT virtual const boost::shared_ptr<GeomAPI_Shape>& preview();
-
- /// \brief Use plugin manager for features creation
- SketchPlugin_ConstraintDiameter();
-};
-
-#endif
--- /dev/null
+// File: SketchPlugin_ConstraintLength.cpp
+// Created: 30 May 2014
+// Author: Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintLength.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+
+SketchPlugin_ConstraintLength::SketchPlugin_ConstraintLength()
+{
+}
+
+void SketchPlugin_ConstraintLength::initAttributes()
+{
+ data()->addAttribute(CONSTRAINT_ATTR_VALUE, ModelAPI_AttributeDouble::type());
+ data()->addAttribute(CONSTRAINT_ATTR_ENTITY_A, ModelAPI_AttributeRefAttr::type());
+}
+
+void SketchPlugin_ConstraintLength::execute()
+{
+}
+
+const boost::shared_ptr<GeomAPI_Shape>& SketchPlugin_ConstraintLength::preview()
+{
+ /// \todo Preview for distance constraint
+ return getPreview();
+}
+
--- /dev/null
+// File: SketchPlugin_ConstraintLength.h
+// Created: 30 May 2014
+// Author: Artem ZHIDKOV
+
+#ifndef SketchPlugin_ConstraintLength_HeaderFile
+#define SketchPlugin_ConstraintLength_HeaderFile
+
+#include "SketchPlugin.h"
+#include "SketchPlugin_Constraint.h"
+#include <list>
+
+
+/** \class SketchPlugin_ConstraintLength
+ * \ingroup DataModel
+ * \brief Feature for creation of a new constraint which defines a length of a line segment
+ *
+ * These constraint has two attributes:
+ * CONSTRAINT_ATTR_VALUE (length) and CONSTRAINT_ATTR_ENTITY_A (segment)
+ */
+class SketchPlugin_ConstraintLength: public SketchPlugin_Constraint
+{
+public:
+ /// \brief Returns the kind of a feature
+ SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
+ {static std::string MY_KIND = "SketchConstraintLength"; return MY_KIND;}
+
+ /// \brief Returns to which group in the document must be added feature
+ SKETCHPLUGIN_EXPORT virtual const std::string& getGroup()
+ {static std::string MY_GROUP = "Sketch"; return MY_GROUP;}
+
+ /// \brief Creates a new part document if needed
+ SKETCHPLUGIN_EXPORT virtual void execute();
+
+ /// \brief Request for initialization of data model of the feature: adding all attributes
+ SKETCHPLUGIN_EXPORT virtual void initAttributes();
+
+ /// \brief Returns the sketch preview
+ SKETCHPLUGIN_EXPORT virtual const boost::shared_ptr<GeomAPI_Shape>& preview();
+
+ /// \brief Use plugin manager for features creation
+ SketchPlugin_ConstraintLength();
+};
+
+#endif
--- /dev/null
+// File: SketchPlugin_ConstraintRadius.cpp
+// Created: 26 May 2014
+// Author: Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintRadius.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <SketchPlugin_Point.h>
+
+SketchPlugin_ConstraintRadius::SketchPlugin_ConstraintRadius()
+{
+}
+
+void SketchPlugin_ConstraintRadius::initAttributes()
+{
+ data()->addAttribute(CONSTRAINT_ATTR_VALUE, ModelAPI_AttributeDouble::type());
+ data()->addAttribute(CONSTRAINT_ATTR_ENTITY_A, ModelAPI_AttributeRefAttr::type());
+}
+
+void SketchPlugin_ConstraintRadius::execute()
+{
+}
+
+const boost::shared_ptr<GeomAPI_Shape>& SketchPlugin_ConstraintRadius::preview()
+{
+ /// \todo Preview for diameter constraint
+ return getPreview();
+}
+
--- /dev/null
+// File: SketchPlugin_ConstraintRadius.h
+// Created: 26 May 2014
+// Author: Artem ZHIDKOV
+
+#ifndef SketchPlugin_ConstraintRadius_HeaderFile
+#define SketchPlugin_ConstraintRadius_HeaderFile
+
+#include "SketchPlugin.h"
+#include "SketchPlugin_Constraint.h"
+
+
+/** \class SketchPlugin_ConstraintRadius
+ * \ingroup DataModel
+ * \brief Feature for creation of a new constraint which defines
+ * a radius of a circle or an arc of circle
+ *
+ * These constraint has two attributes:
+ * CONSTRAINT_ATTR_VALUE (radius), CONSTRAINT_ATTR_ENTITY_A (a circle)
+ */
+class SketchPlugin_ConstraintRadius: public SketchPlugin_Constraint
+{
+public:
+ /// \brief Returns the kind of a feature
+ SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
+ {static std::string MY_KIND = "SketchConstraintRadius"; return MY_KIND;}
+
+ /// \brief Returns to which group in the document must be added feature
+ SKETCHPLUGIN_EXPORT virtual const std::string& getGroup()
+ {static std::string MY_GROUP = "Sketch"; return MY_GROUP;}
+
+ /// \brief Creates a new part document if needed
+ SKETCHPLUGIN_EXPORT virtual void execute();
+
+ /// \brief Request for initialization of data model of the feature: adding all attributes
+ SKETCHPLUGIN_EXPORT virtual void initAttributes();
+
+ /// \brief Returns the sketch preview
+ SKETCHPLUGIN_EXPORT virtual const boost::shared_ptr<GeomAPI_Shape>& preview();
+
+ /// \brief Use plugin manager for features creation
+ SketchPlugin_ConstraintRadius();
+};
+
+#endif
#include "SketchPlugin_Arc.h"
#include "SketchPlugin_ConstraintCoincidence.h"
#include "SketchPlugin_ConstraintDistance.h"
-#include "SketchPlugin_ConstraintDiameter.h"
+#include "SketchPlugin_ConstraintLength.h"
#include "SketchPlugin_ConstraintParallel.h"
#include "SketchPlugin_ConstraintPerpendicular.h"
+#include "SketchPlugin_ConstraintRadius.h"
#include <ModelAPI_PluginManager.h>
#include <ModelAPI_Document.h>
else if (theFeatureID == "SketchConstraintDistance") {
return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintDistance);
}
- else if (theFeatureID == "SketchConstraintDiameter") {
- return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintDiameter);
+ else if (theFeatureID == "SketchConstraintLength") {
+ return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintLength);
}
else if (theFeatureID == "SketchConstraintParallel") {
return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintParallel);
else if (theFeatureID == "SketchConstraintPerpendicular") {
return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintPerpendicular);
}
+ else if (theFeatureID == "SketchConstraintRadius") {
+ return boost::shared_ptr<ModelAPI_Feature>(new SketchPlugin_ConstraintRadius);
+ }
// feature of such kind is not found
return boost::shared_ptr<ModelAPI_Feature>();
}
</feature>
<feature id="SketchConstraintCoincidence" title="Points coincidence" tooltip="Create constraint for the coincidence of two points" internal="1"/>
<feature id="SketchConstraintDistance" title="Distance between objects" tooltip="Create constraint for the distance from a point to an object" internal="1"/>
- <feature id="SketchConstraintDiameter" title="Diameter of a circle" tooltip="Create constraint for the given diameter of a circle" internal="1"/>
+ <feature id="SketchConstraintLength" title="Length of a line" tooltip="Create constraint for the given length of a line segment" internal="1"/>
+ <feature id="SketchConstraintRadius" title="Radius of a circle or an arc" tooltip="Create constraint for the given radius of a circle or an arc" internal="1"/>
<feature id="SketchConstraintParallel" title="Parallelism of a lines" tooltip="Create constraint defining two parallel lines" internal="1"/>
<feature id="SketchConstraintPerpendicular" title="Orthgonality of a lines" tooltip="Create constraint defining two perpendicular lines" internal="1"/>
</group>
return getType();
}
+ // Constraint for the given length of a line
+ if (aConstraintKind.compare("SketchConstraintLength") == 0)
+ {
+ int aNbLines = 0;
+ for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
+ {
+ boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr =
+ boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[indAttr])
+ );
+ if (!anAttr) continue;
+ if (anAttr->isFeature() && anAttr->feature()->getKind().compare("SketchLine") == 0)
+ {
+ myAttributesList[aNbLines++] = CONSTRAINT_ATTRIBUTES[indAttr];
+ break;
+ }
+ }
+ if (aNbLines == 1)
+ myType = SLVS_C_PT_PT_DISTANCE;
+ return getType();
+ }
+
// Constraint for two parallel/perpendicular lines
bool isParallel = (aConstraintKind.compare("SketchConstraintParallel") == 0);
bool isPerpendicular = (aConstraintKind.compare("SketchConstraintPerpendicular") == 0);
return getType();
}
- // Constraint for diameter of a circle
- if (aConstraintKind.compare("SketchConstraintDiameter") == 0)
+ // Constraint for radius of a circle or an arc of circle
+ if (aConstraintKind.compare("SketchConstraintRadius") == 0)
{
int aNbEntities = 2; // lines in SolveSpace constraints should started from CONSTRAINT_ATTR_ENTITY_C attribute
for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++)
);
if (!anAttr || !anAttr->isFeature()) continue;
const std::string& aKind = anAttr->feature()->getKind();
- if (aKind.compare("SketchCircle") == 0)
+ if (aKind.compare("SketchCircle") == 0 || aKind.compare("SketchArc") == 0)
{
myAttributesList[aNbEntities++] = CONSTRAINT_ATTRIBUTES[indAttr];
continue;
theConstraint->data()->attribute(CONSTRAINT_ATTRIBUTES[i])
);
if (!aCAttrRef) continue;
- if (myEntityMap.find(aCAttrRef->attr()) != myEntityMap.end())
+ if (!aCAttrRef->isFeature() &&
+ myEntityAttrMap.find(aCAttrRef->attr()) != myEntityAttrMap.end())
+ return true;
+ if (aCAttrRef->isFeature() &&
+ myEntityFeatMap.find(aCAttrRef->feature()) != myEntityFeatMap.end())
return true;
}
myNeedToSolve = true;
aConstrIter->valA = aDistance;
}
+ // SketchPlugin circle defined by its radius, but SolveSpace uses constraint for diameter
+ if (aConstrType == SLVS_C_DIAMETER)
+ aDistance *= 2.0;
}
Slvs_hEntity aConstrEnt[CONSTRAINT_ATTR_SIZE]; // parameters of the constraint
theConstraint->data()->attribute(aConstraintAttributes[indAttr])
);
if (!aConstrAttr) continue;
- aConstrEnt[indAttr] = changeEntity(aConstrAttr->attr());
+
+ // For the length constraint the start and end points of the line should be added to the entities list instead of line
+ if (aConstrType == SLVS_C_PT_PT_DISTANCE && theConstraint->getKind().compare("SketchConstraintLength") == 0)
+ {
+ boost::shared_ptr<ModelAPI_Data> aData = aConstrAttr->feature()->data();
+ aConstrEnt[indAttr] = changeEntity(aData->attribute(LINE_ATTR_START));
+ aConstrEnt[indAttr+1] = changeEntity(aData->attribute(LINE_ATTR_END));
+ break; // there should be no other entities
+ }
+ else if (aConstrAttr->isFeature())
+ aConstrEnt[indAttr] = changeEntity(aConstrAttr->feature());
+ else
+ aConstrEnt[indAttr] = changeEntity(aConstrAttr->attr());
}
if (aConstrMapIter == myConstraintMap.end())
{
// Several points may be coincident, it is not necessary to store all constraints between them.
// Try to find sequence of coincident points which connects the points of new constraint
- if (aConstrType == SLVS_C_POINTS_COINCIDENT)
+ if (aConstrType == SLVS_C_POINTS_COINCIDENT &&
+ !addCoincidentPoints(aConstrEnt[0], aConstrEnt[1]))
{
- std::vector< std::set<Slvs_hEntity> >::iterator aCoPtIter = myCoincidentPoints.begin();
- std::vector< std::set<Slvs_hEntity> >::iterator aFirstFound = myCoincidentPoints.end();
- for ( ; aCoPtIter != myCoincidentPoints.end(); aCoPtIter++)
- {
- bool isFound[2] = { // indicate which point ID was already in coincidence constraint
- aCoPtIter->find(aConstrEnt[0]) != aCoPtIter->end(),
- aCoPtIter->find(aConstrEnt[1]) != aCoPtIter->end(),
- };
- if (isFound[0] && isFound[1]) // points are already connected by coincidence constraints => no need additional one
- {
- myExtraCoincidence.insert(theConstraint); // the constraint is stored for further purposes
- return false;
- }
- if ((isFound[0] && !isFound[1]) || (!isFound[0] && isFound[1]))
- {
- if (aFirstFound != myCoincidentPoints.end())
- { // there are two groups of coincident points connected by created constraint => merge them
- int aFirstFoundShift = aFirstFound - myCoincidentPoints.begin();
- int aCurrentShift = aCoPtIter - myCoincidentPoints.begin();
- aFirstFound->insert(aCoPtIter->begin(), aCoPtIter->end());
- myCoincidentPoints.erase(aCoPtIter);
- aFirstFound = myCoincidentPoints.begin() + aFirstFoundShift;
- aCoPtIter = myCoincidentPoints.begin() + aCurrentShift;
- }
- else
- {
- aCoPtIter->insert(aConstrEnt[isFound[0] ? 1 : 0]);
- aFirstFound = aCoPtIter;
- }
- }
- }
- // No points were found, need to create new set
- if (aFirstFound == myCoincidentPoints.end())
- {
- std::set<Slvs_hEntity> aNewSet;
- aNewSet.insert(aConstrEnt[0]);
- aNewSet.insert(aConstrEnt[1]);
- myCoincidentPoints.push_back(aNewSet);
- }
+ myExtraCoincidence.insert(theConstraint); // the constraint is stored for further purposes
+ return false;
}
// Create SolveSpace constraint structure
{
// If the entity is already in the group, try to find it
std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator
- aEntIter = myEntityMap.find(theEntity);
+ aEntIter = myEntityAttrMap.find(theEntity);
std::vector<Slvs_Param>::const_iterator aParamIter; // looks at first parameter of already existent entity or at the end of vector otherwise
- if (aEntIter == myEntityMap.end()) // no such entity => should be created
+ if (aEntIter == myEntityAttrMap.end()) // no such entity => should be created
aParamIter = myParams.end();
else
{ // the entity already exists
int aParamPos = Search(myEntities[aEntPos].param[0], myParams);
aParamIter = myParams.begin() + aParamPos;
}
+ const bool isEntExists = (aEntIter != myEntityAttrMap.end()); // defines that the entity already exists
// Look over supported types of entities
Slvs_hParam aY = changeParameter(aPoint->y(), aParamIter);
Slvs_hParam aZ = changeParameter(aPoint->z(), aParamIter);
- if (aEntIter != myEntityMap.end()) // the entity already exists
+ if (isEntExists)
return aEntIter->second;
// New entity
Slvs_Entity aPtEntity = Slvs_MakePoint3d(++myEntityMaxID, myID, aX, aY, aZ);
myEntities.push_back(aPtEntity);
- myEntityMap[theEntity] = aPtEntity.h;
+ myEntityAttrMap[theEntity] = aPtEntity.h;
return aPtEntity.h;
}
Slvs_hParam aU = changeParameter(aPoint2D->x(), aParamIter);
Slvs_hParam aV = changeParameter(aPoint2D->y(), aParamIter);
- if (aEntIter != myEntityMap.end()) // the entity already exists
+ if (isEntExists)
return aEntIter->second;
// New entity
Slvs_Entity aPt2DEntity = Slvs_MakePoint2d(++myEntityMaxID, myID, myWorkplane.h, aU, aV);
myEntities.push_back(aPt2DEntity);
- myEntityMap[theEntity] = aPt2DEntity.h;
+ myEntityAttrMap[theEntity] = aPt2DEntity.h;
return aPt2DEntity.h;
}
{
Slvs_hParam aValue = changeParameter(aScalar->value(), aParamIter);
- if (aEntIter != myEntityMap.end()) // the entity already exists
+ if (isEntExists)
return aEntIter->second;
// New entity
Slvs_Entity aDistance = Slvs_MakeDistance(++myEntityMaxID, myID, myWorkplane.h, aValue);
myEntities.push_back(aDistance);
- myEntityMap[theEntity] = aDistance.h;
+ myEntityAttrMap[theEntity] = aDistance.h;
return aDistance.h;
}
+ /// \todo Other types of entities
+
+ // Unsupported or wrong entity type
+ return SLVS_E_UNKNOWN;
+}
+
+
+// ============================================================================
+// Function: changeEntity
+// Class: SketchSolver_ConstraintGroup
+// Purpose: create/update the element defined by the feature affected by any constraint
+// ============================================================================
+Slvs_hEntity SketchSolver_ConstraintGroup::changeEntity(
+ boost::shared_ptr<ModelAPI_Feature> theEntity)
+{
+ // If the entity is already in the group, try to find it
+ std::map<boost::shared_ptr<ModelAPI_Feature>, Slvs_hEntity>::const_iterator
+ aEntIter = myEntityFeatMap.find(theEntity);
+ // defines that the entity already exists
+ const bool isEntExists = (myEntityFeatMap.find(theEntity) != myEntityFeatMap.end());
+
// SketchPlugin features
- boost::shared_ptr<SketchPlugin_Feature> aFeature =
+ boost::shared_ptr<SketchPlugin_Feature> aFeature;
boost::dynamic_pointer_cast<SketchPlugin_Feature>(theEntity);
if (aFeature)
{ // Verify the feature by its kind
Slvs_hEntity aStart = changeEntity(aFeature->data()->attribute(LINE_ATTR_START));
Slvs_hEntity aEnd = changeEntity(aFeature->data()->attribute(LINE_ATTR_END));
- if (aEntIter != myEntityMap.end()) // the entity already exists
+ if (isEntExists)
return aEntIter->second;
// New entity
Slvs_Entity aLineEntity = Slvs_MakeLineSegment(++myEntityMaxID, myID, myWorkplane.h, aStart, aEnd);
myEntities.push_back(aLineEntity);
- myEntityMap[theEntity] = aLineEntity.h;
+ myEntityFeatMap[theEntity] = aLineEntity.h;
return aLineEntity.h;
}
// Circle
Slvs_hEntity aCenter = changeEntity(aFeature->data()->attribute(CIRCLE_ATTR_CENTER));
Slvs_hEntity aRadius = changeEntity(aFeature->data()->attribute(CIRCLE_ATTR_RADIUS));
- if (aEntIter != myEntityMap.end()) // the entity already exists
+ if (isEntExists)
return aEntIter->second;
// New entity
Slvs_Entity aCircleEntity =
Slvs_MakeCircle(++myEntityMaxID, myID, myWorkplane.h, aCenter, myWorkplane.normal, aRadius);
myEntities.push_back(aCircleEntity);
- myEntityMap[theEntity] = aCircleEntity.h;
+ myEntityFeatMap[theEntity] = aCircleEntity.h;
return aCircleEntity.h;
}
// Arc
Slvs_hEntity aStart = changeEntity(aFeature->data()->attribute(ARC_ATTR_START));
Slvs_hEntity aEnd = changeEntity(aFeature->data()->attribute(ARC_ATTR_END));
- if (aEntIter != myEntityMap.end()) // the entity already exists
+ if (isEntExists)
return aEntIter->second;
Slvs_Entity anArcEntity = Slvs_MakeArcOfCircle(++myEntityMaxID, myID,
myWorkplane.h, myWorkplane.normal, aCenter, aStart, aEnd);
myEntities.push_back(anArcEntity);
- myEntityMap[theEntity] = anArcEntity.h;
+ myEntityFeatMap[theEntity] = anArcEntity.h;
return anArcEntity.h;
}
// Point (it has low probability to be an attribute of constraint, so it is checked at the end)
{
Slvs_hEntity aPoint = changeEntity(aFeature->data()->attribute(POINT_ATTR_COORD));
- if (aEntIter != myEntityMap.end()) // the entity already exists
+ if (isEntExists)
return aEntIter->second;
// Both the sketch point and its attribute (coordinates) link to the same SolveSpace point identifier
- myEntityMap[theEntity] = aPoint;
+ myEntityFeatMap[theEntity] = aPoint;
return aPoint;
}
}
- /// \todo Other types of entities
+ /// \todo Other types of features
// Unsupported or wrong entity type
return SLVS_E_UNKNOWN;
// Try to find existent normal
std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator
- aEntIter = myEntityMap.find(theNorm);
+ aEntIter = myEntityAttrMap.find(theNorm);
std::vector<Slvs_Param>::const_iterator aParamIter; // looks to the first parameter of already existent entity or to the end of vector otherwise
- if (aEntIter == myEntityMap.end()) // no such entity => should be created
+ if (aEntIter == myEntityAttrMap.end()) // no such entity => should be created
aParamIter = myParams.end();
else
{ // the entity already exists, update it
for (int i = 0; i < 4; i++)
aNormParams[i] = changeParameter(aNormCoord[i], aParamIter);
- if (aEntIter != myEntityMap.end()) // the entity already exists
+ if (aEntIter != myEntityAttrMap.end()) // the entity already exists
return aEntIter->second;
// Create a normal
Slvs_Entity aNormal = Slvs_MakeNormal3d(++myEntityMaxID, myID,
aNormParams[0], aNormParams[1], aNormParams[2], aNormParams[3]);
myEntities.push_back(aNormal);
- myEntityMap[theNorm] = aNormal.h;
+ myEntityAttrMap[theNorm] = aNormal.h;
return aNormal.h;
}
if (!myConstrSolver.getResult(myParams))
return;
+ // We should go through the attributes map, because only attributes have valued parameters
std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::iterator
- anEntIter = myEntityMap.begin();
- for ( ; anEntIter != myEntityMap.end(); anEntIter++)
+ anEntIter = myEntityAttrMap.begin();
+ for ( ; anEntIter != myEntityAttrMap.end(); anEntIter++)
updateAttribute(anEntIter->first, anEntIter->second);
}
/// \todo Implement error handling
else if (!theGroup.myTempPointWhereDragged.empty())
{ // Need to create additional transient constraint
std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator
- aFeatureIter = theGroup.myEntityMap.begin();
- for (; aFeatureIter != theGroup.myEntityMap.end(); aFeatureIter++)
+ aFeatureIter = theGroup.myEntityAttrMap.begin();
+ for (; aFeatureIter != theGroup.myEntityAttrMap.end(); aFeatureIter++)
if (aFeatureIter->second == myTempPointWDrgdID)
{
addTemporaryConstraintWhereDragged(aFeatureIter->first);
Slvs_hEntity aConstrEnt[] = {
aConstrIter->ptA, aConstrIter->ptB,
aConstrIter->entityA, aConstrIter->entityB};
+ std::vector<int> anIndexes;
// Go through the groupped entities and find even one of entities of current constraint
std::vector< std::set<Slvs_hEntity> >::iterator aGrEntIter;
for (aGrEntIter = aGroupsEntities.begin(); aGrEntIter != aGroupsEntities.end(); aGrEntIter++)
if (aConstrEnt[i] != 0)
isFound = (aGrEntIter->find(aConstrEnt[i]) != aGrEntIter->end());
if (isFound)
- {
- for (int i = 0; i < 4; i++)
- if (aConstrEnt[i] != 0)
- aGrEntIter->insert(aConstrEnt[i]);
- aGroupsConstr[aGrEntIter - aGroupsEntities.begin()].insert(aConstrIter->h);
- if (aGrEntIter->size() > aGroupsEntities[aMaxNbEntities].size())
- aMaxNbEntities = aGrEntIter - aGroupsEntities.begin();
- break;
- }
+ anIndexes.push_back(aGrEntIter - aGroupsEntities.begin());
}
// Add new group if no one is found
- if (aGrEntIter == aGroupsEntities.end())
+ if (anIndexes.empty())
{
std::set<Slvs_hEntity> aNewGrEnt;
for (int i = 0; i < 4; i++)
if (aNewGrEnt.size() > aGroupsEntities[aMaxNbEntities].size())
aMaxNbEntities = aGroupsEntities.size() - 1;
}
+ else if (anIndexes.size() == 1)
+ { // Add entities indexes into the found group
+ for (int i = 0; i < 4; i++)
+ if (aConstrEnt[i] != 0)
+ aGrEntIter->insert(aConstrEnt[i]);
+ aGroupsConstr[aGrEntIter - aGroupsEntities.begin()].insert(aConstrIter->h);
+ if (aGrEntIter->size() > aGroupsEntities[aMaxNbEntities].size())
+ aMaxNbEntities = aGrEntIter - aGroupsEntities.begin();
+ }
+ else
+ { // There are found several connected groups, merge them
+ std::vector< std::set<Slvs_hEntity> >::iterator aFirstGroup =
+ aGroupsEntities.begin() + anIndexes.front();
+ std::vector< std::set<Slvs_hConstraint> >::iterator aFirstConstr =
+ aGroupsConstr.begin() + anIndexes.front();
+ std::vector<int>::iterator anInd = anIndexes.begin();
+ for (++anInd; anInd != anIndexes.end(); anInd++)
+ {
+ aFirstGroup->insert(aGroupsEntities[*anInd].begin(), aGroupsEntities[*anInd].end());
+ aFirstConstr->insert(aGroupsConstr[*anInd].begin(), aGroupsConstr[*anInd].end());
+ }
+ if (aFirstGroup->size() > aGroupsEntities[aMaxNbEntities].size())
+ aMaxNbEntities = anIndexes.front();
+ // Remove merged groups
+ for (anInd = anIndexes.end() - 1; anInd != anIndexes.begin(); anInd--)
+ {
+ aGroupsEntities.erase(aGroupsEntities.begin() + (*anInd));
+ aGroupsConstr.erase(aGroupsConstr.begin() + (*anInd));
+ }
+ }
}
if (aGroupsEntities.size() <= 1)
void SketchSolver_ConstraintGroup::updateEntityIfPossible(
boost::shared_ptr<ModelAPI_Attribute> theEntity)
{
- if (myEntityMap.find(theEntity) != myEntityMap.end())
+ if (myEntityAttrMap.find(theEntity) != myEntityAttrMap.end())
{
// If the attribute is a point and it is changed (the group needs to rebuild),
// probably user has dragged this point into this position,
{
// Find identifier of the entity
std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::const_iterator
- anEntIter = myEntityMap.find(theEntity);
- if (anEntIter == myEntityMap.end())
+ anEntIter = myEntityAttrMap.find(theEntity);
+ if (anEntIter == myEntityAttrMap.end())
return ;
// If this is a first dragged point, its parameters should be placed
// Remove unused entities
std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::iterator
- anEntMapIter = myEntityMap.begin();
- while (anEntMapIter != myEntityMap.end())
+ anEntAttrIter = myEntityAttrMap.begin();
+ while (anEntAttrIter != myEntityAttrMap.end())
{
- if (anEntToRemove.find(anEntMapIter->second) != anEntToRemove.end())
+ if (anEntToRemove.find(anEntAttrIter->second) != anEntToRemove.end())
{
std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>::iterator
- aRemovedIter = anEntMapIter;
- anEntMapIter++;
- myEntityMap.erase(aRemovedIter);
+ aRemovedIter = anEntAttrIter;
+ anEntAttrIter++;
+ myEntityAttrMap.erase(aRemovedIter);
}
- else anEntMapIter++;
+ else anEntAttrIter++;
+ }
+ std::map<boost::shared_ptr<ModelAPI_Feature>, Slvs_hEntity>::iterator
+ anEntFeatIter = myEntityFeatMap.begin();
+ while (anEntFeatIter != myEntityFeatMap.end())
+ {
+ if (anEntToRemove.find(anEntFeatIter->second) != anEntToRemove.end())
+ {
+ std::map<boost::shared_ptr<ModelAPI_Feature>, Slvs_hEntity>::iterator
+ aRemovedIter = anEntFeatIter;
+ anEntFeatIter++;
+ myEntityFeatMap.erase(aRemovedIter);
+ }
+ else anEntFeatIter++;
}
std::set<Slvs_hEntity>::const_reverse_iterator aRemIter = anEntToRemove.rbegin();
for ( ; aRemIter != anEntToRemove.rend(); aRemIter++)
}
+// ============================================================================
+// Function: addCoincidentPoints
+// Class: SketchSolver_ConstraintGroup
+// Purpose: add coincident point the appropriate list of such points
+// ============================================================================
+bool SketchSolver_ConstraintGroup::addCoincidentPoints(
+ const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2)
+{
+ std::vector< std::set<Slvs_hEntity> >::iterator aCoPtIter = myCoincidentPoints.begin();
+ std::vector< std::set<Slvs_hEntity> >::iterator aFirstFound = myCoincidentPoints.end();
+ while (aCoPtIter != myCoincidentPoints.end())
+ {
+ bool isFound[2] = { // indicate which point ID was already in coincidence constraint
+ aCoPtIter->find(thePoint1) != aCoPtIter->end(),
+ aCoPtIter->find(thePoint2) != aCoPtIter->end(),
+ };
+ if (isFound[0] && isFound[1]) // points are already connected by coincidence constraints => no need additional one
+ return false;
+ if ((isFound[0] && !isFound[1]) || (!isFound[0] && isFound[1]))
+ {
+ if (aFirstFound != myCoincidentPoints.end())
+ { // there are two groups of coincident points connected by created constraint => merge them
+ int aFirstFoundShift = aFirstFound - myCoincidentPoints.begin();
+ int aCurrentShift = aCoPtIter - myCoincidentPoints.begin();
+ aFirstFound->insert(aCoPtIter->begin(), aCoPtIter->end());
+ myCoincidentPoints.erase(aCoPtIter);
+ aFirstFound = myCoincidentPoints.begin() + aFirstFoundShift;
+ aCoPtIter = myCoincidentPoints.begin() + aCurrentShift;
+ continue;
+ }
+ else
+ {
+ aCoPtIter->insert(isFound[0] ? thePoint2 : thePoint1);
+ aFirstFound = aCoPtIter;
+ }
+ }
+ aCoPtIter++;
+ }
+ // No points were found, need to create new set
+ if (aFirstFound == myCoincidentPoints.end())
+ {
+ std::set<Slvs_hEntity> aNewSet;
+ aNewSet.insert(thePoint1);
+ aNewSet.insert(thePoint2);
+ myCoincidentPoints.push_back(aNewSet);
+ }
+
+ return true;
+}
+
+
+
// ========================================================
// ========= Auxiliary functions ===============
* \return identifier of changed entity or 0 if entity could not be changed
*/
Slvs_hEntity changeEntity(boost::shared_ptr<ModelAPI_Attribute> theEntity);
+ Slvs_hEntity changeEntity(boost::shared_ptr<ModelAPI_Feature> theEntity);
/** \brief Adds or updates a normal in the group
*
*/
bool addWorkplane(boost::shared_ptr<SketchPlugin_Feature> theSketch);
+ /** \brief Add the entities of constraint for points coincidence into the appropriate list
+ * \param[in] thePoint1 identifier of the first point
+ * \param[in] thePoint2 identifier of the second point
+ * \return \c true if the points are added successfully, and
+ * \c false if the constraint is the extra one (should not be created in SolveSpace)
+ */
+ bool addCoincidentPoints(const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2);
+
private:
// SolveSpace entities
Slvs_hGroup myID; ///< the index of the group
std::map<boost::shared_ptr<SketchPlugin_Constraint>, Slvs_hConstraint>
myConstraintMap; ///< The map between SketchPlugin and SolveSpace constraints
std::map<boost::shared_ptr<ModelAPI_Attribute>, Slvs_hEntity>
- myEntityMap; ///< The map between parameters of constraints and their equivalent SolveSpace entities
+ myEntityAttrMap; ///< The map between "attribute" parameters of constraints and their equivalent SolveSpace entities
+ std::map<boost::shared_ptr<ModelAPI_Feature>, Slvs_hEntity>
+ myEntityFeatMap; ///< The map between "feature" parameters of constraints and their equivalent SolveSpace entities
// Conincident items
std::vector< std::set<Slvs_hEntity> >
#include "XGUI_DocumentDataModel.h"
#include "XGUI_PartDataModel.h"
#include "XGUI_Workshop.h"
+#include "XGUI_Tools.h"
#include <ModelAPI_PluginManager.h>
#include <ModelAPI_Document.h>
QModelIndex XGUI_DocumentDataModel::partIndex(const FeaturePtr& theFeature) const
{
FeaturePtr aFeature = theFeature;
- if (!aFeature->data()) {
+ if (XGUI_Tools::isModelObject(aFeature)) {
ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature);
aFeature = aObject->featureRef();
}
#include "XGUI_ObjectsBrowser.h"
#include "XGUI_DocumentDataModel.h"
+#include "XGUI_Tools.h"
#include <ModelAPI_Data.h>
#include <ModelAPI_PluginManager.h>
FeaturePtr aFeature = mySelectedData.first();
PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
aMgr->rootDocument()->startOperation();
- if (aFeature->data())
+ if (!XGUI_Tools::isModelObject(aFeature))
aFeature->data()->setName(qPrintable(aRes));
else
boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature)->setName(qPrintable(aRes));
void XGUI_OperationMgr::onCommitOperation()
{
ModuleBase_Operation* anOperation = currentOperation();
- if (anOperation)
- anOperation->commit();
+ if (anOperation) {
+ if (anOperation->canBeCommitted())
+ anOperation->commit();
+ else
+ anOperation->abort();
+ }
}
void XGUI_OperationMgr::onAbortOperation()
#include <iostream>
#include <sstream>
+namespace XGUI_Tools
+{
//******************************************************************
QString dir(const QString& path, bool isAbs)
{
return QRect(qMin(x1, x2), qMin(y1, y2), qAbs(x2 - x1), qAbs(y2 - y1));
}
+//******************************************************************
+bool isModelObject(boost::shared_ptr<ModelAPI_Feature> theFeature)
+{
+ return theFeature && !theFeature->data();
+}
+
//******************************************************************
std::string featureInfo(boost::shared_ptr<ModelAPI_Feature> theFeature)
{
return QString(aStream.str().c_str()).toStdString();
}
+}
\ No newline at end of file
\param abs if true (default) \a path parameter is treated as absolute file path
\return directory part of the file path
*/
-QString XGUI_EXPORT dir(const QString& path, bool isAbs = true);
+namespace XGUI_Tools
+{
+ QString XGUI_EXPORT dir(const QString& path, bool isAbs = true);
-/*!
- \brief Return file name part of the file path.
+ /*!
+ \brief Return file name part of the file path.
- \param path file path
- \param withExt if true (default) complete file name (with all
- extension except the last) is returned, otherwise only base name
- is returned
- \return file name part of the file path
- */
-QString XGUI_EXPORT file(const QString& path, bool withExt = true);
+ \param path file path
+ \param withExt if true (default) complete file name (with all
+ extension except the last) is returned, otherwise only base name
+ is returned
+ \return file name part of the file path
+ */
+ QString XGUI_EXPORT file(const QString& path, bool withExt = true);
-/*!
- \brief Return extension part of the file path.
+ /*!
+ \brief Return extension part of the file path.
- \param path file path
- \param full if true complete extension (all extensions, dot separated)
- is returned, otherwise (default) only last extension is returned
- \return extension part of the file path
- */
-QString XGUI_EXPORT extension(const QString& path, bool full = false);
+ \param path file path
+ \param full if true complete extension (all extensions, dot separated)
+ is returned, otherwise (default) only last extension is returned
+ \return extension part of the file path
+ */
+ QString XGUI_EXPORT extension(const QString& path, bool full = false);
-/*!
- \brief Add a slash (platform-specific) to the end of \a path
- if it is not already there.
- \param path directory path
- \return modified path (with slash added to the end)
- */
-QString XGUI_EXPORT addSlash(const QString& path);
+ /*!
+ \brief Add a slash (platform-specific) to the end of \a path
+ if it is not already there.
+ \param path directory path
+ \return modified path (with slash added to the end)
+ */
+ QString XGUI_EXPORT addSlash(const QString& path);
-/*!
- Creates a rect with TopLeft = ( min(x1,x2), min(y1,y2) )
- and BottomRight = ( TopLeft + (x2-x1)(y2-y1) )
- */
-QRect XGUI_EXPORT makeRect(const int x1, const int y1, const int x2, const int y2);
+ /*!
+ Creates a rect with TopLeft = ( min(x1,x2), min(y1,y2) )
+ and BottomRight = ( TopLeft + (x2-x1)(y2-y1) )
+ */
+ QRect XGUI_EXPORT makeRect(const int x1, const int y1, const int x2, const int y2);
+
+ /// The model concerning tools
+
+ /*!
+ Returns true if the feature is a model object
+ \param theFeature a feature
+ */
+ bool XGUI_EXPORT isModelObject(boost::shared_ptr<ModelAPI_Feature> theFeature);
+
+ /*!
+ Returns the string presentation of the given feature
+ \param theFeature a feature
+ */
+ std::string XGUI_EXPORT featureInfo(boost::shared_ptr<ModelAPI_Feature> theFeature);
+}
-/*!
- Returns the string presentation of the given feature
- \param theFeature a feature
-*/
-std::string XGUI_EXPORT featureInfo(boost::shared_ptr<ModelAPI_Feature> theFeature);
#endif
myCurrX = theEvent->x();
myCurrY = theEvent->y();
drawRect();
- QRect rect = makeRect(myStartX, myStartY, myCurrX, myCurrY);
+ QRect rect = XGUI_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
if (!rect.isEmpty())
myViewPort->fitRect(rect);
endDrawRect();
}
myRectBand->setUpdatesEnabled(false);
- QRect aRect = makeRect(myStartX, myStartY, myCurrX, myCurrY);
+ QRect aRect = XGUI_Tools::makeRect(myStartX, myStartY, myCurrX, myCurrY);
myRectBand->initGeometry(aRect);
if (!myRectBand->isVisible())
QApplication::setOverrideCursor( Qt::WaitCursor );
QImage aPicture = myViewPort->dumpView();
- QString aFmt = extension(aFileName).toUpper();
+ QString aFmt = XGUI_Tools::extension(aFileName).toUpper();
if( aFmt.isEmpty() )
aFmt = QString( "BMP" ); // default format
else if( aFmt == "JPG" )
PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
if (thePart) {
DocumentPtr aFeaDoc;
- if (thePart->data()) {
+ if (!XGUI_Tools::isModelObject(thePart)) {
aFeaDoc = thePart->data()->docRef("PartDocument")->value();
} else {
ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(thePart);
foreach (FeaturePtr aFeature, theList) {
if (aFeature->getKind() == "Part") {
DocumentPtr aDoc;
- if (aFeature->data()) {
+ if (!XGUI_Tools::isModelObject(aFeature)) {
aDoc = aFeature->data()->docRef("PartDocument")->value();
} else {
ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature);
aDoc->close();
}
} else {
- if (!aFeature->data()) {
+ if (XGUI_Tools::isModelObject(aFeature)) {
ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature);
aFeature = aObject->featureRef();
}