std::map<std::string, std::shared_ptr<ModelAPI_Attribute> >::iterator aMyIter = myAttrs.begin();
for(; aMyIter != myAttrs.end(); aMyIter++) {
if (aMyIter->second->isInitialized()) {
- theTarget->attribute(aMyIter->first)->setInitialized();
+ AttributePtr aTargetAttr = theTarget->attribute(aMyIter->first);
+ if (aTargetAttr)
+ aTargetAttr->setInitialized();
}
}
}
std::shared_ptr<ModelAPI_ObjectDeletedMessage> aDeleted =
std::dynamic_pointer_cast<ModelAPI_ObjectDeletedMessage>(theMessage);
if (aDeleted &&
- aDeleted->groups().find(ModelAPI_ResultPart::group()) != aDeleted->groups().end() &&
- !ModelAPI_Tools::findPartResult(moduleDocument(), activeDocument()).get()) // another part may be disabled
+ aDeleted->groups().find(ModelAPI_ResultPart::group()) != aDeleted->groups().end())
{
- setActiveDocument(moduleDocument());
+ // check that the current feature of the session is still the active Part (even disabled)
+ bool aFound = false;
+ FeaturePtr aCurrentPart = moduleDocument()->currentFeature(true);
+ if (aCurrentPart.get()) {
+ const std::list<std::shared_ptr<ModelAPI_Result> >& aResList = aCurrentPart->results();
+ std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResList.begin();
+ for(; !aFound && aRes != aResList.end(); aRes++) {
+ ResultPartPtr aPRes = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRes);
+ if (aPRes.get() && aPRes->isActivated() && aPRes->partDoc() == activeDocument()) {
+ aFound = true;
+
+ }
+ }
+ }
+ if (!aFound) { // if not, the part was removed, so activate the module document
+ setActiveDocument(moduleDocument());
+ }
}
}
}
PartSet_WidgetSketchLabel.h
PartSet_Validators.h
PartSet_WidgetPoint2d.h
- PartSet_WidgetPoint2dAngle.h
PartSet_WidgetEditor.h
PartSet_WidgetMultiSelector.h
PartSet_WidgetPoint2dDistance.h
PartSet_WidgetEditor.cpp
PartSet_WidgetMultiSelector.cpp
PartSet_WidgetPoint2d.cpp
- PartSet_WidgetPoint2dAngle.cpp
PartSet_WidgetPoint2dDistance.cpp
PartSet_WidgetPoint2DFlyout.cpp
PartSet_WidgetShapeSelector.cpp
#include "PartSet_WidgetPoint2dDistance.h"
#include "PartSet_WidgetPoint2DFlyout.h"
#include "PartSet_WidgetShapeSelector.h"
-#include "PartSet_WidgetPoint2dAngle.h"
#include "PartSet_WidgetMultiSelector.h"
#include "PartSet_WidgetEditor.h"
#include "PartSet_WidgetFileSelector.h"
aWorkshop, theWidgetApi, theParentId);
aDistanceWgt->setSketch(mySketchMgr->activeSketch());
aWgt = aDistanceWgt;
- } else if(theType == "point2dangle") {
- PartSet_WidgetPoint2dAngle* anAngleWgt = new PartSet_WidgetPoint2dAngle(theParent,
- aWorkshop, theWidgetApi, theParentId);
- anAngleWgt->setSketch(mySketchMgr->activeSketch());
- aWgt = anAngleWgt;
} else if (theType == "sketch_shape_selector") {
PartSet_WidgetShapeSelector* aShapeSelectorWgt =
new PartSet_WidgetShapeSelector(theParent, aWorkshop, theWidgetApi, theParentId);
+++ /dev/null
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File: PartSet_WidgetPoint2dAngle.cpp
-// Created: 23 June 2014
-// Author: Vitaly Smetannikov
-
-#include "PartSet_WidgetPoint2dAngle.h"
-
-#include <ModuleBase_ParamSpinBox.h>
-
-#include <ModuleBase_Tools.h>
-
-#include <GeomAPI_Pnt2d.h>
-#include <GeomDataAPI_Point2D.h>
-
-#include <ModelAPI_Data.h>
-#include <ModelAPI_AttributeDouble.h>
-
-#include <QMouseEvent>
-
-#include <GeomAPI_Dir2d.h>
-#include <GeomAPI_XY.h>
-
-#define PI 3.1415926535897932
-
-PartSet_WidgetPoint2dAngle::PartSet_WidgetPoint2dAngle(QWidget* theParent,
- ModuleBase_IWorkshop* theWorkshop,
- const Config_WidgetAPI* theData,
- const std::string& theParentId)
-: PartSet_WidgetPoint2dDistance(theParent, theWorkshop, theData, theParentId)
-{
-}
-
-PartSet_WidgetPoint2dAngle::~PartSet_WidgetPoint2dAngle()
-{
-}
-
-double PartSet_WidgetPoint2dAngle::computeValue(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPnt,
- const std::shared_ptr<GeomAPI_Pnt2d>& theCurrentPnt)
-{
- std::shared_ptr<GeomAPI_Dir2d> aHorizontalDir(new GeomAPI_Dir2d(1, 0));
- std::shared_ptr<GeomAPI_XY> aStartPnt = theFirstPnt->xy();
- std::shared_ptr<GeomAPI_XY> aEndPnt = theCurrentPnt->xy();
-
- std::shared_ptr<GeomAPI_Dir2d> aLineDir(new GeomAPI_Dir2d(aEndPnt->decreased(aStartPnt)));
-
- double aValue = aHorizontalDir->angle(aLineDir);
- aValue *= 180.0 / PI;
-
- return aValue;
-}
+++ /dev/null
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
-
-// File: PartSet_WidgetPoint2dAngle.h
-// Created: 30 Apr 2015
-// Author: Natalia Ermolaeva
-
-#ifndef PartSet_WidgetPoint2dAngle_H
-#define PartSet_WidgetPoint2dAngle_H
-
-#include "PartSet.h"
-#include "PartSet_WidgetPoint2dDistance.h"
-
-#include <ModelAPI_Feature.h>
-
-class ModuleBase_IWorkshop;
-
-class GeomAPI_Pnt2d;
-
-/**
-* \ingroup Modules
-* Implementation of model widget for widget which provides input of an anble between two points
-* The XML definion is the same as the parent one.
-*/
-class PARTSET_EXPORT PartSet_WidgetPoint2dAngle : public PartSet_WidgetPoint2dDistance
-{
-Q_OBJECT
- public:
- /// Constructor
- /// \param theParent the parent object
- /// \param theWorkshop a current workshop
- /// \param theData the widget configuation. The attribute of the model widget is obtained from
- /// \param theParentId is Id of a parent of the current attribute
- PartSet_WidgetPoint2dAngle(QWidget* theParent, ModuleBase_IWorkshop* theWorkshop,
- const Config_WidgetAPI* theData, const std::string& theParentId);
-
- virtual ~PartSet_WidgetPoint2dAngle();
-
-protected:
- /// Compute an angle between points
- /// \param theFirstPnt a point value of the out point attribute
- /// \param theCurrentPnt a point of the current widget
- /// \return a double value
- virtual double computeValue(const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPnt,
- const std::shared_ptr<GeomAPI_Pnt2d>& theCurrentPnt);
-};
-
-#endif
#include "SketchPlugin_Tools.h"
#include <GeomDataAPI_Point2D.h>
+#include <ModelAPI_AttributeRefAttr.h>
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeString.h>
#include <ModelAPI_AttributeInteger.h>
#define PI 3.1415926535897932
SketchPlugin_MultiRotation::SketchPlugin_MultiRotation()
-: myBlockAngle(false)
{
}
void SketchPlugin_MultiRotation::initAttributes()
{
- data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId());
+ data()->addAttribute(CENTER_ID(), ModelAPI_AttributeRefAttr::typeId());
data()->addAttribute(ANGLE_TYPE(), ModelAPI_AttributeString::typeId());
data()->addAttribute(ANGLE_ID(), ModelAPI_AttributeDouble::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());
return;
// Obtain center and angle of rotation
- std::shared_ptr<GeomDataAPI_Point2D> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- attribute(CENTER_ID()));
+ AttributeRefAttrPtr aCenter = data()->refattr(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();
+ //double anAngle = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
+ // attribute(ANGLE_ID()))->value();
// Convert angle to radians
- anAngle *= PI / 180.0;
+ //anAngle *= PI / 180.0;
// Wait all objects being created, then send update events
static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
return ObjectPtr();
}
-void SketchPlugin_MultiRotation::rotateFeature(
+/*void SketchPlugin_MultiRotation::rotateFeature(
ObjectPtr theInitial, ObjectPtr theTarget,
double theCenterX, double theCenterY, double theAngle)
{
// unblock feature update
aTargetFeature->data()->blockSendAttributeUpdated(false);
-}
+}*/
void SketchPlugin_MultiRotation::attributeChanged(const std::string& theID)
data()->attribute(SketchPlugin_Constraint::ENTITY_B()))->clear();
}
}
- else if (theID == ANGLE_ID() && !myBlockAngle) {
- int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value() - 1;
- if (aNbCopies > 0) {
- myBlockAngle = true;
- SketchPlugin_Tools::updateMultiAttribute(attribute(ANGLE_ID()), attribute(ANGLE_FULL_ID()),
- aNbCopies, true);
- myBlockAngle = false;
- Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
- }
- }
- else if (theID == ANGLE_FULL_ID() && !myBlockAngle) {
- int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value() - 1;
- if (aNbCopies > 0) {
- myBlockAngle = true;
- SketchPlugin_Tools::updateMultiAttribute(attribute(ANGLE_FULL_ID()), attribute(ANGLE_ID()),
- aNbCopies, false);
- myBlockAngle = false;
- Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
- }
- }
- else if (theID == NUMBER_OF_OBJECTS_ID()) {
- if (attribute(NUMBER_OF_OBJECTS_ID())->isInitialized() &&
- attribute(ANGLE_ID())->isInitialized() &&
- attribute(ANGLE_TYPE())->isInitialized()) {
- AttributeStringPtr aMethodTypeAttr = string(ANGLE_TYPE());
- std::string aMethodType = aMethodTypeAttr->value();
- int aNbCopies = integer(NUMBER_OF_OBJECTS_ID())->value() - 1;
- if (aNbCopies > 0) {
- myBlockAngle = true;
- if (aMethodType == "SingleAngle")
- SketchPlugin_Tools::updateMultiAttribute(attribute(ANGLE_ID()), attribute(ANGLE_FULL_ID()),
- aNbCopies, true);
- else {
- SketchPlugin_Tools::updateMultiAttribute(attribute(ANGLE_FULL_ID()), attribute(ANGLE_ID()),
- aNbCopies, false);
- }
- myBlockAngle = false;
- Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
- }
- }
- }
}
static const std::string MY_ANGLE_ID("MultiRotationAngle");
return MY_ANGLE_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()
private:
ObjectPtr copyFeature(ObjectPtr theObject);
- void rotateFeature(ObjectPtr theInitial, ObjectPtr theTarget,
- double theCenterX, double theCenterY, double theAngle);
+ //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
return;
DataPtr aData = data();
- std::shared_ptr<GeomDataAPI_Point2D> aStart = GeomDataAPI_Point2D::getPoint2D(aData,
- START_POINT_ID());
- std::shared_ptr<GeomDataAPI_Point2D> aEnd = GeomDataAPI_Point2D::getPoint2D(aData,
- END_POINT_ID());
+ AttributePoint2DPtr aStart = GeomDataAPI_Point2D::getPoint2D(aData, START_POINT_ID());
+ AttributePoint2DPtr aEnd = GeomDataAPI_Point2D::getPoint2D(aData, END_POINT_ID());
if (!aStart || !aEnd)
return;
}
}
-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
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
CENTER_Y = 0.
ANGLE = 30.
#=========================================================================
+# Create rotation point
+#=========================================================================
+aSession.startOperation()
+aRotationPoint = aSketchFeature.addFeature("SketchPoint")
+aRotationPointPoint = geomDataAPI_Point2D(aRotationPoint.attribute("PointCoordindates"))
+aRotationPointPoint.setValue(CENTER_X, CENTER_Y)
+aSession.finishOperation()
+#=========================================================================
# Create the Rotation constraint
#=========================================================================
aSession.startOperation()
aValueType = aMultiRotation.string("AngleType")
aValueType.setValue("SingleValue")
-aCenter = geomDataAPI_Point2D(aMultiRotation.attribute("MultiRotationCenter"))
+aCenter = aMultiRotation.refattr("MultiRotationCenter")
+aCenter.setAttr(aRotationPointPoint)
+
anAngle = aMultiRotation.real("MultiRotationAngle")
-aCenter.setValue(CENTER_X, CENTER_Y)
anAngle.setValue(ANGLE)
+
+anAngle = aMultiRotation.string("AngleType")
+anAngle.setValue("SingleAngle")
+
aNbCopies = aMultiRotation.integer("MultiRotationObjects")
-aNbCopies.setValue(1)
+aNbCopies.setValue(2)
aMultiRotation.execute()
aSession.finishOperation()
#=========================================================================
anAttributes.append('ArcStartPoint')
anAttributes.append('ArcEndPoint')
- #for attr in anAttributes:
- #aPoint1 = geomDataAPI_Point2D(feat.attribute(attr))
- #aPoint2 = geomDataAPI_Point2D(next.attribute(attr))
- #aDiffX = aPoint2.x() - aPoint1.x() - theDeltaX
- #aDiffY = aPoint2.y() - aPoint1.y() - theDeltaY
- #assert(aDiffX**2 + aDiffY**2 < 1.e-15)
+ for attr in anAttributes:
+ aPoint1 = geomDataAPI_Point2D(feat.attribute(attr))
+ aPoint2 = geomDataAPI_Point2D(next.attribute(attr))
+ aDiffX = aPoint2.x() - aPoint1.x() - theDeltaX
+ aDiffY = aPoint2.y() - aPoint1.y() - theDeltaY
+ assert(aDiffX**2 + aDiffY**2 < 1.e-15)
# Check the number of copies is as planed
assert(anInd == theNbObjects-1)
label="Start point"
tooltip="Start point of translation"
shape_types="vertex">
- <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityB"/>
<validator id="PartSet_DifferentObjects"/>
<validator id="GeomValidators_ShapeType" parameters="vertex"/>
</sketch_shape_selector>
label="End point"
tooltip="Final point of translation"
shape_types="vertex">
- <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityB"/>
<validator id="PartSet_DifferentObjects"/>
<validator id="GeomValidators_ShapeType" parameters="vertex"/>
</sketch_shape_selector>
label="Start point"
tooltip="Start point of translation"
shape_types="vertex">
- <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityB"/>
<validator id="PartSet_DifferentObjects"/>
<validator id="GeomValidators_ShapeType" parameters="vertex"/>
</sketch_shape_selector>
label="End point"
tooltip="Final point of translation"
shape_types="vertex">
- <validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityB"/>
<validator id="PartSet_DifferentObjects"/>
<validator id="GeomValidators_ShapeType" parameters="vertex"/>
</sketch_shape_selector>
use_external="true">
<validator id="SketchPlugin_CopyValidator" />
</sketch_multi_selector>
- <sketch-2dpoint_selector
- id="MultiRotationCenter"
- title="Center of rotation"
- tooltip="Center of rotation"
- default="0"/>
+ <sketch_shape_selector
+ id="MultiRotationCenter"
+ label="Center of rotation"
+ tooltip="Center of rotation"
+ shape_types="vertex">
+ <validator id="GeomValidators_ShapeType" parameters="vertex"/>
+ </sketch_shape_selector>
<toolbox id="AngleType">
<box id="SingleAngle" title="Single angle" icon=":icons/angle_up_32x32.png">
- <point2dangle id="MultiRotationAngle"
- first_point="MultiRotationCenter"
+ <doublevalue id="MultiRotationAngle"
label="Angle"
icon=":icons/angle.png"
tooltip="Rotation angle"
- default="90"/>
+ default="90" 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"
+ <doublevalue id="MultiRotationAngle"
+ label="Angle"
icon=":icons/angle.png"
- tooltip="Rotation angle"/>
+ tooltip="Rotation angle"
+ default="90" use_reset="false"/>
</box>
</toolbox>
<integervalue id="MultiRotationObjects"
const EntityID& theSketchID,
const SketchSolver_ConstraintType& theType,
const double& theValue,
+ const bool& theFullValue,
const EntityWrapperPtr& thePoint1,
const EntityWrapperPtr& thePoint2,
const std::list<EntityWrapperPtr>& theTrsfEnt) const = 0;
#include <SketchPlugin_MultiRotation.h>
+#include <ModelAPI_AttributeString.h>
+
#include <math.h>
void SketchSolver_ConstraintMultiRotation::getAttributes(
EntityWrapperPtr& theCenter, double& theAngle,
+ bool& theFullValue,
std::list< std::list<EntityWrapperPtr> >& theEntities)
{
DataPtr aData = myBaseConstraint->data();
myStorage->update(aCenterAttr, GID_OUTOFGROUP);
theCenter = myStorage->entity(aCenterAttr);
+ AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiRotation::ANGLE_TYPE());
+ theFullValue = aMethodTypeAttr->value() != "SingleAngle";
+
getEntitiesAndCopies(theEntities);
}
}
EntityWrapperPtr aRotationCenter;
+ bool isFullValue;
std::list<std::list<EntityWrapperPtr> > anEntitiesAndCopies;
- getAttributes(aRotationCenter, myAngle, anEntitiesAndCopies);
+ getAttributes(aRotationCenter, myAngle, isFullValue, anEntitiesAndCopies);
if (!myErrorMsg.empty())
return;
for (; anEntIt != anEntitiesAndCopies.end(); ++anEntIt) {
std::list<ConstraintWrapperPtr> aNewConstraints =
aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID, myType,
- myAngle, aRotationCenter, EntityWrapperPtr(), *anEntIt);
+ myAngle, isFullValue, aRotationCenter, EntityWrapperPtr(), *anEntIt);
aRotConstraints.insert(aRotConstraints.end(), aNewConstraints.begin(), aNewConstraints.end());
}
myStorage->addConstraint(myBaseConstraint, aRotConstraints);
myAngle = aValue;
// update center
- AttributePtr aCenterAttr = myBaseConstraint->attribute(SketchPlugin_MultiRotation::CENTER_ID());
- if (myStorage->update(aCenterAttr, myGroupID)) {
- myStorage->update(aCenterAttr, GID_UNKNOWN);
+ DataPtr aData = myBaseConstraint->data();
+ AttributePoint2DPtr aCenterPointAttribute = GeomDataAPI_Point2D::getPoint2D(aData,
+ SketchPlugin_MultiRotation::CENTER_ID());
+ bool aCenterPointChanged = aCenterPointAttribute != myCenterPointAttribute;
+ if (aCenterPointChanged)
+ myCenterPointAttribute = aCenterPointAttribute;
+
+ AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiRotation::ANGLE_TYPE());
+ bool aFullValue = aMethodTypeAttr->value() != "SingleAngle";
+ bool isMethodChanged = aFullValue != myIsFullValue;
+ if (isMethodChanged)
+ myIsFullValue = aFullValue;
+
+ if (aCenterPointChanged || isMethodChanged) {
+ DataPtr aData = myBaseConstraint->data();
+ std::list<ConstraintWrapperPtr> aConstraints = myStorage->constraint(myBaseConstraint);
+ std::list<ConstraintWrapperPtr>::const_iterator anIt = aConstraints.begin(),
+ aLast = aConstraints.end();
+ std::list<EntityWrapperPtr> anEntities;
+ for (; anIt != aLast; anIt++) {
+ ConstraintWrapperPtr aConstraint = *anIt;
+ aConstraint->setIsFullValue(myIsFullValue);
+ if (aCenterPointChanged) {
+ anEntities.clear();
+ const std::list<EntityWrapperPtr>& aConstraintEntities = aConstraint->entities();
+ std::list<EntityWrapperPtr>::const_iterator aSIt = aConstraintEntities.begin(),
+ aSLast = aConstraintEntities.end();
+ EntityWrapperPtr aCenterPointEntity = *aSIt++;
+ if (aCenterPointChanged) {
+ AttributePtr aCenterPointAttr = aData->attribute(SketchPlugin_MultiRotation::CENTER_ID());
+ myStorage->update(aCenterPointAttr);
+ aCenterPointEntity = myStorage->entity(aCenterPointAttr);
+ }
+ anEntities.push_back(aCenterPointEntity);
+
+ for (; aSIt != aSLast; ++aSIt)
+ anEntities.push_back(*aSIt);
+
+ aConstraint->setEntities(anEntities);
+ }
+ }
+ myStorage->addConstraint(myBaseConstraint, aConstraints);
+
myAdjusted = false;
}
}
#include "SketchSolver.h"
#include <SketchSolver_ConstraintMulti.h>
+#include "GeomDataAPI_Point2D.h"
+
/** \class SketchSolver_ConstraintMultiRotation
* \ingroup Plugins
* \brief Convert rotated features to the list of SolveSpace constraints
/// \brief Generate list of rotated entities
/// \param[out] theCenter central point of rotation
/// \param[out] theAngle rotation angle
+ /// \param[out] theFullValue applying translation using the disstance as a full or single value
/// \param[out] theEntities list of entities and their rotated copies
- void getAttributes(EntityWrapperPtr& theCenter, double& theAngle,
+ void getAttributes(EntityWrapperPtr& theCenter, double& theAngle, bool& theFullValue,
std::list< std::list<EntityWrapperPtr> >& theEntities);
/// \brief This method is used in derived objects to check consistence of constraint.
private:
/// \brief Returns name of NUMBER_OF_COPIES parameter for corresponding feature
virtual const std::string& nameNbObjects();
- double myAngle; ///< angle of rotation
+
+ AttributePoint2DPtr myCenterPointAttribute; ///< a center of rotation
+ double myAngle; ///< angle of rotation
+ bool myIsFullValue; ///< value whether the angle is a full or single for objects
};
#endif
void SketchSolver_ConstraintMultiTranslation::getAttributes(
EntityWrapperPtr& theStartPoint, EntityWrapperPtr& theEndPoint,
- std::list< std::list<EntityWrapperPtr> >& theEntities)
+ bool& theFullValue, std::list< std::list<EntityWrapperPtr> >& theEntities)
{
DataPtr aData = myBaseConstraint->data();
AttributePtr aStartPointAttr = aData->attribute(SketchPlugin_MultiTranslation::START_POINT_ID());
myStorage->update(aEndPointAttr);
theEndPoint = myStorage->entity(aEndPointAttr);
- getEntitiesAndCopies(theEntities);
+ AttributeStringPtr aMethodTypeAttr = aData->string(SketchPlugin_MultiTranslation::VALUE_TYPE());
+ theFullValue = aMethodTypeAttr->value() != "SingleValue";
+ getEntitiesAndCopies(theEntities);
}
void SketchSolver_ConstraintMultiTranslation::process()
}
EntityWrapperPtr aStartPoint, aEndPoint;
+ bool aFullValue;
std::list<std::list<EntityWrapperPtr> > anEntitiesAndCopies;
- getAttributes(aStartPoint, aEndPoint, anEntitiesAndCopies);
+ getAttributes(aStartPoint, aEndPoint, aFullValue, anEntitiesAndCopies);
if (!myErrorMsg.empty())
return;
+ AttributeStringPtr aMethodTypeAttr =
+ myBaseConstraint->data()->string(SketchPlugin_MultiTranslation::VALUE_TYPE());
+
BuilderPtr aBuilder = SketchSolver_Manager::instance()->builder();
std::list<ConstraintWrapperPtr> aTransConstraints;
for (; anEntIt != anEntitiesAndCopies.end(); ++anEntIt) {
std::list<ConstraintWrapperPtr> aNewConstraints =
aBuilder->createConstraint(myBaseConstraint, myGroupID, mySketchID, myType,
- 0.0, aStartPoint, aEndPoint, *anEntIt);
+ 0.0, aFullValue, aStartPoint, aEndPoint, *anEntIt);
aTransConstraints.insert(aTransConstraints.end(), aNewConstraints.begin(), aNewConstraints.end());
}
+
myStorage->addConstraint(myBaseConstraint, aTransConstraints);
myAdjusted = false;
/// \brief Generate list of translated entities
/// \param[out] theStartPoint start point of translation
/// \param[out] theEndPoint final point of translation
+ /// \param[out] theFullValue applying translation using the disstance as a full or single value
/// \param[out] theEntities list of entities and their translated copies
void getAttributes(EntityWrapperPtr& theStartPoint, EntityWrapperPtr& theEndPoint,
- std::list< std::list<EntityWrapperPtr> >& theEntities);
+ bool& theFullValue, std::list< std::list<EntityWrapperPtr> >& theEntities);
/// \brief Update parameters (called from base class)
virtual void updateLocal();
mySketchSolver->setGroup(myID);
mySketchSolver->calculateFailedConstraints(false);
myStorage->initializeSolver(mySketchSolver);
+ mySketchSolver->prepare();
SketchSolver_SolveStatus aResult = STATUS_OK;
try {
sendMessage(EVENT_SOLVER_FAILED);
myPrevSolved = false;
}
+ mySketchSolver->undo();
return false;
}
if (aResult == STATUS_OK || aResult == STATUS_EMPTYSET) { // solution succeeded, store results into correspondent attributes
sendMessage(EVENT_SOLVER_REPAIRED);
myPrevSolved = true;
}
- } else if (!myConstraints.empty()) {
+ } else {
+ mySketchSolver->undo();
+ if (!myConstraints.empty()) {
// Events_Error::send(SketchSolver_Error::CONSTRAINTS(), this);
- getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(SketchSolver_Error::CONSTRAINTS());
- if (myPrevSolved) {
- // the error message should be changed before sending the message
- sendMessage(EVENT_SOLVER_FAILED);
- myPrevSolved = false;
+ getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(SketchSolver_Error::CONSTRAINTS());
+ if (myPrevSolved) {
+ // the error message should be changed before sending the message
+ sendMessage(EVENT_SOLVER_FAILED);
+ myPrevSolved = false;
+ }
}
}
void calculateFailedConstraints(bool theSic)
{ myFindFaileds = theSic; }
+ /// \brief Prepare for solving. Store initial values of parameters for undo
+ virtual void prepare() = 0;
+
/// \brief Solve the set of equations
/// \return identifier whether solution succeeded
virtual SketchSolver_SolveStatus solve() = 0;
+ /// \brief Revert solution to initial values
+ virtual void undo() = 0;
+
protected:
GroupID myGroup; ///< ID of the group to be solved
bool myFindFaileds; ///< flag to find conflicting or inappropriate constraints
(theSolverEntity && !aFound->second->isEqual(theSolverEntity)))
setNeedToResolve(true); // the entity is new or modified
+ if (!theSolverEntity) {
+ // feature links to the empty entity, add its attributes
+ std::list<AttributePtr> aPntAttrs =
+ theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
+ std::list<AttributePtr>::const_iterator anAttrIt = aPntAttrs.begin();
+ for (; anAttrIt != aPntAttrs.end(); ++anAttrIt)
+ addEntity(*anAttrIt, EntityWrapperPtr());
+ }
+
myFeatureMap[theFeature] = theSolverEntity;
// block events if necessary
if (myEventsBlocked && theFeature->data() && theFeature->data()->isValid())
const EntityID& theSketchID,
const SketchSolver_ConstraintType& theType,
const double& theValue,
+ const bool& theFullValue,
const EntityWrapperPtr& thePoint1,
const EntityWrapperPtr& thePoint2,
const std::list<EntityWrapperPtr>& theTrsfEnt) const
ConstraintWrapperPtr aResult(new SolveSpaceSolver_ConstraintWrapper(theConstraint, aConstraint));
aResult->setValue(theValue);
+ aResult->setIsFullValue(theFullValue);
aResult->setEntities(aConstrAttrList);
return std::list<ConstraintWrapperPtr>(1, aResult);
}
{
BuilderPtr aBuilder = SolveSpaceSolver_Builder::getInstance();
- double anAngleRad = theConstraint->value() * PI / 180.0;
+ double anAngleValue = theConstraint->value();
+ const std::list<EntityWrapperPtr>& aSubs = theConstraint->entities();
+
+ bool isFullValue = theConstraint->isFullValue();
+ int aNbObjects = aSubs.size()-2;
+ if (isFullValue && aNbObjects > 0) {
+ anAngleValue /= aNbObjects;
+ }
+
+ double anAngleRad = anAngleValue * PI / 180.0;
double aSin = sin(anAngleRad);
double aCos = cos(anAngleRad);
- const std::list<EntityWrapperPtr>& aSubs = theConstraint->entities();
std::list<EntityWrapperPtr>::const_iterator aSIt = aSubs.begin();
std::shared_ptr<GeomAPI_Pnt2d> aCenter = aBuilder->point(*aSIt++);
const EntityID& theSketchID,
const SketchSolver_ConstraintType& theType,
const double& theValue,
+ const bool& theFullValue,
const EntityWrapperPtr& thePoint1,
const EntityWrapperPtr& thePoint2,
const std::list<EntityWrapperPtr>& theTrsfEnt) const;
// If the set of constraints is inconsistent,
// the failed field will contain wrong constraints
myEquationsSystem.calculateFaileds = 0;
+
+ myParamsCopy = 0;
}
SolveSpaceSolver_Solver::~SolveSpaceSolver_Solver()
if (myEquationsSystem.failed)
delete[] myEquationsSystem.failed;
myEquationsSystem.failed = 0;
+ if (myParamsCopy)
+ delete [] myParamsCopy;
+ myParamsCopy = 0;
}
void SolveSpaceSolver_Solver::setParameters(Slvs_Param* theParameters, int theSize)
default:
aStatus = STATUS_FAILED;
}
+
+ if (aStatus == STATUS_OK) {
+ // additional verification of arcs to be non-degenerated
+ if (hasDegeneratedArcs()) {
+ undo();
+ aStatus = STATUS_INCONSISTENT;
+ }
+ }
+
return aStatus;
}
+
+void SolveSpaceSolver_Solver::prepare()
+{
+ // make a copy of parameters to be able to make undo
+ if (myParamsCopy)
+ delete [] myParamsCopy;
+ myParamsCopy = new Slvs_Param[myEquationsSystem.params];
+ memcpy(myParamsCopy, myEquationsSystem.param, myEquationsSystem.params * sizeof(Slvs_Param));
+}
+
+void SolveSpaceSolver_Solver::undo()
+{
+ if (myParamsCopy) {
+ memcpy(myEquationsSystem.param, myParamsCopy, myEquationsSystem.params * sizeof(Slvs_Param));
+ delete [] myParamsCopy;
+ }
+ myParamsCopy = 0;
+}
+
+
+bool SolveSpaceSolver_Solver::hasDegeneratedArcs() const
+{
+ const double aTol2 = tolerance * tolerance;
+ double anArcPoints[3][2];
+
+ for (int anEnt = 0; anEnt < myEquationsSystem.entities; ++anEnt) {
+ const Slvs_Entity& anEntity = myEquationsSystem.entity[anEnt];
+ if (anEntity.type != SLVS_E_ARC_OF_CIRCLE)
+ continue;
+
+ for (int aPnt = 0; aPnt < 3; ++aPnt) {
+ // search point of arc
+ const int aShift = anEntity.point[aPnt] - anEntity.h;
+ int aPntInd = anEnt + aShift;
+ int aStep = 1;
+ if (myEquationsSystem.entity[aPntInd].h > anEntity.point[aPnt])
+ aStep = -1;
+ for (; aPntInd >=0 && aPntInd < myEquationsSystem.entities; aPntInd += aStep)
+ if (myEquationsSystem.entity[aPntInd].h == anEntity.point[aPnt])
+ break;
+
+ // search coordinates of the point
+ int aParamInd = myEquationsSystem.entity[aPntInd].param[0];
+ if (aParamInd >= myEquationsSystem.params) {
+ aParamInd = myEquationsSystem.params - 1;
+ aStep = -1;
+ }
+ else if ((int)myEquationsSystem.param[aParamInd].h > aParamInd)
+ aStep = -1;
+ else aStep = 1;
+
+ for (; aParamInd >=0 && aParamInd < myEquationsSystem.params; aParamInd += aStep)
+ if (myEquationsSystem.param[aParamInd].h == myEquationsSystem.entity[aPntInd].param[0])
+ break;
+ anArcPoints[aPnt][0] = myEquationsSystem.param[aParamInd].val;
+ anArcPoints[aPnt][1] = myEquationsSystem.param[aParamInd+1].val;
+ }
+
+ // check radius of arc
+ anArcPoints[1][0] -= anArcPoints[0][0];
+ anArcPoints[1][1] -= anArcPoints[0][1];
+ anArcPoints[2][0] -= anArcPoints[0][0];
+ anArcPoints[2][1] -= anArcPoints[0][1];
+ if (anArcPoints[1][0] * anArcPoints[1][0] + anArcPoints[1][1] * anArcPoints[1][1] < aTol2 ||
+ anArcPoints[2][0] * anArcPoints[2][0] + anArcPoints[2][1] * anArcPoints[2][1] < aTol2)
+ return true;
+ }
+ return false;
+}
*/
virtual SketchSolver_SolveStatus solve();
- private:
+ /// \brief Prepare for solving. Store initial values of parameters for undo
+ virtual void prepare();
+
+ /// \brief Revert solution to initial values
+ virtual void undo();
+
+private:
+ /// \brief Check whether degenerated arcs exist
+ bool hasDegeneratedArcs() const;
+
+private:
Slvs_System myEquationsSystem; ///< set of equations for solving in SolveSpace
+ Slvs_Param* myParamsCopy; ///< copy of parameters
};
#endif
for (; anIt != anEntities.end(); ++anIt) {
isUpdated = update(*anIt) || isUpdated;
// do not update constrained entities for Multi constraints
- if (aSlvsConstr.type == SLVS_C_MULTI_ROTATION || aSlvsConstr.type != SLVS_C_MULTI_TRANSLATION)
+ if (aSlvsConstr.type == SLVS_C_MULTI_ROTATION || aSlvsConstr.type == SLVS_C_MULTI_TRANSLATION)
continue;
Slvs_hEntity anID = (Slvs_hEntity)(*anIt)->id();
aSlvsEnt.distance = anID;
else if (aSlvsEnt.point[anInd] != anID) {
aSlvsEnt.point[anInd] = anID;
+ if ((*aSIt)->baseAttribute())
+ SketchSolver_Storage::addEntity((*aSIt)->baseAttribute(), *aSIt);
isUpdated = true;
}
}
Config
ModelAPI
GeomAPI
+ GeomDataAPI
Events
${CAS_KERNEL}
${CAS_MODELER}
drawListOfShapes(anAttrB, thePrs);
if (myConstraint->getKind() == SketchPlugin_MultiTranslation::ID()) {
// If it is translation
- std::shared_ptr<GeomDataAPI_Point2D> aStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aData->attribute(SketchPlugin_MultiTranslation::START_POINT_ID()));
- std::shared_ptr<GeomDataAPI_Point2D> aEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aData->attribute(SketchPlugin_MultiTranslation::END_POINT_ID()));
-
+ AttributePoint2DPtr aStart = GeomDataAPI_Point2D::getPoint2D(aData,
+ SketchPlugin_MultiTranslation::START_POINT_ID());
+ AttributePoint2DPtr aEnd = GeomDataAPI_Point2D::getPoint2D(aData,
+ SketchPlugin_MultiTranslation::END_POINT_ID());
+
if (aStart.get() && aEnd.get() && aStart->isInitialized() && aEnd->isInitialized()) {
// Add start point
std::shared_ptr<GeomAPI_Pnt> aPnt = myPlane->to3D(aStart->x(), aStart->y());
}
} else if (myConstraint->getKind() == SketchPlugin_MultiRotation::ID()) {
// if it is rotation
- std::shared_ptr<GeomDataAPI_Point2D> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- aData->attribute(SketchPlugin_MultiRotation::CENTER_ID()));
+ AttributePoint2DPtr aCenter = GeomDataAPI_Point2D::getPoint2D(aData, SketchPlugin_MultiRotation::CENTER_ID());
if (aCenter.get() && aCenter->isInitialized()) {
// Show center of rotation
std::shared_ptr<GeomAPI_Pnt> aPnt = myPlane->to3D(aCenter->x(), aCenter->y());