From 3b6096ebecf1bf2300555a2f76592950b8c9e7b8 Mon Sep 17 00:00:00 2001 From: azv Date: Wed, 18 Mar 2015 07:12:43 +0300 Subject: [PATCH] Implemented feature for constraint Mirror --- src/SketchPlugin/CMakeLists.txt | 2 + .../SketchPlugin_ConstraintMirror.cpp | 112 ++++++++++++++++ .../SketchPlugin_ConstraintMirror.h | 54 ++++++++ src/SketchPlugin/SketchPlugin_Plugin.cpp | 4 + src/SketchPlugin/Test/TestConstraintMirror.py | 126 ++++++++++++++++++ src/SketchPlugin/plugin-Sketch.xml | 6 + 6 files changed, 304 insertions(+) create mode 100644 src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp create mode 100644 src/SketchPlugin/SketchPlugin_ConstraintMirror.h create mode 100644 src/SketchPlugin/Test/TestConstraintMirror.py diff --git a/src/SketchPlugin/CMakeLists.txt b/src/SketchPlugin/CMakeLists.txt index e2fc76829..b8e644cc6 100644 --- a/src/SketchPlugin/CMakeLists.txt +++ b/src/SketchPlugin/CMakeLists.txt @@ -26,6 +26,7 @@ SET(PROJECT_HEADERS SketchPlugin_ConstraintVertical.h SketchPlugin_ConstraintEqual.h SketchPlugin_ConstraintTangent.h + SketchPlugin_ConstraintMirror.h SketchPlugin_ShapeValidator.h SketchPlugin_Validators.h SketchPlugin_ResultValidators.h @@ -52,6 +53,7 @@ SET(PROJECT_SOURCES SketchPlugin_ConstraintVertical.cpp SketchPlugin_ConstraintEqual.cpp SketchPlugin_ConstraintTangent.cpp + SketchPlugin_ConstraintMirror.cpp SketchPlugin_ShapeValidator.cpp SketchPlugin_Validators.cpp SketchPlugin_ResultValidators.cpp diff --git a/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp b/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp new file mode 100644 index 000000000..633eed69e --- /dev/null +++ b/src/SketchPlugin/SketchPlugin_ConstraintMirror.cpp @@ -0,0 +1,112 @@ +// 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 +#include +#include +#include +#include + +#include +#include + +#include + +#include + +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 aData = data(); + AttributeRefListPtr aRefListOfShapes = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Constraint::ENTITY_B())); + if (!aRefListOfShapes->isInitialized()) + return ; + + AttributeRefListPtr aRefListOfMirrored = std::dynamic_pointer_cast( + aData->attribute(SketchPlugin_Constraint::ENTITY_C())); + // Check consistency of initial list and mirrored list + std::list anInitialList = aRefListOfShapes->list(); + std::list aMirroredList = aRefListOfMirrored->list(); + std::list::iterator anInitIter = anInitialList.begin(); + std::list::iterator aMirrorIter = aMirroredList.begin(); + int indFirstWrong = 0; // index of element starts difference in the lists + std::set anInvalidInd; // list of indices of removed features + std::shared_ptr aFeatureIn, aFeatureOut; + for ( ; anInitIter != anInitialList.end(); anInitIter++, indFirstWrong++) { + // Add features and store indices of objects to remove + aFeatureIn = std::dynamic_pointer_cast(*anInitIter); + aFeatureOut = aMirrorIter != aMirroredList.end() ? + std::dynamic_pointer_cast(*aMirrorIter) : + std::shared_ptr(); + 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::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(*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; +} + + diff --git a/src/SketchPlugin/SketchPlugin_ConstraintMirror.h b/src/SketchPlugin/SketchPlugin_ConstraintMirror.h new file mode 100644 index 000000000..841f11abd --- /dev/null +++ b/src/SketchPlugin/SketchPlugin_ConstraintMirror.h @@ -0,0 +1,54 @@ +// 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 +#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 diff --git a/src/SketchPlugin/SketchPlugin_Plugin.cpp b/src/SketchPlugin/SketchPlugin_Plugin.cpp index fd9b04f8a..fbf1235ce 100644 --- a/src/SketchPlugin/SketchPlugin_Plugin.cpp +++ b/src/SketchPlugin/SketchPlugin_Plugin.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -121,6 +122,8 @@ FeaturePtr SketchPlugin_Plugin::createFeature(string theFeatureID) 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(); @@ -169,6 +172,7 @@ std::shared_ptr SketchPlugin_Plugin 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; diff --git a/src/SketchPlugin/Test/TestConstraintMirror.py b/src/SketchPlugin/Test/TestConstraintMirror.py new file mode 100644 index 000000000..de1c0870e --- /dev/null +++ b/src/SketchPlugin/Test/TestConstraintMirror.py @@ -0,0 +1,126 @@ +""" + 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 +#========================================================================= diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 3bbfbfead..b4a7ab35b 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -183,6 +183,12 @@ label="Last object" tooltip="Select line or arc" shape_types="edge"> + + -- 2.39.2