#include <memory>
// the only created instance of this plugin
-static InitializationPlugin_Plugin* MY_INITIALIZATIONPLUGIN_INSTANCE = new InitializationPlugin_Plugin();
+static InitializationPlugin_Plugin* MY_INITIALIZATIONPLUGIN_INSTANCE =
+ new InitializationPlugin_Plugin();
InitializationPlugin_Plugin::InitializationPlugin_Plugin()
{
{
const Events_ID kDocCreatedEvent = ModelAPI_DocumentCreatedMessage::eventId();
if (theMessage->eventID() == kDocCreatedEvent) {
- std::shared_ptr<ModelAPI_DocumentCreatedMessage> aMessage =
- std::dynamic_pointer_cast<ModelAPI_DocumentCreatedMessage>(theMessage);
+ std::shared_ptr<ModelAPI_DocumentCreatedMessage> aMessage = std::dynamic_pointer_cast<
+ ModelAPI_DocumentCreatedMessage>(theMessage);
DocumentPtr aDoc = aMessage->document();
createPoint(aDoc);
createPlane(aDoc, 1., 0., 0.);
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
} else if (theMessage.get()) {
Events_Error::send(
- std::string("InitializationPlugin_Plugin::processEvent: unhandled message caught: ") +
- theMessage->eventID().eventText());
+ std::string("InitializationPlugin_Plugin::processEvent: unhandled message caught: ")
+ + theMessage->eventID().eventText());
}
}
-void InitializationPlugin_Plugin::createPlane(DocumentPtr theDoc, double theA, double theB, double theC)
+void InitializationPlugin_Plugin::createPlane(DocumentPtr theDoc, double theX, double theY,
+ double theZ)
{
std::shared_ptr<ModelAPI_Feature> aPlane = theDoc->addFeature("Plane");
aPlane->string("CreationMethod")->setValue("PlaneByGeneralEquation");
- aPlane->real("A")->setValue(theA);
- aPlane->real("B")->setValue(theB);
- aPlane->real("C")->setValue(theC);
+ aPlane->real("A")->setValue(theX);
+ aPlane->real("B")->setValue(theY);
+ aPlane->real("C")->setValue(theZ);
aPlane->real("D")->setValue(0.);
- if (theA) {
+ if (theX) {
aPlane->data()->setName("Y0Z");
- } else if (theB) {
+ } else if (theY) {
aPlane->data()->setName("X0Z");
- } else if (theC) {
+ } else if (theZ) {
aPlane->data()->setName("X0Y");
}
- aPlane->setInHistory(aPlane, false); // don't show automatically created feature in the features history
+ aPlane->setInHistory(aPlane, false); // don't show automatically created feature in the features history
}
void InitializationPlugin_Plugin::createPoint(DocumentPtr theDoc)
aPoint->real("y")->setValue(0.);
aPoint->real("z")->setValue(0.);
aPoint->data()->setName("Origin");
- aPoint->setInHistory(aPoint, false); // don't show automatically created feature in the features history
+ aPoint->setInHistory(aPoint, false); // don't show automatically created feature in the features history
}
-
// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
#ifndef INITIALIZATIONPLUGIN_PLUGIN_H_
#include <Events_Loop.h>
/**\class InitializationPlugin_Plugin
- * TODO: Add documentation
+ * \ingroup Plugins
+ * This class is represents a plugin.
+ * It's aim is to fulfill the newly created documents with the "origin"
+ * construction point (0,0,0) and base planes (x0y, z0y, x0z)
*/
class INITIALIZATIONPLUGIN_EXPORT InitializationPlugin_Plugin : public Events_Listener
{
public:
+ /// Creates plug-in and registers it in the Event Loop
InitializationPlugin_Plugin();
- ~InitializationPlugin_Plugin() {}
+ /// Destructs the plugin
+ virtual ~InitializationPlugin_Plugin() {}
+ /// Process the ModelAPI_DocumentCreatedMessage to fulfill a document
+ /// from the message with origin and planes
virtual void processEvent(const std::shared_ptr<Events_Message>& theMessage);
- void createPlane(DocumentPtr theDoc, double theA, double theB, double theC);
+ protected:
+ /// Creates a plane by given parameters A, B, C
+ /// \param theDoc - document to contain a "plane" feature
+ /// \param theX - determines if X is 0 or not
+ /// \param theY - determines if Y is 0 or not
+ /// \param theZ - determines if Z is 0 or not
+ void createPlane(DocumentPtr theDoc, double theX, double theY, double theZ);
+ /// Creates the origin point in (0,0,0)
+ /// \param theDoc - document to contain a "point" feature
void createPoint(DocumentPtr theDoc);
};
#include <Events_Error.h>
#include <TDataStd_Name.hxx>
+#include <TDF_AttributeIterator.hxx>
+#include <TDF_ChildIterator.hxx>
+#include <TDF_RelocationTable.hxx>
#include <string>
}
}
}
+
+/// makes copy of all attributes on the given label and all sub-labels
+static void copyAttrs(TDF_Label theSource, TDF_Label theDestination) {
+ TDF_AttributeIterator anAttrIter(theSource);
+ for(; anAttrIter.More(); anAttrIter.Next()) {
+ Handle(TDF_Attribute) aTargetAttr;
+ if (!theDestination.FindAttribute(anAttrIter.Value()->ID(), aTargetAttr)) {
+ // create a new attribute if not yet exists in the destination
+ aTargetAttr = anAttrIter.Value()->NewEmpty();
+ theDestination.AddAttribute(aTargetAttr);
+ }
+ Handle(TDF_RelocationTable) aRelocTable = new TDF_RelocationTable(); // no relocation, empty map
+ anAttrIter.Value()->Paste(aTargetAttr, aRelocTable);
+ }
+ // copy the sub-labels content
+ TDF_ChildIterator aSubLabsIter(theSource);
+ for(; aSubLabsIter.More(); aSubLabsIter.Next()) {
+ copyAttrs(aSubLabsIter.Value(), theDestination.FindChild(aSubLabsIter.Value().Tag()));
+ }
+}
+
+void Model_Data::copyTo(std::shared_ptr<ModelAPI_Data> theTarget)
+{
+ TDF_Label aTargetRoot = std::dynamic_pointer_cast<Model_Data>(theTarget)->label();
+ copyAttrs(myLab, aTargetRoot);
+ // make initialized the initialized attributes
+ 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();
+ }
+ }
+}
MODEL_EXPORT virtual void referencesToObjects(
std::list<std::pair<std::string, std::list<ObjectPtr> > >& theRefs);
+ /// Copies all atributes content into theTarget data
+ MODEL_EXPORT virtual void copyTo(std::shared_ptr<ModelAPI_Data> theTarget);
+
private:
/// removes all information about back references
void eraseBackReferences();
/// returns all references by attributes of this data
/// \param theRefs returned list of pairs: id of referenced attribute and list of referenced objects
virtual void referencesToObjects(
- std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > >& theRefs) = 0;
+ std::list<std::pair<std::string, std::list<std::shared_ptr<ModelAPI_Object> > > >& theRefs) =0;
+
+ /// Copies all atributes content into theTarget data
+ virtual void copyTo(std::shared_ptr<ModelAPI_Data> theTarget) = 0;
+
protected:
/// Objects are created for features automatically
ModelAPI_Data();
MODELAPI_EXPORT ModelAPI_DocumentCreatedMessage(const Events_ID theID, const void* theSender = 0);
/// The virtual destructor
MODELAPI_EXPORT virtual ~ModelAPI_DocumentCreatedMessage();
-
+ /// Static. Returns EventID of the message.
MODELAPI_EXPORT static Events_ID eventId()
{
static const char * MY_DOCUMENT_CREATED_EVENT_ID("DocumentCreated");
return Events_Loop::eventByName(MY_DOCUMENT_CREATED_EVENT_ID);
}
-
+ /// Returns a document stored in the message
MODELAPI_EXPORT DocumentPtr document() const;
+ /// Sets a document to the message
MODELAPI_EXPORT void setDocument(DocumentPtr theDocument);
};
class QWidget;
/*!
- * Represent a property panel's list of ModuleBase_ModelWidgets.
+ * Represent a property panel's list of ModuleBase_ModelWidgets
+ * or other pages widgets derived from ModuleBase_PageBase.
*/
class MODULEBASE_EXPORT ModuleBase_PageBase
{
public:
+ /// Base constructor.
ModuleBase_PageBase();
+ /// Base virtual destructor.
virtual ~ModuleBase_PageBase();
+ /// Cast the page to regular QWidget
QWidget* pageWidget();
-
+ /// Adds the given ModuleBase_ModelWidget to the page
void addModelWidget(ModuleBase_ModelWidget* theWidget);
+ /// Adds the given ModuleBase_PageBase to the page
void addPageWidget(ModuleBase_PageBase* theWidget);
-
+ /// Removes all items from page's layout
void clearPage();
+ /// Passes focus from page to the first ModuleBase_ModelWidget contained on the page
bool takeFocus();
+ /// Returns list of ModuleBase_ModelWidgets contained on the page
QList<ModuleBase_ModelWidget*> modelWidgets();
+ /// Aligns top all widgets on page
void alignToTop();
protected:
+ /// Pure Virtual. Allows to derived class to lay out the widget properly;
virtual void placeModelWidget(ModuleBase_ModelWidget* theWidget) = 0;
+ /// Pure Virtual. Allows to derived class to lay out the page properly;
virtual void placePageWidget(ModuleBase_PageBase* theWidget) = 0;
+ /// Pure Virtual. Returns layout of the page.
virtual QLayout* pageLayout() = 0;
+ /// Pure Virtual. Allows to derived class to insert page stretch properly.
virtual void addPageStretch() = 0;
private:
- QList<ModuleBase_ModelWidget*> myWidgetList;
+ QList<ModuleBase_ModelWidget*> myWidgetList; ///< list of widgets contained on the page
};
*/
class MODULEBASE_EXPORT ModuleBase_PageGroupBox : public QGroupBox, public ModuleBase_PageBase
{
+ Q_OBJECT
public:
+ /// Constructs a page that looks like a QGroupBox
explicit ModuleBase_PageGroupBox(QWidget* theParent = 0);
+ /// Destructs the page
virtual ~ModuleBase_PageGroupBox();
protected:
+ /// Adds the given widget to page's layout
virtual void placeModelWidget(ModuleBase_ModelWidget* theWidget);
+ /// Adds the given page to page's layout
virtual void placePageWidget(ModuleBase_PageBase* theWidget);
+ /// Returns page's layout (QGridLayout)
virtual QLayout* pageLayout();
+ /// Adds a stretch to page's layout
virtual void addPageStretch();
private:
- QGridLayout* myMainLayout;
+ QGridLayout* myMainLayout; ///< page's layout
};
#endif /* MODULEBASE_PAGEGROUPBOX_H_ */
*/
class MODULEBASE_EXPORT ModuleBase_PageWidget : public QFrame, public ModuleBase_PageBase
{
+ Q_OBJECT
public:
+ /// Constructs a page that looks like a QFrame
explicit ModuleBase_PageWidget(QWidget* theParent = 0);
+ /// Destructs the page
virtual ~ModuleBase_PageWidget();
protected:
+ /// Adds the given widget to page's layout
virtual void placeModelWidget(ModuleBase_ModelWidget* theWidget);
+ /// Adds the given page to page's layout
virtual void placePageWidget(ModuleBase_PageBase* theWidget);
+ /// Returns page's layout (QGridLayout)
virtual QLayout* pageLayout();
+ /// Adds a stretch to page's layout
virtual void addPageStretch();
private:
- QGridLayout* myMainLayout;
+ QGridLayout* myMainLayout; ///< page's layout
};
#endif /* MODULEBASE_PAGEWIDGET_H_ */
for (aIt = aOwnersList.cbegin(); aIt != aOwnersList.cend(); aShpIt.Next(), aIt++) {
ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(*aIt);
// this case should be moved to PartSet module after redesign this class
- if (aShpIt.Value().ShapeType() == TopAbs_COMPOUND) {
+ /*if (aShpIt.Value().ShapeType() == TopAbs_COMPOUND) {
int aValue = 0;
AIS_ListOfInteractive aList;
aSelection->selectedAISObjects(aList);
}
}
}
- else {
+ else*/
+ {
if (myFeature) {
// We can not select a result of our feature
const std::list<ResultPtr>& aResList = myFeature->results();
aShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
aShape->setImpl(new TopoDS_Shape(aShpIt.Value()));
- mySelection.append(GeomSelection(aResult, aShape));
+ if (aShape->isEqual(aResult->shape())) {
+ //aShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
+ mySelection.append(GeomSelection(aResult, NULL));//aShape));
+ }
+ else
+ mySelection.append(GeomSelection(aResult, aShape));
}
}
//updateSelectionList();
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
TestConstraintVertical.py
TestConstraintEqual.py
TestConstraintTangent.py
+ TestConstraintMirror.py
TestHighload.py
TestSnowflake.py)
--- /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 = sketch()->addFeature(aFeatureIn->getKind());
+ aFeatureIn->data()->copyTo(aNewFeature->data());
+ 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()
+#=========================================================================
+# Verify the simmetricity of all mirrored objects
+#=========================================================================
+aRefListC = aMirror.reflist("ConstraintEntityC")
+aListSize = aRefListB.size()
+aLineDirX = aLineEndPoint.x() - aLineStartPoint.x()
+aLineDirY = aLineEndPoint.y() - aLineStartPoint.y()
+
+for ind in range(0, aListSize):
+ aFeatureB = modelAPI_Feature(aRefListB.object(ind))
+ aFeatureC = modelAPI_Feature(aRefListC.object(ind))
+ assert(aFeatureB is not None)
+ assert(aFeatureC is not None)
+ assert(aFeatureB.getKind() == aFeatureC.getKind())
+ anAttributes = {}
+ print aFeatureB.getKind()
+ if (aFeatureB.getKind() == "SketchLine"):
+ anAttributes = {'StartPoint':'StartPoint', 'EndPoint':'EndPoint'}
+ elif (aFeatureB.getKind() == "SketchArc"):
+ anAttributes = {'ArcCenter':'ArcCenter', 'ArcStartPoint':'ArcEndPoint', 'ArcEndPoint':'ArcStartPoint'}
+
+ for key in anAttributes:
+ aPointB = geomDataAPI_Point2D(aFeatureB.attribute(key))
+ aPointC = geomDataAPI_Point2D(aFeatureC.attribute(anAttributes[key]))
+ aDirX = aPointC.x() - aPointB.x()
+ aDirY = aPointC.y() - aPointB.y()
+ aDot = aLineDirX * aDirX + aLineDirY * aDirY
+ assert(math.fabs(aDot) < 1.e-10)
+ aDirX = aLineEndPoint.x() - 0.5 * (aPointB.x() + aPointC.x())
+ aDirY = aLineEndPoint.y() - 0.5 * (aPointB.y() + aPointC.y())
+ aCross = aLineDirX * aDirY - aLineDirY * aDirX
+ assert(math.fabs(aCross) < 1.e-10)
+#=========================================================================
+# 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>
#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>
#include <SketchPlugin_ConstraintVertical.h>
#include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeRefList.h>
#include <ModelAPI_Data.h>
#include <ModelAPI_Document.h>
#include <ModelAPI_Object.h>
return getType();
}
- if (aConstraintKind.compare(SketchPlugin_ConstraintEqual::ID()) == 0)
- {
+ if (aConstraintKind.compare(SketchPlugin_ConstraintEqual::ID()) == 0) {
static const int aConstrType[3] = {
SLVS_C_EQUAL_RADIUS,
SLVS_C_EQUAL_LINE_ARC_LEN,
return getType();
}
- if (aConstraintKind.compare(SketchPlugin_ConstraintTangent::ID()) == 0)
- {
+ if (aConstraintKind.compare(SketchPlugin_ConstraintTangent::ID()) == 0) {
static const int anArcPosDefault = 2;
static const int aLinePosDefault = 3;
int anArcPos = anArcPosDefault; // arc in tangency constraint should be placed before line
return getType();
}
+ if (aConstraintKind.compare(SketchPlugin_ConstraintMirror::ID()) == 0) {
+ int aNbAttrs = 0;
+ bool hasMirrorLine = false;
+ for (unsigned int indAttr = 0; indAttr < CONSTRAINT_ATTR_SIZE; indAttr++) {
+ AttributeRefListPtr anAttrRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+ aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr)));
+ if (anAttrRefList) {
+ aNbAttrs++;
+ myAttributesList[aNbAttrs] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
+ }
+ else {
+ std::shared_ptr<ModelAPI_Attribute> anAttr =
+ aConstrData->attribute(SketchPlugin_Constraint::ATTRIBUTE(indAttr));
+ if (typeOfAttribute(anAttr) == LINE) {
+ hasMirrorLine = !hasMirrorLine;
+ myAttributesList[0] = SketchPlugin_Constraint::ATTRIBUTE(indAttr);
+ }
+ }
+ }
+ if (aNbAttrs == 2 && hasMirrorLine)
+ myType = SLVS_C_SYMMETRIC_LINE;
+ return getType();
+ }
+
/// \todo Implement other kind of constraints
return getType();
#include <SketchPlugin_Constraint.h>
#include <SketchPlugin_ConstraintLength.h>
#include <SketchPlugin_ConstraintCoincidence.h>
+#include <SketchPlugin_ConstraintMirror.h>
#include <SketchPlugin_ConstraintRigid.h>
#include <SketchPlugin_Arc.h>
std::list<std::shared_ptr<ModelAPI_Attribute>>::const_iterator
anAttrIter = anAttrList.begin();
for ( ; anAttrIter != anAttrList.end(); anAttrIter++) {
- std::shared_ptr<ModelAPI_AttributeRefAttr> aCAttrRef =
+ AttributeRefListPtr aCAttrRefList =
+ std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(*anAttrIter);
+ if (aCAttrRefList) {
+ std::list<ObjectPtr> anObjList = aCAttrRefList->list();
+ std::list<ObjectPtr>::iterator anIt = anObjList.begin();
+ for ( ; anIt != anObjList.end(); anIt++) {
+ FeaturePtr aFeature = std::dynamic_pointer_cast<SketchPlugin_Feature>(*anIt);
+ if (aFeature && myEntityFeatMap.find(aFeature) != myEntityFeatMap.end())
+ return true;
+ }
+ continue;
+ }
+ AttributeRefAttrPtr aCAttrRef =
std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttrIter);
if (!aCAttrRef || !aCAttrRef->isObject()) {
std::shared_ptr<ModelAPI_Attribute> anAttr =
if (myWorkplane.h == SLVS_E_UNKNOWN)
return false;
- if (theConstraint && theConstraint->getKind() == SketchPlugin_ConstraintRigid::ID())
- return changeRigidConstraint(theConstraint);
+ if (theConstraint) {
+ if (theConstraint->getKind() == SketchPlugin_ConstraintRigid::ID())
+ return changeRigidConstraint(theConstraint);
+ if (theConstraint->getKind() == SketchPlugin_ConstraintMirror::ID())
+ return changeMirrorConstraint(theConstraint);
+ }
// Search this constraint in the current group to update it
ConstraintMap::const_iterator aConstrMapIter = myConstraintMap.find(theConstraint);
return true;
}
+// ============================================================================
+// Function: changeMirrorConstraint
+// Class: SketchSolver_ConstraintGroup
+// Purpose: create/update the "Mirror" constraint in the group
+// ============================================================================
+bool SketchSolver_ConstraintGroup::changeMirrorConstraint(
+ std::shared_ptr<SketchPlugin_Constraint> theConstraint)
+{
+ DataPtr aConstrData = theConstraint->data();
+
+ // Search this constraint in the current group to update it
+ ConstraintMap::const_iterator aConstrMapIter = myConstraintMap.find(theConstraint);
+ std::vector<Slvs_Constraint>::iterator aConstrIter;
+ if (aConstrMapIter != myConstraintMap.end()) {
+ int aConstrPos = Search(aConstrMapIter->second.front(), myConstraints);
+ aConstrIter = myConstraints.begin() + aConstrPos;
+ }
+
+ // Get constraint type and verify the constraint parameters are correct
+ SketchSolver_Constraint aConstraint(theConstraint);
+ int aConstrType = aConstraint.getType();
+ if (aConstrType == SLVS_C_UNKNOWN
+ || (aConstrMapIter != myConstraintMap.end() && aConstrIter->type != aConstrType))
+ return false;
+ const std::vector<std::string>& aConstraintAttributes = aConstraint.getAttributes();
+
+ Slvs_hEntity aMirrorLineEnt = SLVS_E_UNKNOWN;
+ AttributeRefAttrPtr aConstrAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstrData->attribute(aConstraintAttributes[0]));
+ if (!aConstrAttr)
+ return false;
+
+ // Convert the object of the attribute to the feature
+ FeaturePtr aMirrorLineFeat;
+ if (aConstrAttr->isObject() && aConstrAttr->object()) {
+ ResultConstructionPtr aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
+ aConstrAttr->object());
+ if (!aRC)
+ return false;
+ std::shared_ptr<ModelAPI_Document> aDoc = aRC->document();
+ aMirrorLineFeat = aDoc->feature(aRC);
+ }
+ aMirrorLineEnt = aConstrAttr->isObject() ?
+ changeEntityFeature(aMirrorLineFeat) : changeEntity(aConstrAttr->attr());
+
+ if (aConstrMapIter == myConstraintMap.end()) { // Add new constraint
+ // Append symmetric constraint for each point of mirroring features
+ AttributeRefListPtr aBaseRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+ aConstrData->attribute(aConstraintAttributes[1]));
+ AttributeRefListPtr aMirroredRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+ aConstrData->attribute(aConstraintAttributes[2]));
+ if (!aBaseRefList || !aMirroredRefList)
+ return false;
+
+ std::list<ObjectPtr> aBaseList = aBaseRefList->list();
+ std::list<ObjectPtr> aMirroredList = aMirroredRefList->list();
+ if (aBaseList.size() != aMirroredList.size())
+ return false;
+
+ myConstraintMap[theConstraint] = std::vector<Slvs_hEntity>();
+
+ FeaturePtr aBaseFeature, aMirrorFeature;
+ ResultConstructionPtr aRC;
+ std::list<ObjectPtr>::iterator aBaseIter = aBaseList.begin();
+ std::list<ObjectPtr>::iterator aMirIter = aMirroredList.begin();
+ for ( ; aBaseIter != aBaseList.end(); aBaseIter++, aMirIter++) {
+ aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aBaseIter);
+ aBaseFeature = aRC ? aRC->document()->feature(aRC) :
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(*aBaseIter);
+ aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aMirIter);
+ aMirrorFeature = aRC ? aRC->document()->feature(aRC) :
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(*aMirIter);
+
+ if (!aBaseFeature || !aMirrorFeature ||
+ aBaseFeature->getKind() != aMirrorFeature->getKind())
+ return false;
+ Slvs_hEntity aBaseEnt = changeEntityFeature(aBaseFeature);
+ Slvs_hEntity aMirrorEnt = changeEntityFeature(aMirrorFeature);
+
+ if (aBaseFeature->getKind() == SketchPlugin_Point::ID()) {
+ Slvs_Constraint aConstraint = Slvs_MakeConstraint(++myConstrMaxID, myID, aConstrType,
+ myWorkplane.h, 0.0, aBaseEnt, aMirrorEnt, aMirrorLineEnt, SLVS_E_UNKNOWN);
+ myConstraints.push_back(aConstraint);
+ myConstraintMap[theConstraint].push_back(aConstraint.h);
+ } else {
+ int aBasePos = Search(aBaseEnt, myEntities);
+ int aMirrorPos = Search(aMirrorEnt, myEntities);
+ if (aBaseFeature->getKind() == SketchPlugin_Line::ID()) {
+ for (int ind = 0; ind < 2; ind++) {
+ Slvs_Constraint aConstraint = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0,
+ myEntities[aBasePos].point[ind], myEntities[aMirrorPos].point[ind],
+ aMirrorLineEnt, SLVS_E_UNKNOWN);
+ myConstraints.push_back(aConstraint);
+ myConstraintMap[theConstraint].push_back(aConstraint.h);
+ }
+ } else if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) {
+ Slvs_Constraint aConstraint = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0,
+ myEntities[aBasePos].point[0], myEntities[aMirrorPos].point[0],
+ aMirrorLineEnt, SLVS_E_UNKNOWN);
+ myConstraints.push_back(aConstraint);
+ myConstraintMap[theConstraint].push_back(aConstraint.h);
+ // Additional constraint for equal radii
+ Slvs_Constraint anEqRadConstr = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, SLVS_C_EQUAL_RADIUS, myWorkplane.h, 0.0,
+ SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aBaseEnt, aMirrorEnt);
+ myConstraints.push_back(anEqRadConstr);
+ myConstraintMap[theConstraint].push_back(anEqRadConstr.h);
+ } else if (aBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
+ int aBaseArcInd[3] = {0, 1, 2}; // indices of points of arc, center corresponds center, first point corresponds last point
+ int aMirrorArcInd[3] = {0, 2, 1};
+ for (int ind = 0; ind < 3; ind++) {
+ Slvs_Constraint aConstraint = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0,
+ myEntities[aBasePos].point[aBaseArcInd[ind]], myEntities[aMirrorPos].point[aMirrorArcInd[ind]],
+ aMirrorLineEnt, SLVS_E_UNKNOWN);
+ myConstraints.push_back(aConstraint);
+ myConstraintMap[theConstraint].push_back(aConstraint.h);
+ }
+ }
+ }
+ }
+
+ // Set the mirror line unchanged during constraint recalculation
+ int aMirrorLinePos = Search(aMirrorLineEnt, myEntities);
+ Slvs_Constraint aRigidStart = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, SLVS_C_WHERE_DRAGGED, myWorkplane.h, 0,
+ myEntities[aMirrorLinePos].point[0], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
+ myConstraints.push_back(aRigidStart);
+ myConstraintMap[theConstraint].push_back(aRigidStart.h);
+ Slvs_Constraint aRigidEnd = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, SLVS_C_WHERE_DRAGGED, myWorkplane.h, 0,
+ myEntities[aMirrorLinePos].point[1], SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
+ myConstraints.push_back(aRigidEnd);
+ myConstraintMap[theConstraint].push_back(aRigidEnd.h);
+ }
+ return true;
+}
+
// ============================================================================
// Function: changeEntity
// Class: SketchSolver_ConstraintGroup
* \return \c true if the constraint added or updated successfully
*/
bool changeRigidConstraint(std::shared_ptr<SketchPlugin_Constraint> theConstraint);
+ /** \brief Adds or updates a mirror constraint in the group
+ * \param[in] theConstraint constraint to be changed
+ * \return \c true if the constraint added or updated successfully
+ */
+ bool changeMirrorConstraint(std::shared_ptr<SketchPlugin_Constraint> theConstraint);
/** \brief Verifies the feature attributes are used in this group
* \param[in] theFeature constraint or any other object for verification of interaction
std::shared_ptr<GeomAPI_Curve> aCurve1 = std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShape1));
std::shared_ptr<GeomAPI_Curve> aCurve2 = std::shared_ptr<GeomAPI_Curve>(new GeomAPI_Curve(aShape2));
- if (aCurve1->isLine()) {
+ if (aCurve1->isCircle() && aCurve2->isLine()) {
+ addLine(aGroup, SketchPlugin_Constraint::ENTITY_B());
+ GeomAdaptor_Curve aAdaptor(aCurve1->impl<Handle(Geom_Curve)>(), aCurve1->startParam(), aCurve1->endParam());
+ StdPrs_DeflectionCurve::Add(thePrs,aAdaptor,myDrawer);
+ } else if (aCurve1->isLine() && aCurve2->isCircle()) {
addLine(aGroup, SketchPlugin_Constraint::ENTITY_A());
GeomAdaptor_Curve aAdaptor(aCurve2->impl<Handle(Geom_Curve)>(), aCurve2->startParam(), aCurve2->endParam());
StdPrs_DeflectionCurve::Add(thePrs,aAdaptor,myDrawer);
} else {
- addLine(aGroup, SketchPlugin_Constraint::ENTITY_B());
- GeomAdaptor_Curve aAdaptor(aCurve1->impl<Handle(Geom_Curve)>(), aCurve1->startParam(), aCurve1->endParam());
- StdPrs_DeflectionCurve::Add(thePrs,aAdaptor,myDrawer);
+ // Both curves are arcs
+ GeomAdaptor_Curve aAdaptor1(aCurve1->impl<Handle(Geom_Curve)>(), aCurve1->startParam(), aCurve1->endParam());
+ StdPrs_DeflectionCurve::Add(thePrs, aAdaptor1, myDrawer);
+ GeomAdaptor_Curve aAdaptor2(aCurve2->impl<Handle(Geom_Curve)>(), aCurve2->startParam(), aCurve2->endParam());
+ StdPrs_DeflectionCurve::Add(thePrs, aAdaptor2, myDrawer);
}
}