SketchPlugin_ConstraintVertical.h
SketchPlugin_ConstraintEqual.h
SketchPlugin_ConstraintTangent.h
+ SketchPlugin_ConstraintMirror.h
SketchPlugin_ShapeValidator.h
SketchPlugin_Validators.h
SketchPlugin_ResultValidators.h
SketchPlugin_ConstraintVertical.cpp
SketchPlugin_ConstraintEqual.cpp
SketchPlugin_ConstraintTangent.cpp
+ SketchPlugin_ConstraintMirror.cpp
SketchPlugin_ShapeValidator.cpp
SketchPlugin_Validators.cpp
SketchPlugin_ResultValidators.cpp
--- /dev/null
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: SketchPlugin_ConstraintMirror.cpp
+// Created: 17 Mar 2015
+// Author: Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintMirror.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_Session.h>
+
+#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Sketch.h>
+
+#include <SketcherPrs_Factory.h>
+
+#include <Config_PropManager.h>
+
+SketchPlugin_ConstraintMirror::SketchPlugin_ConstraintMirror()
+{
+}
+
+void SketchPlugin_ConstraintMirror::initAttributes()
+{
+ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
+ data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::type());
+ data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::type());
+}
+
+void SketchPlugin_ConstraintMirror::execute()
+{
+ // Objects to be mirrored will be created here
+ std::shared_ptr<ModelAPI_Data> aData = data();
+ AttributeRefListPtr aRefListOfShapes = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+ aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ if (!aRefListOfShapes->isInitialized())
+ return ;
+
+ AttributeRefListPtr aRefListOfMirrored = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+ aData->attribute(SketchPlugin_Constraint::ENTITY_C()));
+ // Check consistency of initial list and mirrored list
+ std::list<ObjectPtr> anInitialList = aRefListOfShapes->list();
+ std::list<ObjectPtr> aMirroredList = aRefListOfMirrored->list();
+ std::list<ObjectPtr>::iterator anInitIter = anInitialList.begin();
+ std::list<ObjectPtr>::iterator aMirrorIter = aMirroredList.begin();
+ int indFirstWrong = 0; // index of element starts difference in the lists
+ std::set<int> anInvalidInd; // list of indices of removed features
+ std::shared_ptr<SketchPlugin_Feature> aFeatureIn, aFeatureOut;
+ for ( ; anInitIter != anInitialList.end(); anInitIter++, indFirstWrong++) {
+ // Add features and store indices of objects to remove
+ aFeatureIn = std::dynamic_pointer_cast<SketchPlugin_Feature>(*anInitIter);
+ aFeatureOut = aMirrorIter != aMirroredList.end() ?
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(*aMirrorIter) :
+ std::shared_ptr<SketchPlugin_Feature>();
+ if (!aFeatureIn) {
+ if (aFeatureOut)
+ break; // the lists are inconsistent
+ continue;
+ }
+ if (!aFeatureOut) {
+ if (aMirrorIter != aMirroredList.end())
+ break; // the lists are inconsistent
+ // There is no mirrored object yet, create it
+ FeaturePtr aNewFeature = aFeatureIn->document()->addFeature(aFeatureIn->getKind());
+ aRefListOfMirrored->append(aNewFeature);
+ continue;
+ }
+ if (aFeatureIn->getKind() != aFeatureOut->getKind())
+ break; // the lists are inconsistent
+ if (!aFeatureIn->data()->isValid()) {
+ // initial feature was removed, delete it from lists
+ anInvalidInd.insert(indFirstWrong);
+ }
+ aMirrorIter++;
+ }
+ // Remove from the list objects already deleted before
+ std::set<int>::reverse_iterator anIt = anInvalidInd.rbegin();
+ for ( ; anIt != anInvalidInd.rend(); anIt++) {
+ if (*anIt < indFirstWrong) indFirstWrong--;
+ aRefListOfShapes->remove(aRefListOfShapes->object(*anIt));
+ aRefListOfMirrored->remove(aRefListOfMirrored->object(*anIt));
+ }
+ // If the lists inconsistent, remove all objects from mirrored list starting from indFirstWrong
+ if (anInitIter != anInitialList.end()) {
+ while (aRefListOfMirrored->size() > indFirstWrong)
+ aRefListOfMirrored->remove(aRefListOfMirrored->object(indFirstWrong));
+ // Create mirrored features instead of removed
+ anInitialList = aRefListOfShapes->list();
+ anInitIter = anInitialList.begin();
+ for (int i = 0; i < indFirstWrong; i++) anInitIter++;
+ for ( ; anInitIter != anInitialList.end(); anInitIter++) {
+ aFeatureIn = std::dynamic_pointer_cast<SketchPlugin_Feature>(*anInitIter);
+ FeaturePtr aNewFeature = aFeatureIn->document()->addFeature(aFeatureIn->getKind());
+ aRefListOfMirrored->append(aNewFeature);
+ }
+ }
+}
+
+AISObjectPtr SketchPlugin_ConstraintMirror::getAISObject(AISObjectPtr thePrevious)
+{
+ if (!sketch())
+ return thePrevious;
+
+ AISObjectPtr anAIS = thePrevious;
+ /// TODO: Equal constraint presentation should be put here
+ return anAIS;
+}
+
+
--- /dev/null
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: SketchPlugin_ConstraintMirror.h
+// Created: 17 Mar 2015
+// Author: Artem ZHIDKOV
+
+#ifndef SketchPlugin_ConstraintMirror_H_
+#define SketchPlugin_ConstraintMirror_H_
+
+#include "SketchPlugin.h"
+#include <SketchPlugin_Sketch.h>
+#include "SketchPlugin_ConstraintBase.h"
+
+/** \class SketchPlugin_ConstraintMirror
+ * \ingroup Plugins
+ * \brief Feature for creation of a new constraint mirroring a list of objects regarding to a given line
+ *
+ * This constraint has two attributes:
+ * SketchPlugin_Constraint::ENTITY_A() for mirror line and
+ * SketchPlugin_Constraint::ENTITY_B() for the list of objects
+ *
+ * Also the constraint has attribute SketchPlugin_Constraint::ENTITY_C()
+ * which contains list of mirrored objects
+ */
+class SketchPlugin_ConstraintMirror : public SketchPlugin_ConstraintBase
+{
+ public:
+ /// Mirror constraint kind
+ inline static const std::string& ID()
+ {
+ static const std::string MY_CONSTRAINT_MIRROR_ID("SketchConstraintMirror");
+ return MY_CONSTRAINT_MIRROR_ID;
+ }
+ /// \brief Returns the kind of a feature
+ SKETCHPLUGIN_EXPORT virtual const std::string& getKind()
+ {
+ static std::string MY_KIND = SketchPlugin_ConstraintMirror::ID();
+ return MY_KIND;
+ }
+
+ /// \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();
+
+ /// Returns the AIS preview
+ SKETCHPLUGIN_EXPORT virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious);
+
+ /// \brief Use plugin manager for features creation
+ SketchPlugin_ConstraintMirror();
+};
+
+#endif
#include <SketchPlugin_ConstraintEqual.h>
#include <SketchPlugin_ConstraintHorizontal.h>
#include <SketchPlugin_ConstraintLength.h>
+#include <SketchPlugin_ConstraintMirror.h>
#include <SketchPlugin_ConstraintParallel.h>
#include <SketchPlugin_ConstraintPerpendicular.h>
#include <SketchPlugin_ConstraintRadius.h>
return FeaturePtr(new SketchPlugin_ConstraintEqual);
} else if (theFeatureID == SketchPlugin_ConstraintTangent::ID()) {
return FeaturePtr(new SketchPlugin_ConstraintTangent);
+ } else if (theFeatureID == SketchPlugin_ConstraintMirror::ID()) {
+ return FeaturePtr(new SketchPlugin_ConstraintMirror);
}
// feature of such kind is not found
return FeaturePtr();
aMsg->setState(SketchPlugin_ConstraintVertical::ID(), aHasSketchPlane);
aMsg->setState(SketchPlugin_ConstraintEqual::ID(), aHasSketchPlane);
aMsg->setState(SketchPlugin_ConstraintTangent::ID(), aHasSketchPlane);
+ aMsg->setState(SketchPlugin_ConstraintMirror::ID(), aHasSketchPlane);
}
}
return aMsg;
--- /dev/null
+"""
+ TestConstraintMirror.py
+ Unit test of SketchPlugin_ConstraintMirror class
+
+ SketchPlugin_ConstraintMirror
+ static const std::string MY_CONSTRAINT_MIRROR_ID("SketchConstraintMirror");
+ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
+ data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefListAttr::type());
+ data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefListAttr::type());
+
+"""
+from GeomDataAPI import *
+from ModelAPI import *
+import math
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+__updated__ = "2015-03-17"
+
+aSession = ModelAPI_Session.get()
+aDocument = aSession.moduleDocument()
+#=========================================================================
+# Creation of a sketch
+#=========================================================================
+aSession.startOperation()
+aSketchCommonFeature = aDocument.addFeature("Sketch")
+aSketchFeature = modelAPI_CompositeFeature(aSketchCommonFeature)
+origin = geomDataAPI_Point(aSketchFeature.attribute("Origin"))
+origin.setValue(0, 0, 0)
+dirx = geomDataAPI_Dir(aSketchFeature.attribute("DirX"))
+dirx.setValue(1, 0, 0)
+diry = geomDataAPI_Dir(aSketchFeature.attribute("DirY"))
+diry.setValue(0, 1, 0)
+norm = geomDataAPI_Dir(aSketchFeature.attribute("Norm"))
+norm.setValue(0, 0, 1)
+aSession.finishOperation()
+#=========================================================================
+# Creation of an arc and two lines
+#=========================================================================
+# Arc
+aSession.startOperation()
+aSketchArc1 = aSketchFeature.addFeature("SketchArc")
+anArcCentr = geomDataAPI_Point2D(aSketchArc1.attribute("ArcCenter"))
+anArcCentr.setValue(10., 10.)
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcStartPoint"))
+anArcStartPoint.setValue(0., 50.)
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcEndPoint"))
+anArcEndPoint.setValue(50., 0.)
+aSession.finishOperation()
+# Line 1
+aSession.startOperation()
+aSketchLine1 = aSketchFeature.addFeature("SketchLine")
+aLine1StartPoint = geomDataAPI_Point2D(aSketchLine1.attribute("StartPoint"))
+aLine1EndPoint = geomDataAPI_Point2D(aSketchLine1.attribute("EndPoint"))
+aLine1StartPoint.setValue(0., 50.)
+aLine1EndPoint.setValue(0., 100.)
+aSession.finishOperation()
+# Line 2
+aSession.startOperation()
+aSketchLine2 = aSketchFeature.addFeature("SketchLine")
+aLine2StartPoint = geomDataAPI_Point2D(aSketchLine2.attribute("StartPoint"))
+aLine2EndPoint = geomDataAPI_Point2D(aSketchLine2.attribute("EndPoint"))
+aLine2StartPoint.setValue(50., 0.)
+aLine2EndPoint.setValue(100., 0.)
+aSession.finishOperation()
+#=========================================================================
+# Link arc points and lines points by the coincidence constraint
+#=========================================================================
+aSession.startOperation()
+aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
+reflistA = aConstraint.refattr("ConstraintEntityA")
+reflistB = aConstraint.refattr("ConstraintEntityB")
+reflistA.setAttr(anArcStartPoint)
+reflistB.setAttr(aLine1StartPoint)
+aConstraint.execute()
+aSession.finishOperation()
+aSession.startOperation()
+aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
+reflistA = aConstraint.refattr("ConstraintEntityA")
+reflistB = aConstraint.refattr("ConstraintEntityB")
+reflistA.setAttr(anArcEndPoint)
+reflistB.setAttr(aLine2StartPoint)
+aConstraint.execute()
+aSession.finishOperation()
+#=========================================================================
+# Add tangency constraint and check correctness
+#=========================================================================
+aSession.startOperation()
+aTangency = aSketchFeature.addFeature("SketchConstraintTangent")
+aRefObjectA = aTangency.refattr("ConstraintEntityA")
+aRefObjectB = aTangency.refattr("ConstraintEntityB")
+anObjectA = modelAPI_ResultConstruction(aSketchArc1.lastResult())
+anObjectB = modelAPI_ResultConstruction(aSketchLine1.firstResult())
+assert (anObjectA is not None)
+assert (anObjectB is not None)
+aRefObjectA.setObject(anObjectA)
+aRefObjectB.setObject(anObjectB)
+aTangency.execute()
+aSession.finishOperation()
+#=========================================================================
+# Create mirror line
+#=========================================================================
+aSession.startOperation()
+aMirrorLine = aSketchFeature.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aMirrorLine.attribute("StartPoint"))
+aLineEndPoint = geomDataAPI_Point2D(aMirrorLine.attribute("EndPoint"))
+aLineStartPoint.setValue(100., 0.)
+aLineEndPoint.setValue(100., 100.)
+aSession.finishOperation()
+#=========================================================================
+# Make mirror for objects created above
+#=========================================================================
+aSession.startOperation()
+aMirror = aSketchFeature.addFeature("SketchConstraintMirror")
+aRefObjectA = aMirror.refattr("ConstraintEntityA")
+aRefObjectA.setObject(modelAPI_ResultConstruction(aMirrorLine.firstResult()))
+aRefListB = aMirror.reflist("ConstraintEntityB")
+aRefListB.append(aSketchArc1)
+aRefListB.append(aSketchLine1)
+aRefListB.append(aSketchLine2)
+aMirror.execute()
+aSession.finishOperation()
+#=========================================================================
+# End of test
+#=========================================================================
label="Last object" tooltip="Select line or arc" shape_types="edge">
</sketch_constraint_shape_selector>
</feature>
+ <!-- SketchConstraintMirror -->
+ <feature
+ id="SketchConstraintMirror"
+ title="Mirror"
+ tooltip="Create constraint mirroring group of objects"
+ internal="1" />
</group>
</workbench>
</plugin>