ADD_SUBDIRECTORY (src/PartSetPlugin)
ADD_SUBDIRECTORY (src/ConstructionPlugin)
ADD_SUBDIRECTORY (src/FeaturesPlugin)
+ADD_SUBDIRECTORY (src/SketcherPrs)
+ ADD_SUBDIRECTORY (src/PythonFeaturesPlugin)
ADD_SUBDIRECTORY (src/SketchPlugin)
ADD_SUBDIRECTORY (src/SketchSolver)
ADD_SUBDIRECTORY (src/ModuleBase)
} else if (isNode(theNode, NODE_WORKBENCH, NODE_GROUP, NULL)) {
storeAttribute(theNode, _ID);
storeAttribute(theNode, WORKBENCH_DOC);
- } else if (myIsProcessWidgets && isWidgetNode(theNode)) {
- std::shared_ptr<Config_AttributeMessage> aMessage(new Config_AttributeMessage(aMenuItemEvent, this));
- aMessage->setFeatureId(restoreAttribute(NODE_FEATURE, _ID));
- std::string anAttributeID = getProperty(theNode, _ID);
- if (!anAttributeID.empty()) {
- aMessage->setAttributeId(anAttributeID);
- aMessage->setObligatory(getBooleanAttribute(theNode, ATTR_OBLIGATORY, true));
- aMessage->setConcealment(getBooleanAttribute(theNode, ATTR_CONCEALMENT, false));
- Events_Loop::loop()->send(aMessage);
+ } else if (myIsProcessWidgets) {
+ // widgets, like shape_selector or containers, like toolbox
+ if (isAttributeNode(theNode)) {
+ std::shared_ptr<Config_AttributeMessage> aMessage(new Config_AttributeMessage(aMenuItemEvent, this));
+ aMessage->setFeatureId(restoreAttribute(NODE_FEATURE, _ID));
+ std::string anAttributeID = getProperty(theNode, _ID);
+ if (!anAttributeID.empty()) {
+ aMessage->setAttributeId(anAttributeID);
+ aMessage->setObligatory(getBooleanAttribute(theNode, ATTR_OBLIGATORY, true));
+ aMessage->setConcealment(getBooleanAttribute(theNode, ATTR_CONCEALMENT, false));
+ // nested "paged" widgets are not allowed, this issue may be resolved here:
+ if (hasParent(theNode, WDG_SWITCH_CASE, WDG_TOOLBOX_BOX, NULL)) {
+ const char* kWdgCase = hasParent(theNode, WDG_SWITCH_CASE, NULL)
+ ? WDG_SWITCH_CASE
+ : WDG_TOOLBOX_BOX;
+ const char* kWdgSwitch = hasParent(theNode, WDG_SWITCH_CASE, NULL)
+ ? WDG_SWITCH
+ : WDG_TOOLBOX;
+ aMessage->setCaseId(restoreAttribute(kWdgCase, _ID));
+ aMessage->setSwitchId(restoreAttribute(kWdgSwitch, _ID));
+ }
+ Events_Loop::loop()->send(aMessage);
+ }
+ // container pages, like "case" or "box"
+ } else if (isNode(theNode, WDG_SWITCH, WDG_SWITCH_CASE, WDG_TOOLBOX, WDG_TOOLBOX_BOX, NULL)) {
+ storeAttribute(theNode, _ID); // save case:caseId (or box:boxId)
}
}
- //Process SOURCE, VALIDATOR nodes.
+ //Process SOURCE nodes.
Config_XMLReader::processNode(theNode);
}
return result;
}
- void Config_XMLReader::processValidator(xmlNodePtr theNode)
+ void Config_XMLReader::storeAttribute(xmlNodePtr theNode, const char* theAttribute)
{
- Events_ID aValidatoEvent = Events_Loop::eventByName(EVENT_VALIDATOR_LOADED);
- Events_Loop* aEvLoop = Events_Loop::loop();
- std::shared_ptr<Config_ValidatorMessage>
- aMessage(new Config_ValidatorMessage(aValidatoEvent, this));
- std::string aValidatorId;
- std::list<std::string> aParameters;
- getParametersInfo(theNode, aValidatorId, aParameters);
- aMessage->setValidatorId(aValidatorId);
- aMessage->setValidatorParameters(aParameters);
- xmlNodePtr aFeatureOrWdgNode = theNode->parent;
- if (isNode(aFeatureOrWdgNode, NODE_FEATURE, NULL)) {
- aMessage->setFeatureId(getProperty(aFeatureOrWdgNode, _ID));
- } else {
- aMessage->setAttributeId(getProperty(aFeatureOrWdgNode, _ID));
- aMessage->setFeatureId(myCurrentFeature);
+ std::string aKey = getNodeName(theNode) + ":" + std::string(theAttribute);
+ std::string aValue = getProperty(theNode, theAttribute);
+ if(!aValue.empty()) {
+ myCachedAttributes[aKey] = aValue;
}
- aEvLoop->send(aMessage);
}
- void Config_XMLReader::processSelectionFilter(xmlNodePtr theNode)
+ std::string Config_XMLReader::restoreAttribute(xmlNodePtr theNode, const char* theAttribute)
{
- Events_ID aFilterEvent = Events_Loop::eventByName(EVENT_SELFILTER_LOADED);
- Events_Loop* aEvLoop = Events_Loop::loop();
- std::shared_ptr<Config_SelectionFilterMessage> aMessage =
- std::make_shared<Config_SelectionFilterMessage>(aFilterEvent, this);
- std::string aSelectionFilterId;
- std::list<std::string> aParameters;
- getParametersInfo(theNode, aSelectionFilterId, aParameters);
- aMessage->setSelectionFilterId(aSelectionFilterId);
- aMessage->setFilterParameters(aParameters);
-
- xmlNodePtr aFeatureOrWdgNode = theNode->parent;
- if (isNode(aFeatureOrWdgNode, NODE_FEATURE, NULL)) {
- aMessage->setFeatureId(getProperty(aFeatureOrWdgNode, _ID));
- } else {
- aMessage->setAttributeId(getProperty(aFeatureOrWdgNode, _ID));
- aMessage->setFeatureId(myCurrentFeature);
+ return restoreAttribute(getNodeName(theNode).c_str(), theAttribute);
+ }
+
+ std::string Config_XMLReader::restoreAttribute(const char* theNodeName, const char* theAttribute)
+ {
+ std::string aKey = std::string(theNodeName) + ":" + std::string(theAttribute);
+ std::string result = "";
+ if(myCachedAttributes.find(aKey) != myCachedAttributes.end()) {
+ result = myCachedAttributes[aKey];
}
- aEvLoop->send(aMessage);
+ return result;
+ }
++
++bool Config_XMLReader::cleanupAttribute(xmlNodePtr theNode, const char* theNodeAttribute)
++{
++ return cleanupAttribute(getNodeName(theNode).c_str(), theNodeAttribute);
++}
++
++bool Config_XMLReader::cleanupAttribute(const char* theNodeName, const char* theNodeAttribute)
++{
++ std::string aKey = std::string(theNodeName) + ":" + std::string(theNodeAttribute);
++ bool result = false;
++ std::map<std::string, std::string>::iterator anEntry = myCachedAttributes.find(aKey);
++ if( anEntry != myCachedAttributes.end()) {
++ myCachedAttributes.erase(anEntry);
++ result = true;
++ }
++ return result;
+}
xmlNodePtr node(void* theNode);
/// Gets xml node name
std::string getNodeName(xmlNodePtr theNode);
- /*!
- * \brief Retrieves all the necessary info from the validator node.
- * Sends ValidatorLoaded event
- */
- void processValidator(xmlNodePtr theNode);
- /*!
- * \brief Retrieves all the necessary info from the SelectionFilter node.
- * Sends SelectionFilterLoaded event
- */
- void processSelectionFilter(xmlNodePtr theNode);
+ /// Stores an attribute in internal map for later use.
+ /// Key is "Node_Name:Node_Attribute" and value is getProperty(theNodeAttribute)
+ void storeAttribute(xmlNodePtr theNode, const char* theNodeAttribute);
+ /// Restores an attribute from internal map.
+ std::string restoreAttribute(xmlNodePtr theNode, const char* theNodeAttribute);
+ /// Restores an attribute from internal map.
+ std::string restoreAttribute(const char* theNodeName, const char* theNodeAttribute);
++ bool cleanupAttribute(xmlNodePtr theNode, const char* theNodeAttribute);
++ bool cleanupAttribute(const char* theNodeName, const char* theNodeAttribute);
protected:
- std::string myCurrentFeature; ///< Name of currently processed feature
std::string myDocumentPath; ///< Path to the xml document
xmlDocPtr myXmlDoc; ///< Root of the xml document
+ /// A map to store all parent's attributes.
+ /// The key has from "Node_Name:Node_Attribute"
+ std::map<std::string, std::string> myCachedAttributes;
};
#endif /* CONFIG_XMLREADER_H_ */
<plugin library="ConstructionPlugin" configuration="plugin-Construction.xml"/>
<plugin library="FeaturesPlugin" configuration="plugin-Features.xml"/>
<plugin library="ExchangePlugin" configuration="plugin-Exchange.xml"/>
+ <plugin script="PythonFeaturesPlugin" configuration="plugin-PythonFeatures.xml"/>
<plugin script="ConnectorPlugin" configuration="plugin-Connector.xml" dependency="Geometry"/>
+ <plugin library="ParametersPlugin" configuration="plugin-Parameters.xml"/>
<plugin library="SketchSolver"/>
<plugin library="GeomValidators"/>
<plugin library="DFBrowser" internal="true"/>
void ConstructionPlugin_Axis::initAttributes()
{
- data()->addAttribute(POINT_ATTR_FIRST, ModelAPI_AttributeSelection::typeId());
- data()->addAttribute(POINT_ATTR_SECOND, ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(ConstructionPlugin_Axis::METHOD(),
- ModelAPI_AttributeString::type());
++ ModelAPI_AttributeString::typeId());
+ data()->addAttribute(ConstructionPlugin_Axis::POINT_FIRST(),
- ModelAPI_AttributeSelection::type());
++ ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(ConstructionPlugin_Axis::POINT_SECOND(),
- ModelAPI_AttributeSelection::type());
++ ModelAPI_AttributeSelection::typeId());
+ data()->addAttribute(ConstructionPlugin_Axis::CYLINDRICAL_FACE(),
- ModelAPI_AttributeSelection::type());
++ ModelAPI_AttributeSelection::typeId());
}
-void ConstructionPlugin_Axis::execute()
+void ConstructionPlugin_Axis::createAxisByTwoPoints()
{
- AttributeSelectionPtr aRef1 = data()->selection(POINT_ATTR_FIRST);
- AttributeSelectionPtr aRef2 = data()->selection(POINT_ATTR_SECOND);
+ AttributeSelectionPtr aRef1 = data()->selection(ConstructionPlugin_Axis::POINT_FIRST());
+ AttributeSelectionPtr aRef2 = data()->selection(ConstructionPlugin_Axis::POINT_SECOND());
if ((aRef1.get() != NULL) && (aRef2.get() != NULL)) {
GeomShapePtr aShape1 = aRef1->value();
GeomShapePtr aShape2 = aRef2->value();
void ConstructionPlugin_Plane::initAttributes()
{
- data()->addAttribute(ConstructionPlugin_Plane::METHOD(), ModelAPI_AttributeString::type());
- data()->addAttribute(FACE_ATTR, ModelAPI_AttributeSelection::typeId());
- data()->addAttribute(DISTANCE_ATTR, ModelAPI_AttributeDouble::typeId());
++ data()->addAttribute(ConstructionPlugin_Plane::METHOD(), ModelAPI_AttributeString::typeId());
+ // Face & Distance
- data()->addAttribute(ConstructionPlugin_Plane::FACE(), ModelAPI_AttributeSelection::type());
- data()->addAttribute(ConstructionPlugin_Plane::DISTANCE(), ModelAPI_AttributeDouble::type());
++ data()->addAttribute(ConstructionPlugin_Plane::FACE(), ModelAPI_AttributeSelection::typeId());
++ data()->addAttribute(ConstructionPlugin_Plane::DISTANCE(), ModelAPI_AttributeDouble::typeId());
+ // General equation
- data()->addAttribute(ConstructionPlugin_Plane::A(), ModelAPI_AttributeDouble::type());
- data()->addAttribute(ConstructionPlugin_Plane::B(), ModelAPI_AttributeDouble::type());
- data()->addAttribute(ConstructionPlugin_Plane::C(), ModelAPI_AttributeDouble::type());
- data()->addAttribute(ConstructionPlugin_Plane::D(), ModelAPI_AttributeDouble::type());
++ data()->addAttribute(ConstructionPlugin_Plane::A(), ModelAPI_AttributeDouble::typeId());
++ data()->addAttribute(ConstructionPlugin_Plane::B(), ModelAPI_AttributeDouble::typeId());
++ data()->addAttribute(ConstructionPlugin_Plane::C(), ModelAPI_AttributeDouble::typeId());
++ data()->addAttribute(ConstructionPlugin_Plane::D(), ModelAPI_AttributeDouble::typeId());
}
void ConstructionPlugin_Plane::execute()
{
}
+const std::string& ConstructionPlugin_Point::getKind()
+{
+ static std::string MY_KIND = ConstructionPlugin_Point::ID();
+ return MY_KIND;
+}
+
void ConstructionPlugin_Point::initAttributes()
{
- data()->addAttribute(ConstructionPlugin_Point::X(), ModelAPI_AttributeDouble::type());
- data()->addAttribute(ConstructionPlugin_Point::Y(), ModelAPI_AttributeDouble::type());
- data()->addAttribute(ConstructionPlugin_Point::Z(), ModelAPI_AttributeDouble::type());
- data()->addAttribute(POINT_ATTR_X, ModelAPI_AttributeDouble::typeId());
- data()->addAttribute(POINT_ATTR_Y, ModelAPI_AttributeDouble::typeId());
- data()->addAttribute(POINT_ATTR_Z, ModelAPI_AttributeDouble::typeId());
++ data()->addAttribute(ConstructionPlugin_Point::X(), ModelAPI_AttributeDouble::typeId());
++ data()->addAttribute(ConstructionPlugin_Point::Y(), ModelAPI_AttributeDouble::typeId());
++ data()->addAttribute(ConstructionPlugin_Point::Z(), ModelAPI_AttributeDouble::typeId());
}
void ConstructionPlugin_Point::execute()
void FeaturesPlugin_Extrusion::initAttributes()
{
- data()->addAttribute(FeaturesPlugin_Extrusion::FACE_ID(), ModelAPI_AttributeSelection::typeId());
+ AttributeSelectionListPtr aSelection =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
- FeaturesPlugin_Extrusion::LIST_ID(), ModelAPI_AttributeSelectionList::type()));
++ FeaturesPlugin_Extrusion::LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
+ // extrusion works with faces always
+ aSelection->setSelectionType("FACE");
- data()->addAttribute(FeaturesPlugin_Extrusion::SIZE_ID(), ModelAPI_AttributeDouble::type());
- data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::type());
+ data()->addAttribute(FeaturesPlugin_Extrusion::SIZE_ID(), ModelAPI_AttributeDouble::typeId());
+ data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
}
void FeaturesPlugin_Extrusion::execute()
}
}
- }
+
+//============================================================================
+void FeaturesPlugin_Extrusion::clearResult()
+{
+ std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
+ std::shared_ptr<GeomAPI_Shape> anEmptyShape(new GeomAPI_Shape);
+ aResultBody->store(anEmptyShape);
+ setResult(aResultBody);
++}
void FeaturesPlugin_Placement::initAttributes()
{
- data()->addAttribute(FeaturesPlugin_Placement::BASE_OBJECT_ID(), ModelAPI_AttributeSelection::type());
- data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID(), ModelAPI_AttributeSelection::type());
- data()->addAttribute(FeaturesPlugin_Placement::REVERSE_ID(), ModelAPI_AttributeBoolean::type());
- data()->addAttribute(FeaturesPlugin_Placement::CENTERING_ID(), ModelAPI_AttributeBoolean::type());
- data()->addAttribute(FeaturesPlugin_Placement::BASE_FACE_ID(), ModelAPI_AttributeSelection::typeId());
- data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_FACE_ID(), ModelAPI_AttributeSelection::typeId());
++ data()->addAttribute(FeaturesPlugin_Placement::BASE_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
++ data()->addAttribute(FeaturesPlugin_Placement::ATTRACT_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
++ data()->addAttribute(FeaturesPlugin_Placement::REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
++ data()->addAttribute(FeaturesPlugin_Placement::CENTERING_ID(), ModelAPI_AttributeBoolean::typeId());
}
void FeaturesPlugin_Placement::execute()
class FeaturesPlugin_Extrusion : public ModelAPI_Feature
static const std::string MY_EXTRUSION_ID("Extrusion");
- static const std::string MY_FACE_ID("extrusion_face");
- static const std::string MY_SIZE_ID("extrusion_size");
- static const std::string MY_REVERSE_ID("extrusion_reverse");
+ static const std::string MY_FACE_ID("base");
+ static const std::string MY_SIZE_ID("size");
+ static const std::string MY_REVERSE_ID("reverse");
-- data()->addAttribute(FeaturesPlugin_Extrusion::FACE_ID(), ModelAPI_AttributeSelection::type());
-- data()->addAttribute(FeaturesPlugin_Extrusion::SIZE_ID(), ModelAPI_AttributeDouble::type());
-- data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::type());
++ data()->addAttribute(FeaturesPlugin_Extrusion::FACE_ID(), ModelAPI_AttributeSelection::typeId());
++ data()->addAttribute(FeaturesPlugin_Extrusion::SIZE_ID(), ModelAPI_AttributeDouble::typeId());
++ data()->addAttribute(FeaturesPlugin_Extrusion::REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
"""
# Number rows and columns of cylinders that cuts the big box. Number of Boolena operations is N*N
#=========================================================================
# Initialization of the test
#=========================================================================
--from ModelAPI import *
--from GeomDataAPI import *
--from GeomAlgoAPI import *
from GeomAPI import *
- __updated__ = "2015-02-25"
++from GeomAlgoAPI import *
++from GeomDataAPI import *
++from ModelAPI import *
+
-__updated__ = "2015-02-25"
+
++__updated__ = "2015-03-26"
aSession = ModelAPI_Session.get()
aDocument = aSession.moduleDocument()
aSession.startOperation()
aSketchFeatures = []
for i in xrange(0, N):
-- for j in xrange(0, N):
-- # Create circle
-- aSketchFeature = modelAPI_CompositeFeature(aPart.addFeature("Sketch"))
-- 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)
-- aSketchCircle = aSketchFeature.addFeature("SketchCircle")
-- anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
-- aCircleRadius = aSketchCircle.real("CircleRadius")
-- anCircleCentr.setValue(0.5 + step * (0.5 + i), 0.5 + step * (0.5 + j))
-- aCircleRadius.setValue(radius)
-- aSketchFeatures.append(aSketchFeature)
++ for j in xrange(0, N):
++ # Create circle
++ aSketchFeature = modelAPI_CompositeFeature(aPart.addFeature("Sketch"))
++ 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)
++ aSketchCircle = aSketchFeature.addFeature("SketchCircle")
++ anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
++ aCircleRadius = aSketchCircle.real("CircleRadius")
++ anCircleCentr.setValue(0.5 + step * (0.5 + i), 0.5 + step * (0.5 + j))
++ aCircleRadius.setValue(radius)
++ aSketchFeatures.append(aSketchFeature)
aSession.finishOperation()
anExtrusions = []
for i in xrange(0, N * N):
-- aSketchResult = aSketchFeatures[i].firstResult()
-- aSketchEdges = modelAPI_ResultConstruction(aSketchResult).shape()
-- origin = geomDataAPI_Point(aSketchFeatures[i].attribute("Origin")).pnt()
-- dirX = geomDataAPI_Dir(aSketchFeatures[i].attribute("DirX")).dir()
-- dirY = geomDataAPI_Dir(aSketchFeatures[i].attribute("DirY")).dir()
-- norm = geomDataAPI_Dir(aSketchFeatures[i].attribute("Norm")).dir()
-- aSketchFaces = ShapeList()
-- GeomAlgoAPI_SketchBuilder.createFaces(
-- origin, dirX, dirY, norm, aSketchEdges, aSketchFaces)
--
-- anExtrusionFt = aPart.addFeature("Extrusion")
-- assert (anExtrusionFt.getKind() == "Extrusion")
-
- anExtrusionFt.selectionList("base").append(
- anExtrusionFt.selection("extrusion_face").setValue(
-- aSketchResult, aSketchFaces[0])
- anExtrusionFt.real("size").setValue(10)
- anExtrusionFt.boolean("reverse").setValue(False)
- anExtrusionFt.real("extrusion_size").setValue(10)
- anExtrusionFt.boolean("extrusion_reverse").setValue(False)
-- anExtrusions.append(anExtrusionFt)
++ aSketchResult = aSketchFeatures[i].firstResult()
++ aSketchEdges = modelAPI_ResultConstruction(aSketchResult).shape()
++ origin = geomDataAPI_Point(aSketchFeatures[i].attribute("Origin")).pnt()
++ dirX = geomDataAPI_Dir(aSketchFeatures[i].attribute("DirX")).dir()
++ dirY = geomDataAPI_Dir(aSketchFeatures[i].attribute("DirY")).dir()
++ norm = geomDataAPI_Dir(aSketchFeatures[i].attribute("Norm")).dir()
++ aSketchFaces = ShapeList()
++ GeomAlgoAPI_SketchBuilder.createFaces(
++ origin, dirX, dirY, norm, aSketchEdges, aSketchFaces)
++
++ anExtrusionFt = aPart.addFeature("Extrusion")
++ assert (anExtrusionFt.getKind() == "Extrusion")
++
++ anExtrusionFt.selectionList("base").append(
++ aSketchResult, aSketchFaces[0])
++ anExtrusionFt.real("size").setValue(10)
++ anExtrusionFt.boolean("reverse").setValue(False)
++ # v1.0.2 from master
++ # anExtrusionFt.selection("extrusion_face").setValue(
++ # aSketchResult, aSketchFaces[0])
++ # anExtrusionFt.real("extrusion_size").setValue(10)
++ # anExtrusionFt.boolean("extrusion_reverse").setValue(False)
++ anExtrusions.append(anExtrusionFt)
aSession.finishOperation()
origin, dirX, dirY, norm, aSketchEdges, aSketchFaces)
# Create extrusion on them
aBox = aPart.addFeature("Extrusion")
-aBox.selection("extrusion_face").setValue(
+aBox.selectionList("base").append(
aSketchResult, aSketchFaces[0])
-aBox.real("extrusion_size").setValue(10)
-aBox.boolean("extrusion_reverse").setValue(False)
+aBox.real("size").setValue(10)
+aBox.boolean("reverse").setValue(False)
++# v 1.0.2 from master
++# aBox.selection("extrusion_face").setValue(
++# aSketchResult, aSketchFaces[0])
++# aBox.real("extrusion_size").setValue(10)
++# aBox.boolean("extrusion_reverse").setValue(False)
+
aSession.finishOperation()
#=========================================================================
--# Create a boolean cut of cylinders from the box:
++# Create a boolean cut of cylinders from the box:
# result of Boolean is the first argument of the next Boolean
#=========================================================================
aCurrentResult = aBox.firstResult()
aSession.startOperation()
for i in xrange(0, N * N):
-- aBooleanFt = aPart.addFeature("Boolean")
-- aBooleanFt.reference("main_object").setValue(modelAPI_ResultBody(aCurrentResult))
-- aBooleanFt.reference("tool_object").setValue(modelAPI_ResultBody(anExtrusions[i].firstResult()))
-- kBooleanTypeCut = 0
-- aBooleanFt.integer("bool_type").setValue(kBooleanTypeCut)
-- aBooleanFt.execute()
-- aCurrentResult = aBooleanFt.firstResult()
++ aBooleanFt = aPart.addFeature("Boolean")
++ aBooleanFt.reference("main_object").setValue(modelAPI_ResultBody(aCurrentResult))
++ aBooleanFt.reference("tool_object").setValue(modelAPI_ResultBody(anExtrusions[i].firstResult()))
++ kBooleanTypeCut = 0
++ aBooleanFt.integer("bool_type").setValue(kBooleanTypeCut)
++ aBooleanFt.execute()
++ aCurrentResult = aBooleanFt.firstResult()
aSession.finishOperation()
#=========================================================================
virtual double z() const = 0;
/// Returns the direction of this attribute
virtual std::shared_ptr<GeomAPI_Dir> dir() = 0;
+ /// Returns the coordinates of this attribute
+ virtual std::shared_ptr<GeomAPI_XYZ> xyz() = 0;
/// Returns the type of this class of attributes
- static inline std::string type()
+ static std::string typeId()
{
return std::string("Dir");
}
--- /dev/null
- aValid = aRefAttr.get() != NULL && aRefAttr->attributeType() == GeomDataAPI_Point2D::type();
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+
+#include "GeomValidators_EdgeOrVertex.h"
+#include "GeomValidators_Tools.h"
+#include "GeomValidators_Edge.h"
+
+#include "ModelAPI_AttributeRefAttr.h"
+#include "ModelAPI_Result.h"
+
+#include <ModelAPI_Session.h>
+
+#include <GeomAPI_Curve.h>
+#include <GeomDataAPI_Point2D.h>
+
+#include <Events_Error.h>
+
+#include <StdSelect_TypeOfEdge.hxx>
+
+#include <QString>
+#include <QMap>
+
+
+bool GeomValidators_EdgeOrVertex::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments) const
+{
+ bool aValid = false;
+
+ // 1. check whether the attribute is a linear edge
+ // there is a check whether the feature contains a point and a linear edge or two point values
+ SessionPtr aMgr = ModelAPI_Session::get();
+ ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
+
+ const GeomValidators_Edge* aLinearEdgeValidator =
+ dynamic_cast<const GeomValidators_Edge*>(aFactory->validator("GeomValidators_Edge"));
+
+ std::list<std::string> anArguments;
+ anArguments.push_back("line");
+ aValid = aLinearEdgeValidator->isValid(theAttribute, anArguments);
+ if (!aValid) {
+ //2. check whether the attribute is a vertex
+ ObjectPtr anObject = GeomValidators_Tools::getObject(theAttribute);
+ if (anObject.get() != NULL) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+ ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
+ if (aResult.get() != NULL) {
+ GeomShapePtr aShape = aResult->shape();
+ if (aShape.get() != NULL) {
+ aValid = aShape->isVertex();
+ }
+ }
+ }
+ else {
+ AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+ if (anAttr.get() != NULL) {
+ AttributePtr aRefAttr = anAttr->attr();
++ aValid = aRefAttr.get() != NULL && aRefAttr->attributeType() == GeomDataAPI_Point2D::typeId();
+ }
+ }
+ }
+ return aValid;
+}
--- /dev/null
- if (anAttrType == ModelAPI_AttributeRefAttr::type()) {
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: GeomValidators_Tools.cpp
+// Created: 06 Aug 2014
+// Author: Vitaly Smetannikov
+
+#include "GeomValidators_Tools.h"
+
+#include "ModelAPI_AttributeRefAttr.h"
+#include "ModelAPI_AttributeSelection.h"
+#include "ModelAPI_AttributeReference.h"
+
+namespace GeomValidators_Tools {
+
+ ObjectPtr getObject(const AttributePtr& theAttribute)
+ {
+ ObjectPtr anObject;
+ std::string anAttrType = theAttribute->attributeType();
- if (anAttrType == ModelAPI_AttributeSelection::type()) {
++ if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
+ AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+ if (anAttr != NULL && anAttr->isObject())
+ anObject = anAttr->object();
+ }
- if (anAttrType == ModelAPI_AttributeReference::type()) {
++ if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
+ AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
+ if (anAttr != NULL && anAttr->isInitialized())
+ anObject = anAttr->context();
+ }
++ if (anAttrType == ModelAPI_AttributeReference::typeId()) {
+ AttributeReferencePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
+ if (anAttr.get() != NULL && anAttr->isInitialized())
+ anObject = anAttr->value();
+ }
+ return anObject;
+ }
+}
aName = GetShapeName(aDoc, aSubShape, selectionLabel());
if(aName.empty() ) { // not in the document!
TopAbs_ShapeEnum aType = aSubShape.ShapeType();
- switch (aType) {
- case TopAbs_FACE:
+ switch (aType) {
+ case TopAbs_FACE:
// the Face should be in DF. If it is not the case, it is an error ==> to be debugged
- break;
- case TopAbs_EDGE:
- {
- // name structure: F1 | F2 [| F3 | F4], where F1 & F2 the faces which gives the Edge in trivial case
- // if it is not atrivial case we use localization by neighbours. F3 & F4 - neighbour faces
- TopTools_IndexedDataMapOfShapeListOfShape aMap;
- TopExp::MapShapesAndAncestors(aContext, TopAbs_EDGE, TopAbs_FACE, aMap);
- TopTools_IndexedMapOfShape aSMap; // map for ancestors of the sub-shape
- bool isTrivialCase(true);
- /* for (int i = 1; i <= aMap.Extent(); i++) {
- const TopoDS_Shape& aKey = aMap.FindKey(i);
- //if (aKey.IsNotEqual(aSubShape)) continue; // find exactly the selected key
- if (aKey.IsSame(aSubShape)) continue;
- const TopTools_ListOfShape& anAncestors = aMap.FindFromIndex(i);
- // check that it is not a trivial case (F1 & F2: aNumber = 1)
- isTrivialCase = isTrivial(anAncestors, aSMap);
- break;
- }*/
- if(aMap.Contains(aSubShape)) {
- const TopTools_ListOfShape& anAncestors = aMap.FindFromKey(aSubShape);
- // check that it is not a trivial case (F1 & F2: aNumber = 1)
- isTrivialCase = isTrivial(anAncestors, aSMap);
- } else
- break;
- TopTools_ListOfShape aListOfNbs;
- if(!isTrivialCase) { // find Neighbors
- TNaming_Localizer aLocalizer;
- TopTools_MapOfShape aMap3;
- aLocalizer.FindNeighbourg(aContext, aSubShape, aMap3);
- //int n = aMap3.Extent();
- TopTools_MapIteratorOfMapOfShape it(aMap3);
- for(;it.More();it.Next()) {
- const TopoDS_Shape& aNbShape = it.Key(); // neighbor edge
- //TopAbs_ShapeEnum aType = aNbShape.ShapeType();
- const TopTools_ListOfShape& aList = aMap.FindFromKey(aNbShape);
- TopTools_ListIteratorOfListOfShape it2(aList);
- for(;it2.More();it2.Next()) {
- if(aSMap.Contains(it2.Value())) continue; // skip this Face
- aListOfNbs.Append(it2.Value());
- }
- }
- } // else a trivial case
-
- // build name of the sub-shape Edge
- for(int i=1; i <= aSMap.Extent(); i++) {
- const TopoDS_Shape& aFace = aSMap.FindKey(i);
- std::string aFaceName = GetShapeName(aDoc, aFace, selectionLabel());
- if(i == 1)
- aName = aFaceName;
- else
- aName += "|" + aFaceName;
- }
- TopTools_ListIteratorOfListOfShape itl(aListOfNbs);
- for (;itl.More();itl.Next()) {
- std::string aFaceName = GetShapeName(aDoc, itl.Value(), selectionLabel());
- aName += "|" + aFaceName;
- }
- }
- break;
+ break;
+ case TopAbs_EDGE:
+ {
+ // name structure: F1 | F2 [| F3 | F4], where F1 & F2 the faces which gives the Edge in trivial case
+ // if it is not atrivial case we use localization by neighbours. F3 & F4 - neighbour faces
+ if (BRep_Tool::Degenerated(TopoDS::Edge(aSubShape))) {
+ aName = "Degenerated_Edge";
+ break;
+ }
+ TopTools_IndexedDataMapOfShapeListOfShape aMap;
+ TopExp::MapShapesAndAncestors(aContext, TopAbs_EDGE, TopAbs_FACE, aMap);
+ TopTools_IndexedMapOfShape aSMap; // map for ancestors of the sub-shape
+ bool isTrivialCase(true);
+/* for (int i = 1; i <= aMap.Extent(); i++) {
+ const TopoDS_Shape& aKey = aMap.FindKey(i);
+ //if (aKey.IsNotEqual(aSubShape)) continue; // find exactly the selected key
+ if (aKey.IsSame(aSubShape)) continue;
+ const TopTools_ListOfShape& anAncestors = aMap.FindFromIndex(i);
+ // check that it is not a trivial case (F1 & F2: aNumber = 1)
+ isTrivialCase = isTrivial(anAncestors, aSMap);
+ break;
+ }*/
+ if(aMap.Contains(aSubShape)) {
+ const TopTools_ListOfShape& anAncestors = aMap.FindFromKey(aSubShape);
+ // check that it is not a trivial case (F1 & F2: aNumber = 1)
+ isTrivialCase = isTrivial(anAncestors, aSMap);
+ } else
+ break;
+ TopTools_ListOfShape aListOfNbs;
+ if(!isTrivialCase) { // find Neighbors
+ TNaming_Localizer aLocalizer;
+ TopTools_MapOfShape aMap3;
+ aLocalizer.FindNeighbourg(aContext, aSubShape, aMap3);
+ //int n = aMap3.Extent();
+ TopTools_MapIteratorOfMapOfShape it(aMap3);
+ for(;it.More();it.Next()) {
+ const TopoDS_Shape& aNbShape = it.Key(); // neighbor edge
+ //TopAbs_ShapeEnum aType = aNbShape.ShapeType();
+ const TopTools_ListOfShape& aList = aMap.FindFromKey(aNbShape);
+ TopTools_ListIteratorOfListOfShape it2(aList);
+ for(;it2.More();it2.Next()) {
+ if(aSMap.Contains(it2.Value())) continue; // skip this Face
+ aListOfNbs.Append(it2.Value());
+ }
+ }
+ } // else a trivial case
+
+ // build name of the sub-shape Edge
+ for(int i=1; i <= aSMap.Extent(); i++) {
+ const TopoDS_Shape& aFace = aSMap.FindKey(i);
+ std::string aFaceName = GetShapeName(aDoc, aFace, selectionLabel());
+ if(i == 1)
+ aName = aFaceName;
+ else
+ aName += "|" + aFaceName;
+ }
+ TopTools_ListIteratorOfListOfShape itl(aListOfNbs);
+ for (;itl.More();itl.Next()) {
+ std::string aFaceName = GetShapeName(aDoc, itl.Value(), selectionLabel());
+ aName += "|" + aFaceName;
+ }
+ }
+ break;
- case TopAbs_VERTEX:
- // name structure (Monifold Topology):
- // 1) F1 | F2 | F3 - intersection of 3 faces defines a vertex - trivial case.
- // 2) F1 | F2 | F3 [|F4 [|Fn]] - redundant definition, but it should be kept as is to obtain safe recomputation
- // 2) F1 | F2 - intersection of 2 faces definses a vertex - applicable for case
- // when 1 faces is cylindrical, conical, spherical or revolution and etc.
- // 3) E1 | E2 | E3 - intersection of 3 edges defines a vertex - when we have case of a shell
- // or compound of 2 open faces.
- // 4) E1 | E2 - intesection of 2 edges defines a vertex - when we have a case of
- // two independent edges (wire or compound)
- // implemented 2 first cases
- {
- TopTools_IndexedDataMapOfShapeListOfShape aMap;
- TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_FACE, aMap);
- const TopTools_ListOfShape& aList2 = aMap.FindFromKey(aSubShape);
- TopTools_ListOfShape aList;
- TopTools_MapOfShape aFMap;
+ case TopAbs_VERTEX:
+ // name structure (Monifold Topology):
+ // 1) F1 | F2 | F3 - intersection of 3 faces defines a vertex - trivial case.
+ // 2) F1 | F2 | F3 [|F4 [|Fn]] - redundant definition, but it should be kept as is to obtain safe recomputation
+ // 2) F1 | F2 - intersection of 2 faces definses a vertex - applicable for case
+ // when 1 faces is cylindrical, conical, spherical or revolution and etc.
+ // 3) E1 | E2 | E3 - intersection of 3 edges defines a vertex - when we have case of a shell
+ // or compound of 2 open faces.
+ // 4) E1 | E2 - intesection of 2 edges defines a vertex - when we have a case of
+ // two independent edges (wire or compound)
+ // implemented 2 first cases
+ {
+ TopTools_IndexedDataMapOfShapeListOfShape aMap;
+ TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_FACE, aMap);
+ const TopTools_ListOfShape& aList2 = aMap.FindFromKey(aSubShape);
+ TopTools_ListOfShape aList;
+ TopTools_MapOfShape aFMap;
#ifdef FIX_BUG1
- //int n = aList2.Extent(); //bug! duplication
- // fix is below
- TopTools_ListIteratorOfListOfShape itl2(aList2);
- for (int i = 1;itl2.More();itl2.Next(),i++) {
- if(aFMap.Add(itl2.Value()))
- aList.Append(itl2.Value());
- }
- //n = aList.Extent();
+ //int n = aList2.Extent(); //bug! duplication
+ // fix is below
+ TopTools_ListIteratorOfListOfShape itl2(aList2);
+ for (int i = 1;itl2.More();itl2.Next(),i++) {
+ if(aFMap.Add(itl2.Value()))
+ aList.Append(itl2.Value());
+ }
+ //n = aList.Extent();
#endif
- int n = aList.Extent();
- if(n < 3) { // open topology case or Compound case => via edges
- TopTools_IndexedDataMapOfShapeListOfShape aMap;
- TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_EDGE, aMap);
- const TopTools_ListOfShape& aList22 = aMap.FindFromKey(aSubShape);
- if(aList22.Extent() >= 2) { // regular solution
+ int n = aList.Extent();
- if(n < 3) { // open topology case => via edges
++ if(n < 3) { // open topology case or Compound case => via edges
+ TopTools_IndexedDataMapOfShapeListOfShape aMap;
+ TopExp::MapShapesAndAncestors(aContext, TopAbs_VERTEX, TopAbs_EDGE, aMap);
- const TopTools_ListOfShape& aList2 = aMap.FindFromKey(aSubShape);
- if(aList2.Extent() >= 2) { // regular solution
- TopTools_ListIteratorOfListOfShape itl(aList2);
++ const TopTools_ListOfShape& aList22 = aMap.FindFromKey(aSubShape);
++ if(aList22.Extent() >= 2) { // regular solution
+#ifdef FIX_BUG1
-
- // bug! duplication; fix is below
- aFMap.Clear();
- TopTools_ListOfShape aListE;
- TopTools_ListIteratorOfListOfShape itl2(aList22);
- for (int i = 1;itl2.More();itl2.Next(),i++) {
- if(aFMap.Add(itl2.Value()))
- aListE.Append(itl2.Value());
- }
- n = aListE.Extent();
++
++ // bug! duplication; fix is below
++ aFMap.Clear();
++ TopTools_ListOfShape aListE;
++ TopTools_ListIteratorOfListOfShape itl2(aList22);
++ for (int i = 1;itl2.More();itl2.Next(),i++) {
++ if(aFMap.Add(itl2.Value()))
++ aListE.Append(itl2.Value());
++ }
++ n = aListE.Extent();
+#endif
- TopTools_ListIteratorOfListOfShape itl(aListE);
- for (int i = 1;itl.More();itl.Next(),i++) {
- const TopoDS_Shape& anEdge = itl.Value();
- std::string anEdgeName = GetShapeName(aDoc, anEdge, selectionLabel());
- if(i == 1)
- aName = anEdgeName;
- else
- aName += "|" + anEdgeName;
- }
- }//reg
- else { // dangle vertex: if(aList22.Extent() == 1)
- //it should be already in DF
- }
- }
- else {
- TopTools_ListIteratorOfListOfShape itl(aList);
- for (int i = 1;itl.More();itl.Next(),i++) {
- const TopoDS_Shape& aFace = itl.Value();
- std::string aFaceName = GetShapeName(aDoc, aFace, selectionLabel());
- if(i == 1)
- aName = aFaceName;
- else
- aName += "|" + aFaceName;
- }
- }
- }
- break;
- }
++ TopTools_ListIteratorOfListOfShape itl(aListE);
+ for (int i = 1;itl.More();itl.Next(),i++) {
+ const TopoDS_Shape& anEdge = itl.Value();
+ std::string anEdgeName = GetShapeName(aDoc, anEdge, selectionLabel());
+ if(i == 1)
+ aName = anEdgeName;
+ else
+ aName += "|" + anEdgeName;
+ }
++ }//reg
++ else { // dangle vertex: if(aList22.Extent() == 1)
++ //it should be already in DF
+ }
+ }
+ else {
+ TopTools_ListIteratorOfListOfShape itl(aList);
+ for (int i = 1;itl.More();itl.Next(),i++) {
+ const TopoDS_Shape& aFace = itl.Value();
+ std::string aFaceName = GetShapeName(aDoc, aFace, selectionLabel());
+ if(i == 1)
+ aName = aFaceName;
+ else
+ aName += "|" + aFaceName;
+ }
+ }
+ }
+ break;
+ }
// register name
// aDoc->addNamingName(selectionLabel(), aName);
- // the selected sub-shape will not be shared and as result it will not require registration
+ // the selected sub-shape will not be shared and as result it will not require registration
}
return aName;
}
}
}
-void Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
+AttributePtr Model_Data::addAttribute(const std::string& theID, const std::string theAttrType)
{
+ AttributePtr aResult;
TDF_Label anAttrLab = myLab.FindChild(myAttrs.size() + 1);
ModelAPI_Attribute* anAttr = 0;
- if (theAttrType == ModelAPI_AttributeDocRef::type()) {
+ if (theAttrType == ModelAPI_AttributeDocRef::typeId()) {
anAttr = new Model_AttributeDocRef(anAttrLab);
- } else if (theAttrType == Model_AttributeInteger::type()) {
+ } else if (theAttrType == Model_AttributeInteger::typeId()) {
anAttr = new Model_AttributeInteger(anAttrLab);
- } else if (theAttrType == ModelAPI_AttributeDouble::type()) {
+ } else if (theAttrType == ModelAPI_AttributeDouble::typeId()) {
anAttr = new Model_AttributeDouble(anAttrLab);
- } else if (theAttrType == Model_AttributeBoolean::type()) {
+ } else if (theAttrType == Model_AttributeBoolean::typeId()) {
anAttr = new Model_AttributeBoolean(anAttrLab);
- } else if (theAttrType == Model_AttributeString::type()) {
+ } else if (theAttrType == Model_AttributeString::typeId()) {
anAttr = new Model_AttributeString(anAttrLab);
- } else if (theAttrType == ModelAPI_AttributeReference::type()) {
+ } else if (theAttrType == ModelAPI_AttributeReference::typeId()) {
anAttr = new Model_AttributeReference(anAttrLab);
- } else if (theAttrType == ModelAPI_AttributeSelection::type()) {
+ } else if (theAttrType == ModelAPI_AttributeSelection::typeId()) {
anAttr = new Model_AttributeSelection(anAttrLab);
- } else if (theAttrType == ModelAPI_AttributeSelectionList::type()) {
+ } else if (theAttrType == ModelAPI_AttributeSelectionList::typeId()) {
anAttr = new Model_AttributeSelectionList(anAttrLab);
- } else if (theAttrType == ModelAPI_AttributeRefAttr::type()) {
+ } else if (theAttrType == ModelAPI_AttributeRefAttr::typeId()) {
anAttr = new Model_AttributeRefAttr(anAttrLab);
- } else if (theAttrType == ModelAPI_AttributeRefList::type()) {
+ } else if (theAttrType == ModelAPI_AttributeRefList::typeId()) {
anAttr = new Model_AttributeRefList(anAttrLab);
- } else if (theAttrType == ModelAPI_AttributeIntArray::type()) {
++ } else if (theAttrType == ModelAPI_AttributeIntArray::typeId()) {
+ anAttr = new Model_AttributeIntArray(anAttrLab);
}
// create also GeomData attributes here because only here the OCAF strucure is known
- else if (theAttrType == GeomData_Point::type()) {
+ else if (theAttrType == GeomData_Point::typeId()) {
anAttr = new GeomData_Point(anAttrLab);
- } else if (theAttrType == GeomData_Dir::type()) {
+ } else if (theAttrType == GeomData_Dir::typeId()) {
anAttr = new GeomData_Dir(anAttrLab);
- } else if (theAttrType == GeomData_Point2D::type()) {
+ } else if (theAttrType == GeomData_Point2D::typeId()) {
anAttr = new GeomData_Point2D(anAttrLab);
}
if (anAttr) {
setIsConcealed(false);
}
- aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::type());
+void Model_ResultBody::initAttributes()
+{
+ // append the color attribute. It is empty, the attribute will be filled by a request
+ DataPtr aData = data();
++ aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId());
+}
+
+void Model_ResultBody::colorConfigInfo(std::string& theSection, std::string& theName,
+ std::string& theDefault)
+{
+ theSection = "Visualization";
+ theName = "result_body_color";
+ theDefault = DEFAULT_COLOR();
+}
+
void Model_ResultBody::store(const std::shared_ptr<GeomAPI_Shape>& theShape)
{
std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
#include <Model_ResultConstruction.h>
- aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::type());
+#include <ModelAPI_AttributeIntArray.h>
+#include <Config_PropManager.h>
+#include <GeomAPI_PlanarEdges.h>
+#include <GeomAlgoAPI_SketchBuilder.h>
+
+void Model_ResultConstruction::initAttributes()
+{
+ // append the color attribute. It is empty, the attribute will be filled by a request
+ DataPtr aData = data();
++ aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId());
+}
+
+void Model_ResultConstruction::colorConfigInfo(std::string& theSection, std::string& theName,
+ std::string& theDefault)
+{
+ theSection = "Visualization";
+ theName = "result_construction_color";
+ theDefault = DEFAULT_COLOR();
+}
+
void Model_ResultConstruction::setShape(std::shared_ptr<GeomAPI_Shape> theShape)
{
- myShape = theShape;
+ if (myShape != theShape && (!theShape.get() || !theShape->isEqual(myShape))) {
+ myShape = theShape;
+ if (theShape.get()) {
+ myFacesUpToDate = false;
+ myFaces.clear();
+ }
+ }
}
std::shared_ptr<GeomAPI_Shape> Model_ResultConstruction::shape()
myOwnerData = theOwnerData;
}
- aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::type());
+void Model_ResultGroup::initAttributes()
+{
+ // append the color attribute. It is empty, the attribute will be filled by a request
+ DataPtr aData = data();
++ aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId());
+}
+
+void Model_ResultGroup::colorConfigInfo(std::string& theSection, std::string& theName,
+ std::string& theDefault)
+{
+ theSection = "Visualization";
+ theName = "result_group_color";
+ theDefault = DEFAULT_COLOR();
+}
+
std::shared_ptr<GeomAPI_Shape> Model_ResultGroup::shape()
{
std::shared_ptr<GeomAPI_Shape> aResult;
--- /dev/null
- return type();
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModelAPI_AttributeIntArray.cpp
+// Created: 6 Mar 2015
+// Author: Natalia ERMOLAEVA
+
+#include <ModelAPI_AttributeIntArray.h>
+
+
+std::string ModelAPI_AttributeIntArray::attributeType()
+{
++ return typeId();
+}
+
+/// To virtually destroy the fields of successors
+ModelAPI_AttributeIntArray::~ModelAPI_AttributeIntArray()
+{
+}
+
+ModelAPI_AttributeIntArray::ModelAPI_AttributeIntArray()
+{
+}
--- /dev/null
- MODELAPI_EXPORT static std::string type()
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D
+
+// File: ModelAPI_AttributeIntArray.h
+// Created: 6 Mar 2015
+// Author: Natalia ERMOLAEVA
+
+#ifndef ModelAPI_AttributeIntArray_H_
+#define ModelAPI_AttributeIntArray_H_
+
+#include <ModelAPI.h>
+#include <ModelAPI_Attribute.h>
+
+#include <string>
+
+
+/**\class ModelAPI_AttributeIntArray
+ * \ingroup DataModel
+ * \brief API for the attribute that contains several integers in the array inside.
+ * Used for RGB color storage for an example. By default size is one, zero-based.
+ */
+
+class ModelAPI_AttributeIntArray : public ModelAPI_Attribute
+{
+ public:
+
+ /// Returns the size of the array (zero means that it is empty)
+ MODELAPI_EXPORT virtual int size() = 0;
+
+ /// Sets the new size of the array. The previous data is erased.
+ MODELAPI_EXPORT virtual void setSize(const int theSize) = 0;
+
+ /// Defines the value of the array by index [0; size-1]
+ MODELAPI_EXPORT virtual void setValue(const int theIndex,
+ const int theValue) = 0;
+
+ /// Returns the value by the index
+ MODELAPI_EXPORT virtual int value(const int theIndex) = 0;
+
+ /// Returns the type of this class of attributes
++ MODELAPI_EXPORT static std::string typeId()
+ {
+ return "IntArray";
+ }
+
+ /// Returns the type of this class of attributes, not static method
+ MODELAPI_EXPORT virtual std::string attributeType();
+
+ /// To virtually destroy the fields of successors
+ MODELAPI_EXPORT virtual ~ModelAPI_AttributeIntArray();
+
+ protected:
+ /// Objects are created for features automatically
+ MODELAPI_EXPORT ModelAPI_AttributeIntArray();
+};
+
+//! Pointer on double attribute
+typedef std::shared_ptr<ModelAPI_AttributeIntArray> AttributeIntArrayPtr;
+
+#endif
std::string aCurrentAttributeId = theAttribute->id();
// get all feature attributes
std::list<AttributePtr> anAttrs =
- aFeature->data()->attributes(ModelAPI_AttributeSelection::type());
- theFeature->data()->attributes(ModelAPI_AttributeSelection::typeId());
- if (anAttrs.size() > 0 && theShape.get() != NULL) {
++ aFeature->data()->attributes(ModelAPI_AttributeSelection::typeId());
+ if (anAttrs.size() > 0 && aShape.get() != NULL) {
std::list<AttributePtr>::iterator anAttr = anAttrs.begin();
for(; anAttr != anAttrs.end(); anAttr++) {
AttributePtr anAttribute = *anAttr;
return false;
}
-
-std::shared_ptr<ModelAPI_Document> ModuleBase_Operation::document() const
-{
- return ModelAPI_Session::get()->moduleDocument();
-}
-
-
void ModuleBase_Operation::start()
{
- ModelAPI_Session::get()->startOperation();
+ QString anId = getDescription()->operationId();
+ if (myIsEditing) {
+ anId = anId.append(EditSuffix());
+ }
+ ModelAPI_Session::get()->startOperation(anId.toStdString());
- if (!myIsEditing)
- createFeature();
+ if (!myIsEditing) {
+ FeaturePtr aFeature = createFeature();
+ // if the feature is not created, there is no sense to start the operation
+ if (aFeature.get() == NULL) {
+ // it is necessary to abor the operation in the session and emit the aborted signal
+ // in order to update commands status in the workshop, to be exact the feature action
+ // to be unchecked
+ abort();
+ return;
+ }
+ }
startOperation();
emit started();
}
//********************************************************************
-bool ModuleBase_WidgetShapeSelector::isValid(ObjectPtr theObj, std::shared_ptr<GeomAPI_Shape> theShape)
+void ModuleBase_WidgetShapeSelector::restoreAttributeValue(bool theValid)
{
- SessionPtr aMgr = ModelAPI_Session::get();
- ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
- std::list<ModelAPI_Validator*> aValidators;
- std::list<std::list<std::string> > anArguments;
- aFactory->validators(parentID(), attributeID(), aValidators, anArguments);
-
- // Check the type of selected object
- std::list<ModelAPI_Validator*>::iterator aValidator = aValidators.begin();
- bool isValid = true;
- for (; aValidator != aValidators.end(); aValidator++) {
- const ModelAPI_ResultValidator* aResValidator =
- dynamic_cast<const ModelAPI_ResultValidator*>(*aValidator);
- if (aResValidator) {
- isValid = false;
- if (aResValidator->isValid(theObj)) {
- isValid = true;
- break;
- }
- }
+ DataPtr aData = myFeature->data();
+ AttributePtr anAttribute = myFeature->attribute(attributeID());
+
+ setObject(myObject, myShape);
+ AttributeRefAttrPtr aRefAttr = aData->refattr(attributeID());
+ if (aRefAttr) {
+ if (!myIsObject)
+ aRefAttr->setAttr(myRefAttribute);
}
- if (!isValid)
+}
+
+//********************************************************************
+bool ModuleBase_WidgetShapeSelector::setSelection(const Handle_SelectMgr_EntityOwner& theOwner)
+{
+ bool isDone = false;
+
+ ModuleBase_ViewerPrs aPrs;
+ myWorkshop->selection()->fillPresentation(aPrs, theOwner);
+ ObjectPtr aObject = aPrs.object();
+ ObjectPtr aCurrentObject = GeomValidators_Tools::getObject(myFeature->attribute(attributeID()));
+ if ((!aCurrentObject) && (!aObject))
+ return false;
+
+ // Check that the selected object is result (others can not be accepted)
+ ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObject);
+ if (!aRes)
return false;
- // Check the acceptability of the object as attribute
- aValidator = aValidators.begin();
- std::list<std::list<std::string> >::iterator aArgs = anArguments.begin();
- for (; aValidator != aValidators.end(); aValidator++, aArgs++) {
- const ModelAPI_RefAttrValidator* aAttrValidator =
- dynamic_cast<const ModelAPI_RefAttrValidator*>(*aValidator);
- if (aAttrValidator) {
- if (!aAttrValidator->isValid(myFeature, *aArgs, theObj, theShape)) {
+ if (myFeature) {
+ // We can not select a result of our feature
+ const std::list<std::shared_ptr<ModelAPI_Result>>& aResList = myFeature->results();
+ std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aIt;
+ for (aIt = aResList.cbegin(); aIt != aResList.cend(); ++aIt) {
+ if ((*aIt) == aRes)
++// TODO(nds): v1.0.2 (master)
++// // Check the acceptability of the object as attribute
++// aValidator = aValidators.begin();
++// std::list<std::list<std::string> >::iterator aArgs = anArguments.begin();
++// for (; aValidator != aValidators.end(); aValidator++, aArgs++) {
++// const ModelAPI_RefAttrValidator* aAttrValidator =
++// dynamic_cast<const ModelAPI_RefAttrValidator*>(*aValidator);
++// if (aAttrValidator) {
++// if (!aAttrValidator->isValid(myFeature, *aArgs, theObj, theShape)) {
return false;
- }
- }
- else {
- const ModelAPI_ShapeValidator* aShapeValidator =
- dynamic_cast<const ModelAPI_ShapeValidator*>(*aValidator);
- if (aShapeValidator) {
- DataPtr aData = myFeature->data();
- AttributeSelectionPtr aSelectAttr = aData->selection(attributeID());
- if (!aShapeValidator->isValid(myFeature, aSelectAttr, theShape)) {
- return false;
- }
- }
}
}
+ // Check that object belongs to active document or PartSet
+ DocumentPtr aDoc = aRes->document();
+ SessionPtr aMgr = ModelAPI_Session::get();
+ if (!(aDoc == aMgr->activeDocument()) && !(aDoc == aMgr->moduleDocument()))
+ return false;
+
+ // Check that the result has a shape
+ GeomShapePtr aShape = ModelAPI_Tools::shape(aRes);
+ if (!aShape)
+ return false;
+
+ // Get sub-shapes from local selection
+ if (!aPrs.shape().IsNull()) {
+ aShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
+ aShape->setImpl(new TopoDS_Shape(aPrs.shape()));
+ }
+ // Check that the selection corresponds to selection type
+ if (!acceptSubShape(aShape))
+ return false;
+
+ setObject(aObject, aShape);
return true;
-}
+}
+
+//********************************************************************
+void ModuleBase_WidgetShapeSelector::deactivate()
+{
+ activateSelection(false);
+ disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
+}
--- /dev/null
- data()->addAttribute(ParametersPlugin_Parameter::VARIABLE_ID(), ModelAPI_AttributeString::type());
- data()->addAttribute(ParametersPlugin_Parameter::EXPRESSION_ID(), ModelAPI_AttributeString::type());
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: ParametersPlugin_Parameter.cpp
+// Created: 23 MArch 2015
+// Author: sbh
+
+#include "ParametersPlugin_Parameter.h"
+#include <ModelAPI_AttributeString.h>
+
+ParametersPlugin_Parameter::ParametersPlugin_Parameter()
+{
+}
+
+void ParametersPlugin_Parameter::initAttributes()
+{
++ data()->addAttribute(ParametersPlugin_Parameter::VARIABLE_ID(), ModelAPI_AttributeString::typeId());
++ data()->addAttribute(ParametersPlugin_Parameter::EXPRESSION_ID(), ModelAPI_AttributeString::typeId());
+}
+
+void ParametersPlugin_Parameter::execute()
+{
+}
ModuleBase
Config
GeomAPI
+ GeomValidators
+ GeomDataAPI
${QT_LIBRARIES}
${CAS_KERNEL}
${CAS_SHAPE}
new GeomAPI_Pnt2d(theClickedX, theClickedY));
for (; anIt != aLast; anIt++) {
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anIt);
+ if (theFeature == aFeature)
+ continue;
// find the given point in the feature attributes
- anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::type());
+ anAttiributes = aFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
std::list<std::shared_ptr<ModelAPI_Attribute> >::const_iterator anIt = anAttiributes.begin(),
aLast = anAttiributes.end();
std::shared_ptr<GeomDataAPI_Point2D> aFPoint;
return (aCount > 0) && (aCount < 2);
}
-bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature,
- const std::list<std::string>& theArguments,
- const ObjectPtr& theObject,
- const GeomShapePtr& theShape) const
+bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments) const
{
- // Check RefAttr attributes
- std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
- theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
- if (anAttrs.size() > 0) {
- std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
- for(; anAttr != anAttrs.end(); anAttr++) {
- if (*anAttr) {
- std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
- std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
- // check the object is already presented
- if (aRef->isObject() && aRef->object() == theObject)
- return false;
- }
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+
+ // 1. check whether the object of the attribute is not among the feature attributes
+ // find the attribute's object
+ ObjectPtr anObject = GeomValidators_Tools::getObject(theAttribute);
+
+ // check whether the object is not among other feature attributes
+ if (anObject.get() != NULL) {
+ // Check RefAttr attributes
+ std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs = aFeature->data()->attributes("");
+ //if (anAttrs.size() > 0) {
+ std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anIt = anAttrs.begin();
+ for(; anIt != anAttrs.end(); anIt++) {
+ AttributePtr anAttr = *anIt;
+ // the function parameter attribute should be skipped
+ if (anAttr.get() == NULL || anAttr->id() == theAttribute->id())
+ continue;
+ ObjectPtr aCurObject = GeomValidators_Tools::getObject(anAttr);
+ if (aCurObject && aCurObject == anObject)
+ return false;
}
}
- // Check selection attributes
- anAttrs = theFeature->data()->attributes(ModelAPI_AttributeSelection::typeId());
- if (anAttrs.size() > 0) {
- std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
- for(; anAttr != anAttrs.end(); anAttr++) {
- if (*anAttr) {
- std::shared_ptr<ModelAPI_AttributeSelection> aRef =
- std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*anAttr);
- // check the object is already presented
- if (aRef->isInitialized() && aRef->context() == theObject) {
- if (theShape.get() != NULL) {
- if (aRef->value()->isEqual(theShape))
- return false;
- } else
+ else {
+ // 2. collect object referenced by theAttribute and ...
+ if (featureHasReferences(theAttribute)) {
+ // 3. check whether the attribute value is not among other feature attributes
+ std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
- aFeature->data()->attributes(ModelAPI_AttributeRefAttr::type());
++ aFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
+ std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
+ for(; anAttr != anAttrs.end(); anAttr++) {
+ if (*anAttr) {
+ std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
+ std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
+ // check the object is already presented
+ if (!aRef->isObject() && aRef->attr() == theAttribute)
return false;
}
++// TODO(nds) v1.0.2 master
++//bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature,
++// const std::list<std::string>& theArguments,
++// const ObjectPtr& theObject,
++// const GeomShapePtr& theShape) const
++//{
++// // Check RefAttr attributes
++// std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
++// theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
++// if (anAttrs.size() > 0) {
++// std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
++// for(; anAttr != anAttrs.end(); anAttr++) {
++// if (*anAttr) {
++// std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
++// std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
++// // check the object is already presented
++// if (aRef->isObject() && aRef->object() == theObject)
++// return false;
++// }
++// }
++// }
++// // Check selection attributes
++// anAttrs = theFeature->data()->attributes(ModelAPI_AttributeSelection::typeId());
++// if (anAttrs.size() > 0) {
++// std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
++// for(; anAttr != anAttrs.end(); anAttr++) {
++// if (*anAttr) {
++// std::shared_ptr<ModelAPI_AttributeSelection> aRef =
++// std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*anAttr);
++// // check the object is already presented
++// if (aRef->isInitialized() && aRef->context() == theObject) {
++// if (theShape.get() != NULL) {
++// if (aRef->value()->isEqual(theShape))
++// return false;
++// } else
++// return false;
++// }
++// }
++// }
++// }
++// // Check selection attributes
++// anAttrs = theFeature->data()->attributes(ModelAPI_AttributeReference::typeId());
++// if (anAttrs.size() > 0) {
++// std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
++// for(; anAttr != anAttrs.end(); anAttr++) {
++// if (*anAttr) {
++// std::shared_ptr<ModelAPI_AttributeReference> aRef =
++// std::dynamic_pointer_cast<ModelAPI_AttributeReference>(*anAttr);
++// // check the object is already presented
++// if (aRef->isInitialized() && aRef->value() == theObject)
++// return false;
++// ======= end of todo
}
- }
- }
- // Check selection attributes
- anAttrs = theFeature->data()->attributes(ModelAPI_AttributeReference::typeId());
- if (anAttrs.size() > 0) {
- std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
- for(; anAttr != anAttrs.end(); anAttr++) {
- if (*anAttr) {
- std::shared_ptr<ModelAPI_AttributeReference> aRef =
- std::dynamic_pointer_cast<ModelAPI_AttributeReference>(*anAttr);
- // check the object is already presented
- if (aRef->isInitialized() && aRef->value() == theObject)
- return false;
- }
+ return true;
}
}
return true;
}
-bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature,
- const std::list<std::string>& theArguments,
- const AttributePtr& theAttribute) const
-{
- if (PartSet_DifferentObjectsValidator::isValid(theAttribute, theArguments)) {
- std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
- theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
- std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
- for(; anAttr != anAttrs.end(); anAttr++) {
- if (*anAttr) {
- std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
- std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
- // check the object is already presented
- if (!aRef->isObject() && aRef->attr() == theAttribute)
- return false;
- }
- }
- return true;
- }
- return false;
-}
-
-bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute,
- const std::list<std::string>& theArguments) const
+bool PartSet_DifferentObjectsValidator::featureHasReferences(const AttributePtr& theAttribute) const
++// TODO(nds) v1.0.2 master
++//bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature,
++// const std::list<std::string>& theArguments,
++// const AttributePtr& theAttribute) const
++//{
++// if (PartSet_DifferentObjectsValidator::isValid(theAttribute, theArguments)) {
++// std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
++// theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
++// std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
++// for(; anAttr != anAttrs.end(); anAttr++) {
++// if (*anAttr) {
++// std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
++// std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
++// // check the object is already presented
++// if (!aRef->isObject() && aRef->attr() == theAttribute)
++// return false;
++// }
++// }
++// return true;
++// }
++// return false;
++//}
++//
++//bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute,
++// const std::list<std::string>& theArguments) const
++// ======= end of todo
{
std::list<std::pair<std::string, std::list<ObjectPtr> > > allRefs;
if (theAttribute->owner().get() && theAttribute->owner()->data().get())
return true;
}
-bool PartSet_SketchValidator::isValid(const ObjectPtr theObject) const
+bool PartSet_SketchEntityValidator::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments) const
{
- FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
- return aFeature->getKind() == SketchPlugin_Sketch::ID();
+ bool isSketchEntities = true;
+ std::set<std::string> anEntityKinds;
+ std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
+ for (; anIt != aLast; anIt++) {
+ anEntityKinds.insert(*anIt);
+ }
+
+ std::string anAttributeType = theAttribute->attributeType();
- if (anAttributeType == ModelAPI_AttributeSelectionList::type()) {
++ if (anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
+ AttributeSelectionListPtr aSelectionListAttr =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
+ // it filters only selection list attributes
+ std::string aType = aSelectionListAttr->selectionType().c_str();
+ // all context objects should be sketch entities
+ int aSize = aSelectionListAttr->size();
+ for (int i = 0; i < aSelectionListAttr->size() && isSketchEntities; i++) {
+ AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i);
+ ObjectPtr anObject = aSelectAttr->context();
+ FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+ isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
+ }
+ }
- if (anAttributeType == ModelAPI_AttributeRefAttr::type()) {
++ if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
+ std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
+ std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+ isSketchEntities = false;
+ if (aRef->isObject()) {
+ ObjectPtr anObject = aRef->object();
+ if (anObject.get() != NULL) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+ if (aFeature.get() != NULL)
+ isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
+ }
+ }
+ }
+
+ return isSketchEntities;
}
* \ingroup Validators
* A validator which checks that objects selected for feature attributes are different (not the same)
*/
-class PartSet_DifferentObjectsValidator : public ModelAPI_RefAttrValidator
+class PartSet_DifferentObjectsValidator : public ModelAPI_AttributeValidator
{
public:
- /// Returns True if the feature is valid
- /// \param theFeature a feature to check
- /// \param theArguments a list of arguments (names of attributes to check)
- /// \param theObject a selected object
- /// \param theShape a selected sub-shape
- virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
- const ObjectPtr& theObject, const GeomShapePtr& theShape) const;
-
- //! Returns true if the attribute is good for the feature attribute
- //! \param theFeature a feature to check
- //! \param theArguments a list of arguments (names of attributes to check)
- //! \param theAttribute an attribute
- virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
- const AttributePtr& theAttribute) const;
-
++// TODO(nds) v1.0.2 master
++// /// Returns True if the feature is valid
++// /// \param theFeature a feature to check
++// /// \param theArguments a list of arguments (names of attributes to check)
++// /// \param theObject a selected object
++// /// \param theShape a selected sub-shape
++// virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
++// const ObjectPtr& theObject, const GeomShapePtr& theShape) const;
++//
++// //! Returns true if the attribute is good for the feature attribute
++// //! \param theFeature a feature to check
++// //! \param theArguments a list of arguments (names of attributes to check)
++// //! \param theAttribute an attribute
++// virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
++// const AttributePtr& theAttribute) const;
++ // ======= end of todo
//! Returns true if the attribute is good for the feature attribute
//! \param theAttribute an attribute
//! \param theArguments a list of arguments (names of attributes to check)
/**
* \ingroup Validators
-* A Validator which validates tha selected object is a Sketch
+* A validator which checks that objects selected for feature attributes are different (not the same)
*/
-class PartSet_SketchValidator : public ModelAPI_ResultValidator
+class PartSet_SketchEntityValidator : public ModelAPI_AttributeValidator
{
public:
- /// Returns True if the given object is a sketch
- /// \param theObject an object
- virtual bool isValid(const ObjectPtr theObject) const;
+ //! Returns true if the attribute is good for the feature attribute
+ //! \param theAttribute an attribute
+ //! \param theArguments a list of arguments (names of attributes to check)
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments) const;
};
- #endif
-
+ #endif
}
//********************************************************************
-bool PartSet_WidgetShapeSelector::isValid(ObjectPtr theObj, std::shared_ptr<GeomAPI_Shape> theShape)
+void PartSet_WidgetShapeSelector::storeAttributeValue()
{
- // the method is redefined to analize the selected shape in validators
- SessionPtr aMgr = ModelAPI_Session::get();
- ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
- std::list<ModelAPI_Validator*> aValidators;
- std::list<std::list<std::string> > anArguments;
- aFactory->validators(parentID(), attributeID(), aValidators, anArguments);
+ /// this is a temporary code, will be removed when master is merged to this branch
+ /*XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
+ XGUI_Workshop* aWorkshop = aConnector->workshop();
+ aWorkshop->displayer()->enableUpdateViewer(false);
+ */
+ ModuleBase_WidgetShapeSelector::storeAttributeValue();
+}
- // Check the type of selected object
- std::list<ModelAPI_Validator*>::iterator aValidator = aValidators.begin();
- bool isValid = true;
- for (; aValidator != aValidators.end(); aValidator++) {
- const ModelAPI_ResultValidator* aResValidator =
- dynamic_cast<const ModelAPI_ResultValidator*>(*aValidator);
- if (aResValidator) {
- isValid = false;
- if (aResValidator->isValid(theObj)) {
- isValid = true;
- break;
- }
- }
- }
- if (!isValid)
- return false;
+//********************************************************************
+void PartSet_WidgetShapeSelector::restoreAttributeValue(const bool theValid)
+{
+ ModuleBase_WidgetShapeSelector::restoreAttributeValue(theValid);
+ /// this is a temporary code, will be removed when master is merged to this branch
+ /// after merge, the external edge should be removed always, without flag checking
+ if (!theValid)
+ removeExternal();
+ /*
+ XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
+ XGUI_Workshop* aWorkshop = aConnector->workshop();
+ aWorkshop->displayer()->enableUpdateViewer(false);//->erase(myExternalObject);
+ aWorkshop->displayer()->enableUpdateViewer(true);*/
+}
- // Check the acceptability of the object and shape as validator attribute
- AttributePtr aPntAttr;
- DataPtr aData = myFeature->data();
- if (theShape.get() != NULL) {
- AttributePtr aAttr = aData->attribute(attributeID());
- AttributeRefAttrPtr aRefAttr =
- std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aAttr);
- if (aRefAttr) {
- TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
- aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theObj, aShape, mySketch);
- }
- }
- // Check the acceptability of the object as attribute
- aValidator = aValidators.begin();
- std::list<std::list<std::string> >::iterator aArgs = anArguments.begin();
- for (; aValidator != aValidators.end(); aValidator++, aArgs++) {
- const ModelAPI_RefAttrValidator* aAttrValidator =
- dynamic_cast<const ModelAPI_RefAttrValidator*>(*aValidator);
- if (aAttrValidator) {
- if (aPntAttr.get() != NULL)
- {
- if (!aAttrValidator->isValid(myFeature, *aArgs, aPntAttr)) {
- return false;
- }
- }
- else
- {
- if (!aAttrValidator->isValid(myFeature, *aArgs, theObj, theShape)) {
- return false;
- }
- }
- }
+//********************************************************************
+void PartSet_WidgetShapeSelector::createExternal(ObjectPtr theSelectedObject,
+ GeomShapePtr theShape)
+{
+ ObjectPtr aObj = PartSet_Tools::createFixedObjectByExternal(theShape->impl<TopoDS_Shape>(),
+ theSelectedObject, mySketch);
+ if (aObj != myExternalObject) {
+ removeExternal();
+ myExternalObject = aObj;
++// TODO(nds) v1.0.2 master
++// // Check the acceptability of the object and shape as validator attribute
++// AttributePtr aPntAttr;
++// DataPtr aData = myFeature->data();
++// if (theShape.get() != NULL) {
++// AttributePtr aAttr = aData->attribute(attributeID());
++// AttributeRefAttrPtr aRefAttr =
++// std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aAttr);
++// if (aRefAttr) {
++// TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
++// aPntAttr = PartSet_Tools::findAttributeBy2dPoint(theObj, aShape, mySketch);
++// }
++// }
++// // Check the acceptability of the object as attribute
++// aValidator = aValidators.begin();
++// std::list<std::list<std::string> >::iterator aArgs = anArguments.begin();
++// for (; aValidator != aValidators.end(); aValidator++, aArgs++) {
++// const ModelAPI_RefAttrValidator* aAttrValidator =
++// dynamic_cast<const ModelAPI_RefAttrValidator*>(*aValidator);
++// if (aAttrValidator) {
++// if (aPntAttr.get() != NULL)
++// {
++// if (!aAttrValidator->isValid(myFeature, *aArgs, aPntAttr)) {
++// return false;
++// }
++// }
++// else
++// {
++// if (!aAttrValidator->isValid(myFeature, *aArgs, theObj, theShape)) {
++// return false;
++// }
++// }
++// }
++// ======= end of todo
}
- return true;
}
-//*********************************************
-bool PartSet_WidgetConstraintShapeSelector::storeValue() const
+//********************************************************************
+void PartSet_WidgetShapeSelector::removeExternal()
{
- FeaturePtr aFeature = ModelAPI_Feature::feature(mySelectedObject);
- if (aFeature) {
- std::shared_ptr<SketchPlugin_Feature> aSPFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(aFeature);
- if ((!aSPFeature) && (!myShape->isNull())) {
- ObjectPtr aObj = PartSet_Tools::createFixedObjectByEdge(myShape->impl<TopoDS_Shape>(),
- mySelectedObject, mySketch);
- if (aObj) {
- PartSet_WidgetConstraintShapeSelector* that = (PartSet_WidgetConstraintShapeSelector*) this;
- that->mySelectedObject = aObj;
- } else
- return false;
+ if (myExternalObject.get()) {
+ DocumentPtr aDoc = myExternalObject->document();
+ FeaturePtr aFeature = ModelAPI_Feature::feature(myExternalObject);
+ if (aFeature.get() != NULL) {
+ aDoc->removeFeature(aFeature);
}
+ myExternalObject = NULL;
}
- return ModuleBase_WidgetShapeSelector::storeValue();
}
Config
GeomAPI
GeomAlgoAPI
+ GeomValidators
ModelAPI
+ SketcherPrs
+ GeomDataAPI
${CAS_KERNEL}
${CAS_SHAPE}
)
void SketchPlugin_Arc::initAttributes()
{
- data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::type());
- data()->addAttribute(START_ID(), GeomDataAPI_Point2D::type());
- data()->addAttribute(END_ID(), GeomDataAPI_Point2D::type());
- data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
+ SketchPlugin_SketchEntity::initAttributes();
+
+ data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId());
+ data()->addAttribute(START_ID(), GeomDataAPI_Point2D::typeId());
+ data()->addAttribute(END_ID(), GeomDataAPI_Point2D::typeId());
+ data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
}
void SketchPlugin_Circle::initAttributes()
{
- data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::type());
- data()->addAttribute(RADIUS_ID(), ModelAPI_AttributeDouble::type());
- data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
+ SketchPlugin_SketchEntity::initAttributes();
+
+ data()->addAttribute(CENTER_ID(), GeomDataAPI_Point2D::typeId());
+ data()->addAttribute(RADIUS_ID(), ModelAPI_AttributeDouble::typeId());
+ data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
}
{
}
- }
+AISObjectPtr SketchPlugin_ConstraintCoincidence::getAISObject(AISObjectPtr thePrevious)
+{
+ if (!sketch())
+ return thePrevious;
+
+ AISObjectPtr anAIS = thePrevious;
+ if (!anAIS) {
+ anAIS = SketcherPrs_Factory::coincidentConstraint(this, sketch()->coordinatePlane());
+ anAIS->setColor(0, 0, 255);
+ }
+ return anAIS;
++}
--- /dev/null
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: SketchPlugin_ConstraintEqual.cpp
+// Created: 16 Mar 2015
+// Author: Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintEqual.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_ResultConstruction.h>
+
+#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Sketch.h>
+
+#include <SketcherPrs_Factory.h>
+
+#include <Config_PropManager.h>
+
+SketchPlugin_ConstraintEqual::SketchPlugin_ConstraintEqual()
+{
+}
+
+void SketchPlugin_ConstraintEqual::initAttributes()
+{
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
+}
+
+void SketchPlugin_ConstraintEqual::execute()
+{
+}
+
+AISObjectPtr SketchPlugin_ConstraintEqual::getAISObject(AISObjectPtr thePrevious)
+{
+ if (!sketch())
+ return thePrevious;
+
+ AISObjectPtr anAIS = thePrevious;
+ if (!anAIS) {
+ anAIS = SketcherPrs_Factory::equalConstraint(this, sketch()->coordinatePlane());
+ }
+ return anAIS;
+}
+
+
--- /dev/null
- data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::type());
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::type());
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: SketchPlugin_ConstraintFillet.cpp
+// Created: 19 Mar 2015
+// Author: Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintFillet.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_AttributeRefAttr.h>
+#include <ModelAPI_AttributeRefList.h>
+#include <ModelAPI_Session.h>
+
+#include <SketchPlugin_Arc.h>
+#include <SketchPlugin_Sketch.h>
+
+#include <SketcherPrs_Factory.h>
+
+#include <Config_PropManager.h>
+
+SketchPlugin_ConstraintFillet::SketchPlugin_ConstraintFillet()
+{
+}
+
+void SketchPlugin_ConstraintFillet::initAttributes()
+{
++ data()->addAttribute(SketchPlugin_Constraint::VALUE(), ModelAPI_AttributeDouble::typeId());
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::typeId());
+ // initialize attribute not applicable for user
+ data()->attribute(SketchPlugin_Constraint::ENTITY_C())->setInitialized();
+}
+
+void SketchPlugin_ConstraintFillet::execute()
+{
+ std::shared_ptr<ModelAPI_Data> aData = data();
+ // Check the base objects are initialized
+ AttributeRefAttrPtr aBaseA = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ AttributeRefAttrPtr aBaseB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ if (!aBaseA->isInitialized() || !aBaseB->isInitialized() ||
+ !aBaseA->isObject() || !aBaseB->isObject())
+ return;
+ // Check the fillet shapes is not initialized yet
+ AttributeRefListPtr aRefListOfFillet = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+ aData->attribute(SketchPlugin_Constraint::ENTITY_C()));
+ if (aRefListOfFillet->size() > 0)
+ return;
+ // Obtain features for the base objects
+ FeaturePtr aFeatureA, aFeatureB;
+ ResultConstructionPtr aRC =
+ std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aBaseA->object());
+ if (aRC) aFeatureA = aRC->document()->feature(aRC);
+ aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aBaseB->object());
+ if (aRC) aFeatureB = aRC->document()->feature(aRC);
+ if (!aFeatureA || !aFeatureB)
+ return;
+
+ // Create list of objects composing a fillet
+ // copy aFeatureA
+ FeaturePtr aNewFeature = sketch()->addFeature(aFeatureA->getKind());
+ aFeatureA->data()->copyTo(aNewFeature->data());
+ aRefListOfFillet->append(aNewFeature);
+ // copy aFeatureB
+ aNewFeature = sketch()->addFeature(aFeatureB->getKind());
+ aFeatureB->data()->copyTo(aNewFeature->data());
+ aRefListOfFillet->append(aNewFeature);
+ // create filleting arc
+ aNewFeature = sketch()->addFeature(SketchPlugin_Arc::ID());
+ aNewFeature->attribute(SketchPlugin_Arc::CENTER_ID())->setInitialized();
+ aNewFeature->attribute(SketchPlugin_Arc::START_ID())->setInitialized();
+ aNewFeature->attribute(SketchPlugin_Arc::END_ID())->setInitialized();
+ aRefListOfFillet->append(aNewFeature);
+ aRefListOfFillet->setInitialized();
+}
+
+AISObjectPtr SketchPlugin_ConstraintFillet::getAISObject(AISObjectPtr thePrevious)
+{
+ if (!sketch())
+ return thePrevious;
+
+ AISObjectPtr anAIS = thePrevious;
+ /// TODO: Equal constraint presentation should be put here
+ return anAIS;
+}
+
+
--- /dev/null
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: SketchPlugin_ConstraintHorizontal.cpp
+// Created: 16 Mar 2015
+// Author: Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintHorizontal.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_ResultConstruction.h>
+
+#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Sketch.h>
+
+#include <SketcherPrs_Factory.h>
+
+#include <Config_PropManager.h>
+
+SketchPlugin_ConstraintHorizontal::SketchPlugin_ConstraintHorizontal()
+{
+}
+
+void SketchPlugin_ConstraintHorizontal::initAttributes()
+{
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
+}
+
+void SketchPlugin_ConstraintHorizontal::execute()
+{
+}
+
+AISObjectPtr SketchPlugin_ConstraintHorizontal::getAISObject(AISObjectPtr thePrevious)
+{
+ if (!sketch())
+ return thePrevious;
+
+ AISObjectPtr anAIS = thePrevious;
+ if (!anAIS) {
+ anAIS = SketcherPrs_Factory::horisontalConstraint(this, sketch()->coordinatePlane());
+ }
+ return anAIS;
+}
+
+
--- /dev/null
- 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());
+// 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::typeId());
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefList::typeId());
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefList::typeId());
+}
+
+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;
+}
+
+
void SketchPlugin_ConstraintParallel::initAttributes()
{
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
- //data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::type());
+ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
+ data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
- data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::typeId());
++ //data()->addAttribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT(), GeomDataAPI_Point2D::typeId());
}
void SketchPlugin_ConstraintParallel::execute()
--- /dev/null
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: SketchPlugin_ConstraintTangent.cpp
+// Created: 16 Mar 2015
+// Author: Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintTangent.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_ResultConstruction.h>
+
+#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Sketch.h>
+
+#include <SketcherPrs_Factory.h>
+
+#include <Config_PropManager.h>
+
+SketchPlugin_ConstraintTangent::SketchPlugin_ConstraintTangent()
+{
+}
+
+void SketchPlugin_ConstraintTangent::initAttributes()
+{
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
+}
+
+void SketchPlugin_ConstraintTangent::execute()
+{
+}
+
+AISObjectPtr SketchPlugin_ConstraintTangent::getAISObject(AISObjectPtr thePrevious)
+{
+ if (!sketch())
+ return thePrevious;
+
+ AISObjectPtr anAIS = thePrevious;
+ if (!anAIS) {
+ anAIS = SketcherPrs_Factory::tangentConstraint(this, sketch()->coordinatePlane());
+ }
+ return anAIS;
+}
+
+
--- /dev/null
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+// File: SketchPlugin_ConstraintVertical.cpp
+// Created: 16 Mar 2015
+// Author: Artem ZHIDKOV
+
+#include "SketchPlugin_ConstraintVertical.h"
+
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_ResultConstruction.h>
+
+#include <SketchPlugin_Line.h>
+#include <SketchPlugin_Sketch.h>
+
+#include <SketcherPrs_Factory.h>
+
+#include <Config_PropManager.h>
+
+SketchPlugin_ConstraintVertical::SketchPlugin_ConstraintVertical()
+{
+}
+
+void SketchPlugin_ConstraintVertical::initAttributes()
+{
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
+}
+
+void SketchPlugin_ConstraintVertical::execute()
+{
+}
+
+AISObjectPtr SketchPlugin_ConstraintVertical::getAISObject(AISObjectPtr thePrevious)
+{
+ if (!sketch())
+ return thePrevious;
+
+ AISObjectPtr anAIS = thePrevious;
+ if (!anAIS) {
+ anAIS = SketcherPrs_Factory::verticalConstraint(this, sketch()->coordinatePlane());
+ }
+ return anAIS;
+}
+
+
void SketchPlugin_Line::initAttributes()
{
- data()->addAttribute(START_ID(), GeomDataAPI_Point2D::type());
- data()->addAttribute(END_ID(), GeomDataAPI_Point2D::type());
- data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
+ SketchPlugin_SketchEntity::initAttributes();
+
+ data()->addAttribute(START_ID(), GeomDataAPI_Point2D::typeId());
+ data()->addAttribute(END_ID(), GeomDataAPI_Point2D::typeId());
+ data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
}
new SketchPlugin_DistanceAttrValidator);
//aFactory->registerValidator("SketchPlugin_DifferentObjects",
// new SketchPlugin_DifferentObjectsValidator);
-
- aFactory->registerValidator("SketchPlugin_ShapeValidator",
- new SketchPlugin_ShapeValidator);
- aFactory->registerValidator("SketchPlugin_ResultPoint", new SketchPlugin_ResultPointValidator);
- aFactory->registerValidator("SketchPlugin_ResultLine", new SketchPlugin_ResultLineValidator);
- aFactory->registerValidator("SketchPlugin_ResultArc", new SketchPlugin_ResultArcValidator);
++ aFactory->registerValidator("SketchPlugin_ShapeValidator", new SketchPlugin_ShapeValidator);
// register this plugin
ModelAPI_Session::get()->registerPlugin(this);
void SketchPlugin_Point::initAttributes()
{
- data()->addAttribute(SketchPlugin_Point::COORD_ID(), GeomDataAPI_Point2D::type());
- data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
+ SketchPlugin_SketchEntity::initAttributes();
+
+ data()->addAttribute(SketchPlugin_Point::COORD_ID(), GeomDataAPI_Point2D::typeId());
+ data()->addAttribute(EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), EXTERNAL_ID());
}
void SketchPlugin_Sketch::initAttributes()
{
- data()->addAttribute(SketchPlugin_Sketch::ORIGIN_ID(), GeomDataAPI_Point::type());
- data()->addAttribute(SketchPlugin_Sketch::DIRX_ID(), GeomDataAPI_Dir::type());
- data()->addAttribute(SketchPlugin_Sketch::NORM_ID(), GeomDataAPI_Dir::type());
- data()->addAttribute(SketchPlugin_Sketch::FEATURES_ID(), ModelAPI_AttributeRefList::type());
+ data()->addAttribute(SketchPlugin_Sketch::ORIGIN_ID(), GeomDataAPI_Point::typeId());
+ data()->addAttribute(SketchPlugin_Sketch::DIRX_ID(), GeomDataAPI_Dir::typeId());
- data()->addAttribute(SketchPlugin_Sketch::DIRY_ID(), GeomDataAPI_Dir::typeId());
+ data()->addAttribute(SketchPlugin_Sketch::NORM_ID(), GeomDataAPI_Dir::typeId());
+ data()->addAttribute(SketchPlugin_Sketch::FEATURES_ID(), ModelAPI_AttributeRefList::typeId());
// the selected face, base for the sketcher plane, not obligatory
- data()->addAttribute(SketchPlugin_SketchEntity::EXTERNAL_ID(), ModelAPI_AttributeSelection::type());
- data()->addAttribute(SketchPlugin_Feature::EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
++ data()->addAttribute(SketchPlugin_SketchEntity::EXTERNAL_ID(), ModelAPI_AttributeSelection::typeId());
ModelAPI_Session::get()->validators()->registerNotObligatory(
- getKind(), SketchPlugin_Feature::EXTERNAL_ID());
+ getKind(), SketchPlugin_SketchEntity::EXTERNAL_ID());
}
void SketchPlugin_Sketch::execute()
--- /dev/null
- data()->addAttribute(AUXILIARY_ID(), ModelAPI_AttributeBoolean::type());
+// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
+
+#include "SketchPlugin_SketchEntity.h"
+
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Validator.h>
+#include <ModelAPI_AttributeIntArray.h>
+
+SketchPlugin_SketchEntity::SketchPlugin_SketchEntity()
+: SketchPlugin_Feature()
+{
+}
+
+void SketchPlugin_SketchEntity::initAttributes()
+{
++ data()->addAttribute(AUXILIARY_ID(), ModelAPI_AttributeBoolean::typeId());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), AUXILIARY_ID());
+}
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_AttributeRefAttr.h>
#include <ModelAPI_Session.h>
+
+#include <GeomValidators_Edge.h>
+
#include <GeomDataAPI_Point2D.h>
-bool SketchPlugin_DistanceAttrValidator::isValid(const FeaturePtr& theFeature,
- const std::list<std::string>& theArguments,
- const ObjectPtr& theObject,
- const GeomShapePtr& theShape) const
+bool SketchPlugin_DistanceAttrValidator::isValid(
+ const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
++//bool SketchPlugin_DistanceAttrValidator::isValid(const FeaturePtr& theFeature,
++// const std::list<std::string>& theArguments,
++// const ObjectPtr& theObject,
++// const GeomShapePtr& theShape) const
++// ======= end of todo master
{
+ // there is a check whether the feature contains a point and a linear edge or two point values
std::string aParamA = theArguments.front();
SessionPtr aMgr = ModelAPI_Session::get();
ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
- const ModelAPI_ResultValidator* anArcValidator =
- dynamic_cast<const ModelAPI_ResultValidator*>(aFactory->validator("SketchPlugin_ResultArc"));
- bool anArcValid = anArcValidator->isValid(theObject);
- if (anArcValid)
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+ if (!aRefAttr)
return false;
-
- // If the object is not a line then it is accepted
- const ModelAPI_ResultValidator* aLineValidator =
- dynamic_cast<const ModelAPI_ResultValidator*>(aFactory->validator("SketchPlugin_ResultLine"));
- bool aLineValid = aLineValidator->isValid(theObject);
- if (!aLineValid)
+ bool isObject = aRefAttr->isObject();
+ if (!isObject) {
+ // an attribute is a point. A point value is valid always for the distance
return true;
+ } else {
+ // 1. check whether the references object is a linear
+ ObjectPtr anObject = aRefAttr->object();
- // If it is a line then we have to check that first attribute id not a line
- std::shared_ptr<GeomDataAPI_Point2D> aPoint = getFeaturePoint(theFeature->data(), aParamA);
- if (aPoint)
- return true;
- return false;
-}
+ const ModelAPI_AttributeValidator* anEdgeValidator =
+ dynamic_cast<const GeomValidators_Edge*>(aFactory->validator("GeomValidators_Edge"));
+ std::list<std::string> anArguments;
+ anArguments.push_back("circle");
+ bool anEdgeValid = anEdgeValidator->isValid(aRefAttr, anArguments);
+ // the circle line is not a valid case
+ if (anEdgeValid)
+ return false;
+
+ anArguments.clear();
+ anArguments.push_back("line");
+ anEdgeValid = anEdgeValidator->isValid(aRefAttr, anArguments);
+ // if the attribute value is not a line, that means it is a vertex. A vertex is always valid
+ if (!anEdgeValid)
+ return true;
-bool SketchPlugin_DistanceAttrValidator::isValid(
- const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
-{
- // any point attribute is acceptable for the distance operation
- return true;
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+ // If it is a line then we have to check that first attribute id not a line
+ std::shared_ptr<GeomDataAPI_Point2D> aPoint = getFeaturePoint(aFeature->data(), aParamA);
+ if (aPoint)
+ return true;
+ }
+ return false;
}
-bool SketchPlugin_DistanceAttrValidator::isValid(const FeaturePtr& theFeature,
- const std::list<std::string>& theArguments,
- const AttributePtr& theAttribute) const
-{
- return isValid(theAttribute, theArguments);
-}
++// TODO(nds) v1.0.2, master
++// return false;
++//}
+
++//bool SketchPlugin_DistanceAttrValidator::isValid(
++// const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
++//{
++// // any point attribute is acceptable for the distance operation
++// return true;
++//}
++//
++//bool SketchPlugin_DistanceAttrValidator::isValid(const FeaturePtr& theFeature,
++// const std::list<std::string>& theArguments,
++// const AttributePtr& theAttribute) const
++//{
++// return isValid(theAttribute, theArguments);
++//}
+
++// commented in v1.0.2, master:
+ //bool SketchPlugin_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature,
+ // const std::list<std::string>& theArguments,
+ // const ObjectPtr& theObject) const
+ //{
+ // std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
+ // theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
+ // std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
+ // for(; anAttr != anAttrs.end(); anAttr++) {
+ // if (*anAttr) {
+ // std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
+ // std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
+ // // check the object is already presented
+ // if (aRef->isObject() && aRef->object() == theObject)
+ // return false;
+ // }
+ // }
+ // return true;
+ //}
+
+ //bool SketchPlugin_DifferentObjectsValidator::isValid(
+ // const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
+ //{
+ // std::shared_ptr<ModelAPI_AttributeRefAttr> anOrigAttr =
+ // std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+ // if (anOrigAttr && anOrigAttr->isObject()) {
+ // const ObjectPtr& anObj = theAttribute->owner();
+ // const FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObj);
+ //
+ // std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
+ // aFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
+ // std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
+ // for(; anAttr != anAttrs.end(); anAttr++) {
+ // if (*anAttr && *anAttr != theAttribute) {
+ // std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
+ // std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
+ // // check the object is already presented
+ // if (aRef->isObject() && aRef->object() == anOrigAttr->object())
+ // return false;
+ // }
+ // }
+ // }
+ // return true;
+ //}
+
+ //bool SketchPlugin_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature,
+ // const std::list<std::string>& theArguments, const AttributePtr& theAttribute) const
+ //{
+ // std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs =
+ // theFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
+ // std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
+ // for(; anAttr != anAttrs.end(); anAttr++) {
+ // if (*anAttr) {
+ // std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
+ // std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
+ // // check the object is already presented
+ // if (!aRef->isObject() && aRef->attr() == theAttribute)
+ // return false;
+ // }
+ // }
+ // return true;
+ //}
++// =========== end of todo
//! returns true if attribute is valid
//! \param theAttribute the checked attribute
//! \param theArguments arguments of the attribute
- virtual bool isValid(const AttributePtr& theAttribute,
+ virtual bool isValid(const AttributePtr& theAttribute,
const std::list<std::string>& theArguments) const;
-
- //! Returns true if object is good for the feature attribute
- virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
- const ObjectPtr& theObject, const GeomShapePtr& theShape) const;
-
- //! Returns true if the attribute is good for the feature attribute
- virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
- const AttributePtr& theAttribute) const;
};
++// virtual bool isValid(const AttributePtr& theAttribute,
++// const std::list<std::string>& theArguments) const;
++//
++// //! Returns true if object is good for the feature attribute
++// virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
++// const ObjectPtr& theObject, const GeomShapePtr& theShape) const;
++//
++// //! Returns true if the attribute is good for the feature attribute
++// virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
++// const AttributePtr& theAttribute) const;
++//};
+
++// commented in v1.0.2, master:
+ /**\class SketchPlugin_DifferentObjectsValidator
+ * \ingroup Validators
+ *
+ * Check that there is no same object was already selected in the feature.
+ * For an example: to avoid perpendicularity on line and the same line.
+ */
+ // Use PartSet_DifferentObjectsValidator instead
+ //class SketchPlugin_DifferentObjectsValidator : public ModelAPI_RefAttrValidator
+ //{
+ // public:
+ // //! returns true if attribute is valid
+ // //! \param theAttribute the checked attribute
+ // //! \param theArguments arguments of the attribute
+ // virtual bool isValid(
+ // const AttributePtr& theAttribute, const std::list<std::string>& theArguments) const;
+ // //! Returns true if object is good for the feature attribute
+ // virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
+ // const ObjectPtr& theObject) const;
+ // //! Returns true if the attribute is good for the feature attribute
+ // virtual bool isValid(const FeaturePtr& theFeature, const std::list<std::string>& theArguments,
+ // const AttributePtr& theAttribute) const;
+ //};
++// ======= end of todo
#endif
--- /dev/null
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
+"""
+ TestConstraintEqual.py
+ Unit test of SketchPlugin_ConstraintEqual class
+
+ SketchPlugin_ConstraintEqual
+ static const std::string MY_CONSTRAINT_EQAUL_ID("SketchConstraintEqual");
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
+
+"""
+from GeomDataAPI import *
+from ModelAPI import *
+import math
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+__updated__ = "2015-03-16"
+
+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 a circle
+#=========================================================================
+aSession.startOperation()
+aSketchArc = aSketchFeature.addFeature("SketchArc")
+anArcCentr = geomDataAPI_Point2D(aSketchArc.attribute("ArcCenter"))
+anArcCentr.setValue(10., 10.)
+anArcStartPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcStartPoint"))
+anArcStartPoint.setValue(0., 50.)
+anArcEndPoint = geomDataAPI_Point2D(aSketchArc.attribute("ArcEndPoint"))
+anArcEndPoint.setValue(50., 0.)
+aSession.finishOperation()
+# Circle
+aSession.startOperation()
+aSketchCircle = aSketchFeature.addFeature("SketchCircle")
+anCircleCentr = geomDataAPI_Point2D(aSketchCircle.attribute("CircleCenter"))
+aCircleRadius = aSketchCircle.real("CircleRadius")
+anCircleCentr.setValue(-25., -25)
+aCircleRadius.setValue(25.)
+aSession.finishOperation()
+#=========================================================================
+# A constraint to make equal radii of arc and circle
+#=========================================================================
+aSession.startOperation()
+aConstraintEqRad = aSketchFeature.addFeature("SketchConstraintEqual")
+aRefObjectA = aConstraintEqRad.refattr("ConstraintEntityA")
+aRefObjectB = aConstraintEqRad.refattr("ConstraintEntityB")
+aResultA = modelAPI_ResultConstruction(aSketchArc.lastResult())
+aResultB = modelAPI_ResultConstruction(aSketchCircle.lastResult())
+assert (aResultA is not None)
+assert (aResultB is not None)
+aRefObjectA.setObject(aResultA)
+aRefObjectB.setObject(aResultB)
+aConstraintEqRad.execute()
+aSession.finishOperation()
+aCircRadius = aCircleRadius.value();
+anArcVecX = anArcStartPoint.x() - anArcCentr.x();
+anArcVecY = anArcStartPoint.y() - anArcCentr.y();
+anArcRadius = math.sqrt(anArcVecX**2 + anArcVecY**2)
+assert (math.fabs(aCircRadius - anArcRadius) <= 1.e-10)
+#=========================================================================
+# Creation of two different lines
+#=========================================================================
+# First Line
+aSession.startOperation()
+aSketchLine1 = aSketchFeature.addFeature("SketchLine")
+aLine1StartPoint = geomDataAPI_Point2D(aSketchLine1.attribute("StartPoint"))
+aLine1EndPoint = geomDataAPI_Point2D(aSketchLine1.attribute("EndPoint"))
+aLine1StartPoint.setValue(0., 15.)
+aLine1EndPoint.setValue(20., 25.)
+aSession.finishOperation()
+# Second Line
+aSession.startOperation()
+aSketchLine2 = aSketchFeature.addFeature("SketchLine")
+aLine2StartPoint = geomDataAPI_Point2D(aSketchLine2.attribute("StartPoint"))
+aLine2EndPoint = geomDataAPI_Point2D(aSketchLine2.attribute("EndPoint"))
+aLine2StartPoint.setValue(0., 0.)
+aLine2EndPoint.setValue(-1., 10.)
+aSession.finishOperation()
+#=========================================================================
+# A constraint to make equal lengths of lines
+#=========================================================================
+aSession.startOperation()
+aConstraintEqLen = aSketchFeature.addFeature("SketchConstraintEqual")
+aRefObjectA = aConstraintEqLen.refattr("ConstraintEntityA")
+aRefObjectB = aConstraintEqLen.refattr("ConstraintEntityB")
+aResultA = modelAPI_ResultConstruction(aSketchLine1.firstResult())
+aResultB = modelAPI_ResultConstruction(aSketchLine2.firstResult())
+assert (aResultA is not None)
+assert (aResultB is not None)
+aRefObjectA.setObject(aResultA)
+aRefObjectB.setObject(aResultB)
+aConstraintEqLen.execute()
+aSession.finishOperation()
+aVecX = aLine1StartPoint.x() - aLine1EndPoint.x();
+aVecY = aLine1StartPoint.y() - aLine1EndPoint.y();
+aLine1Len = math.sqrt(anArcVecX * anArcVecX + anArcVecY * anArcVecY)
+aVecX = aLine2StartPoint.x() - aLine2EndPoint.x();
+aVecY = aLine2StartPoint.y() - aLine2EndPoint.y();
+aLine2Len = math.sqrt(anArcVecX**2 + anArcVecY**2)
+assert (aLine1Len == aLine2Len)
+#=========================================================================
+# End of test
+#=========================================================================
--- /dev/null
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
+"""
+ TestConstraintHorizontal.py
+ Unit test of SketchPlugin_ConstraintHorizontal class
+
+ SketchPlugin_ConstraintHorizontal
+ static const std::string MY_CONSTRAINT_HORIZONTAL_ID("SketchConstraintHorizontal");
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
+
+"""
+from GeomDataAPI import *
+from ModelAPI import *
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+__updated__ = "2015-03-16"
+
+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()
+#=========================================================================
+# Create non-horizontal line
+#=========================================================================
+aSession.startOperation()
+aSketchLine = aSketchFeature.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
+aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
+aLineStartPoint.setValue(0., 15.)
+aLineEndPoint.setValue(20., 25.)
+aSession.finishOperation()
+#=========================================================================
+# Assign horizontal constraint for a line
+#=========================================================================
+aSession.startOperation()
+aHorizontalConstraint = aSketchFeature.addFeature("SketchConstraintHorizontal")
+refattrA = aHorizontalConstraint.refattr("ConstraintEntityA")
+aResult = modelAPI_ResultConstruction(aSketchLine.firstResult())
+assert (aResult is not None)
+refattrA.setObject(aResult)
+aHorizontalConstraint.execute()
+aSession.finishOperation()
+assert(aLineStartPoint.y() == aLineEndPoint.y())
+#=========================================================================
+# Move one of boundary points of a line
+#=========================================================================
+deltaX = deltaY = 10.
+aSession.startOperation()
+aLineStartPoint.setValue(aLineStartPoint.x() + deltaX,
+ aLineStartPoint.y() + deltaY)
+aSession.finishOperation()
+assert(aLineStartPoint.y() == aLineEndPoint.y())
+#=========================================================================
+# Move other boundary point of a line
+#=========================================================================
+deltaX = -3.
+deltaY = -10.
+aSession.startOperation()
+aLineEndPoint.setValue(aLineEndPoint.x() + deltaX,
+ aLineEndPoint.y() + deltaY)
+aSession.finishOperation()
+assert(aLineStartPoint.y() == aLineEndPoint.y())
+#=========================================================================
+# End of test
+#=========================================================================
--- /dev/null
- 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());
+"""
+ 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::typeId());
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefListAttr::typeId());
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_C(), ModelAPI_AttributeRefListAttr::typeId());
+
+"""
+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
+#=========================================================================
--- /dev/null
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::type());
+"""
+ TestConstraintTangent.py
+ Unit test of SketchPlugin_ConstraintTangent class
+
+ SketchPlugin_ConstraintTangent
+ static const std::string MY_CONSTRAINT_TANGENT_ID("SketchConstraintTangent");
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_B(), ModelAPI_AttributeRefAttr::typeId());
+
+"""
+from GeomDataAPI import *
+from GeomAPI 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()
+#=========================================================================
+# TEST 1. Arc-line tangency
+#=========================================================================
+# 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()
+anArcVecX = anArcStartPoint.x() - anArcCentr.x()
+anArcVecY = anArcStartPoint.y() - anArcCentr.y()
+aLineVecX = aLine1EndPoint.x() - aLine1StartPoint.x()
+aLineVecY = aLine1EndPoint.y() - aLine1StartPoint.y()
+aDot = anArcVecX * aLineVecX + anArcVecY * aLineVecY
+assert(math.fabs(aDot) <= 1.e-12)
+#=========================================================================
+# Add tangency constraint for arc and second line 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(aSketchLine2.firstResult())
+assert (anObjectA is not None)
+assert (anObjectB is not None)
+aRefObjectA.setObject(anObjectA)
+aRefObjectB.setObject(anObjectB)
+aTangency.execute()
+aSession.finishOperation()
+anArcVecX = anArcEndPoint.x() - anArcCentr.x()
+anArcVecY = anArcEndPoint.y() - anArcCentr.y()
+aLineVecX = aLine2EndPoint.x() - aLine2StartPoint.x()
+aLineVecY = aLine2EndPoint.y() - aLine2StartPoint.y()
+aDot = anArcVecX * aLineVecX + anArcVecY * aLineVecY
+assert(math.fabs(aDot) <= 1.e-12)
+
+#=========================================================================
+# TEST 2. Arc-arc tangency
+#=========================================================================
+# Creation of arcs
+#=========================================================================
+# Arc 1
+aSession.startOperation()
+aSketchArc1 = aSketchFeature.addFeature("SketchArc")
+anArc1Centr = geomDataAPI_Point2D(aSketchArc1.attribute("ArcCenter"))
+anArc1Centr.setValue(10., 10.)
+anArc1StartPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcStartPoint"))
+anArc1StartPoint.setValue(50., 0.)
+anArc1EndPoint = geomDataAPI_Point2D(aSketchArc1.attribute("ArcEndPoint"))
+anArc1EndPoint.setValue(0., 50.)
+aSession.finishOperation()
+# Arc 2
+aSession.startOperation()
+aSketchArc2 = aSketchFeature.addFeature("SketchArc")
+anArc2Centr = geomDataAPI_Point2D(aSketchArc2.attribute("ArcCenter"))
+anArc2Centr.setValue(-10., 10.)
+anArc2StartPoint = geomDataAPI_Point2D(aSketchArc2.attribute("ArcStartPoint"))
+anArc2StartPoint.setValue(0., 50.)
+anArc2EndPoint = geomDataAPI_Point2D(aSketchArc2.attribute("ArcEndPoint"))
+anArc2EndPoint.setValue(-50., 0.)
+aSession.finishOperation()
+#=========================================================================
+# Link points of arcs by the coincidence constraint
+#=========================================================================
+aSession.startOperation()
+aConstraint = aSketchFeature.addFeature("SketchConstraintCoincidence")
+reflistA = aConstraint.refattr("ConstraintEntityA")
+reflistB = aConstraint.refattr("ConstraintEntityB")
+reflistA.setAttr(anArc1EndPoint)
+reflistB.setAttr(anArc2StartPoint)
+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(aSketchArc2.lastResult())
+assert (anObjectA is not None)
+assert (anObjectB is not None)
+aRefObjectA.setObject(anObjectA)
+aRefObjectB.setObject(anObjectB)
+aTangency.execute()
+aSession.finishOperation()
+anArc1VecX = anArc1EndPoint.x() - anArc1Centr.x()
+anArc1VecY = anArc1EndPoint.y() - anArc1Centr.y()
+anArc2VecX = anArc2StartPoint.x() - anArc2Centr.x()
+anArc2VecY = anArc2StartPoint.y() - anArc2Centr.y()
+aCross = anArc1VecX * anArc2VecY - anArc1VecY * anArc2VecX
+assert(math.fabs(aCross) <= 1.e-12)
+
+#=========================================================================
+# TEST 3. Tangency between non-connected objects should be wrong
+#=========================================================================
+# Store data
+aLine2StartPointPrev = (aLine2StartPoint.x(), aLine2StartPoint.y())
+aLine2EndPointPrev = (aLine2EndPoint.x(), aLine2EndPoint.y())
+anArc2CenterPrev = (anArc2Centr.x(), anArc2Centr.y())
+anArc2StartPointPrev = (anArc2StartPoint.x(), anArc2StartPoint.y())
+anArc2EndPointPrev = (anArc2EndPoint.x(), anArc2EndPoint.y())
+#=========================================================================
+# Add tangency between arc2 and line2
+#=========================================================================
+aSession.startOperation()
+aTangency = aSketchFeature.addFeature("SketchConstraintTangent")
+aRefObjectA = aTangency.refattr("ConstraintEntityA")
+aRefObjectB = aTangency.refattr("ConstraintEntityB")
+anObjectA = modelAPI_ResultConstruction(aSketchArc2.lastResult())
+anObjectB = modelAPI_ResultConstruction(aSketchLine2.firstResult())
+assert (anObjectA is not None)
+assert (anObjectB is not None)
+aRefObjectA.setObject(anObjectA)
+aRefObjectB.setObject(anObjectB)
+aTangency.execute()
+aSession.finishOperation()
+# Check that nothing is changed
+aLine2StartPointNew = (aLine2StartPoint.x(), aLine2StartPoint.y())
+aLine2EndPointNew = (aLine2EndPoint.x(), aLine2EndPoint.y())
+anArc2CenterNew = (anArc2Centr.x(), anArc2Centr.y())
+anArc2StartPointNew = (anArc2StartPoint.x(), anArc2StartPoint.y())
+anArc2EndPointNew = (anArc2EndPoint.x(), anArc2EndPoint.y())
+assert(aLine2StartPointNew == aLine2StartPointPrev)
+assert(aLine2EndPointNew == aLine2EndPointPrev)
+assert(anArc2CenterNew == anArc2CenterPrev)
+assert(anArc2StartPointNew == anArc2StartPointPrev)
+assert(anArc2EndPointNew == anArc2EndPointPrev)
+#=========================================================================
+# End of test
+#=========================================================================
--- /dev/null
- data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::type());
+"""
+ TestConstraintVertical.py
+ Unit test of SketchPlugin_ConstraintVertical class
+
+ SketchPlugin_ConstraintVertical
+ static const std::string MY_CONSTRAINT_VERTICAL_ID("SketchConstraintVertical");
++ data()->addAttribute(SketchPlugin_Constraint::ENTITY_A(), ModelAPI_AttributeRefAttr::typeId());
+
+"""
+from GeomDataAPI import *
+from ModelAPI import *
+#=========================================================================
+# Initialization of the test
+#=========================================================================
+
+__updated__ = "2015-03-16"
+
+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()
+#=========================================================================
+# Create non-vertical line
+#=========================================================================
+aSession.startOperation()
+aSketchLine = aSketchFeature.addFeature("SketchLine")
+aLineStartPoint = geomDataAPI_Point2D(aSketchLine.attribute("StartPoint"))
+aLineEndPoint = geomDataAPI_Point2D(aSketchLine.attribute("EndPoint"))
+aLineStartPoint.setValue(0., 15.)
+aLineEndPoint.setValue(20., 25.)
+aSession.finishOperation()
+#=========================================================================
+# Assign vertical constraint for a line
+#=========================================================================
+aSession.startOperation()
+aVerticalConstraint = aSketchFeature.addFeature("SketchConstraintVertical")
+refattrA = aVerticalConstraint.refattr("ConstraintEntityA")
+aResult = modelAPI_ResultConstruction(aSketchLine.firstResult())
+assert (aResult is not None)
+refattrA.setObject(aResult)
+aVerticalConstraint.execute()
+aSession.finishOperation()
+assert(aLineStartPoint.x() == aLineEndPoint.x())
+#=========================================================================
+# Move one of boundary points of a line
+#=========================================================================
+deltaX = deltaY = 10.
+aSession.startOperation()
+aLineStartPoint.setValue(aLineStartPoint.x() + deltaX,
+ aLineStartPoint.y() + deltaY)
+aSession.finishOperation()
+assert(aLineStartPoint.x() == aLineEndPoint.x())
+#=========================================================================
+# Move other boundary point of a line
+#=========================================================================
+deltaX = -3.
+deltaY = -10.
+aSession.startOperation()
+aLineEndPoint.setValue(aLineEndPoint.x() + deltaX,
+ aLineEndPoint.y() + deltaY)
+aSession.finishOperation()
+assert(aLineStartPoint.x() == aLineEndPoint.x())
+#=========================================================================
+# End of test
+#=========================================================================
id="ConstraintEntityB"
label="Last object"
tooltip="Select point, line end point, line, center of circle or arc."
- shape_types="edge vertex">
++ shape_types="edge vertex">
+ <validator id="PartSet_DifferentObjects"/>
+ <validator id="SketchPlugin_DistanceAttr" parameters="ConstraintEntityA"/>
+ <validator id="SketchPlugin_ShapeValidator" parameters="ConstraintEntityA"/>
+ <validator id="GeomValidators_EdgeOrVertex"/>
+ </sketch_shape_selector>
++ <!--
++ TODO(nds): v1.0.2, master
+ shape_types="edge vertex">
+ <validator id="PartSet_DifferentObjects"/>
+ <validator id="SketchPlugin_DistanceAttr" parameters="ConstraintEntityA"/>
+ <selection_filter id="MultiFilter" parameters="line,vertex"/>
+ </sketch_shape_selector>
+
+ <sketch-2dpoint_selector id="ConstraintFlyoutValuePnt" internal="1" obligatory="0"/>
++ -->
- <doublevalue_editor label="Value" tooltip="Distance" id="ConstraintValue" default="computed" min="0">
+ <sketch-2dpoint_selector id="ConstraintFlyoutValuePnt" default="computed" internal="1" obligatory="0"/>
+
+ <doublevalue_editor label="Value" tooltip="Distance" id="ConstraintValue" default="computed" min="0">
<validator id="GeomValidators_Positive"/>
</doublevalue_editor>
<doublevalue_editor label="Value" tooltip="Radius" id="ConstraintValue" default="computed"/>
<validator id="PartSet_RadiusValidator"/>
</feature>
- <!-- SketchConstraintParallel -->
+ <!-- SketchConstraintParallel -->
<feature id="SketchConstraintParallel" title="Parallel" tooltip="Create constraint defining two parallel lines" icon=":icons/parallel.png">
+ <sketch_constraint_shape_selector id="ConstraintEntityA"
+ label="First line" tooltip="Select a line" shape_types="edge">
+ <validator id="GeomValidators_Edge" parameters="line"/>
+ <validator id="SketchPlugin_ShapeValidator" parameters="ConstraintEntityB"/>
+ </sketch_constraint_shape_selector>
+
+ <sketch_constraint_shape_selector id="ConstraintEntityB" label="Last line" tooltip="Select a line"
+ shape_types="edge">
+ <validator id="GeomValidators_Edge" parameters="line"/>
+ <validator id="PartSet_DifferentObjects"/>
+ <validator id="SketchPlugin_ShapeValidator" parameters="ConstraintEntityA"/>
+ </sketch_constraint_shape_selector>
+
++<!--
++ TODO(nds): v1.0.2, master
+ <sketch_constraint_shape_selector id="ConstraintEntityA"
+ label="First line" tooltip="Select a line" shape_types="edge">
+ <selection_filter id="EdgeFilter" parameters="line"/>
+ </sketch_constraint_shape_selector>
+
+ <sketch_constraint_shape_selector id="ConstraintEntityB" label="Last line" tooltip="Select a line"
+ shape_types="edge">
+ <selection_filter id="EdgeFilter" parameters="line"/>
+ <validator id="PartSet_DifferentObjects"/>
+ </sketch_constraint_shape_selector>
+
+ <sketch-2dpoint_selector id="ConstraintFlyoutValuePnt" internal="1" obligatory="0"/>
++-->
<validator id="PartSet_ParallelValidator"/>
</feature>
- <!-- SketchConstraintPerpendicular -->
- <feature id="SketchConstraintPerpendicular" title="Perpendicular" tooltip="Create constraint defining two perpendicular lines" icon=":icons/perpendicular.png">
+ <!-- SketchConstraintPerpendicular -->
- <feature id="SketchConstraintPerpendicular" title="Perpendicular" tooltip="Create constraint defining two perpendicular lines" icon=":icons/perpendicular.png">
++ <feature id="SketchConstraintPerpendicular" title="Perpendicular"
++ tooltip="Create constraint defining two perpendicular lines"
++ icon=":icons/perpendicular.png">
+ <sketch_constraint_shape_selector id="ConstraintEntityA"
+ label="First line" tooltip="Select an line"
+ shape_types="edge">
+ <validator id="SketchPlugin_ShapeValidator" parameters="ConstraintEntityB"/>
+ <validator id="GeomValidators_Edge" parameters="line"/>
+ </sketch_constraint_shape_selector>
+
+ <sketch_constraint_shape_selector id="ConstraintEntityB"
+ label="Last line" tooltip="Select an line"
+ shape_types="edge">
+ <validator id="PartSet_DifferentObjects"/>
+ <validator id="SketchPlugin_ShapeValidator" parameters="ConstraintEntityA"/>
+ <validator id="GeomValidators_Edge" parameters="line"/>
+ </sketch_constraint_shape_selector>
++<!--
++ TODO(nds): v1.0.2, master
+ <sketch_constraint_shape_selector id="ConstraintEntityA"
+ label="First line" tooltip="Select an line"
+ shape_types="edge">
+ <selection_filter id="EdgeFilter" parameters="line"/>
+ </sketch_constraint_shape_selector>
+
+ <sketch_constraint_shape_selector id="ConstraintEntityB"
+ label="Last line" tooltip="Select an line"
+ shape_types="edge">
+ <validator id="PartSet_DifferentObjects"/>
+ <selection_filter id="EdgeFilter" parameters="line"/>
+ </sketch_constraint_shape_selector>
++-->
<validator id="PartSet_PerpendicularValidator"/>
</feature>
- <!-- SketchConstraintRigid -->
+ <!-- SketchConstraintRigid -->
<feature id="SketchConstraintRigid" title="Fixed" tooltip="Fix an object" icon=":icons/fixed.png">
<shape_selector id="ConstraintEntityA" label="Object" tooltip="Select an object"
- shape_types="edge vertex">
- <validator id="SketchPlugin_ResultPoint"/>
- <validator id="SketchPlugin_ResultLine"/>
- <validator id="SketchPlugin_ResultArc"/>
- </shape_selector>
- <validator id="PartSet_RigidValidator"/>
+ shape_types="edge vertex">
+ <validator id="PartSet_SketchEntityValidator" parameters="SketchPoint,SketchLine,SketchCircle,SketchArc"/>
+ </shape_selector>
+ <validator id="PartSet_RigidValidator"/>
+ </feature>
+ <!-- SketchConstraintHorizontal -->
+ <feature id="SketchConstraintHorizontal" title="Horizontal" tooltip="Create constraint defining horizontal line" icon=":icons/horisontal.png">
+ <sketch_constraint_shape_selector id="ConstraintEntityA"
+ label="Line" tooltip="Select a line" shape_types="edge">
+ <validator id="GeomValidators_Edge" parameters="line"/>
+ </sketch_constraint_shape_selector>
+ </feature>
+ <!-- SketchConstraintVertical -->
+ <feature id="SketchConstraintVertical" title="Vertical" tooltip="Create constraint defining vertical line" icon=":icons/vertical.png">
+ <sketch_constraint_shape_selector id="ConstraintEntityA"
+ label="Line" tooltip="Select a line" shape_types="edge">
+ <validator id="GeomValidators_Edge" parameters="line"/>
+ </sketch_constraint_shape_selector>
+ </feature>
+ <!-- SketchConstraintEqual -->
+ <feature id="SketchConstraintEqual" title="Equal" tooltip="Create constraint defining equality of two objects" icon=":icons/equal.png">
+ <sketch_constraint_shape_selector id="ConstraintEntityA"
+ label="First object" tooltip="Select line, circle or arc" shape_types="edge">
+ </sketch_constraint_shape_selector>
+
+ <sketch_constraint_shape_selector id="ConstraintEntityB"
+ label="Last object" tooltip="Select line, circle or arc" shape_types="edge">
+ </sketch_constraint_shape_selector>
+ </feature>
+ <!-- SketchConstraintTangent -->
+ <feature id="SketchConstraintTangent" title="Tangent" tooltip="Create constraint defining tangency of two objects" icon=":icons/tangent.png">
+ <sketch_constraint_shape_selector id="ConstraintEntityA"
+ label="First object" tooltip="Select line or arc" shape_types="edge">
+ </sketch_constraint_shape_selector>
+
+ <sketch_constraint_shape_selector id="ConstraintEntityB"
+ 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>
+ <group id="Edit">
+ <!-- SketchConstraintFillet -->
+ <feature id="SketchConstraintFillet" title="Fillet" tooltip="Create constraint defining fillet between two objects" icon=":icons/fillet.png">
+ <sketch_constraint_shape_selector id="ConstraintEntityA"
+ label="First object" tooltip="Select line or arc" shape_types="edge">
+ </sketch_constraint_shape_selector>
+
+ <sketch_constraint_shape_selector id="ConstraintEntityB"
+ label="Last object" tooltip="Select line or arc" shape_types="edge">
+ </sketch_constraint_shape_selector>
+
+ <doublevalue_editor label="Value" tooltip="Fillet radius" id="ConstraintValue" default="0" min="0">
+ <validator id="GeomValidators_Positive"/>
+ </doublevalue_editor>
</feature>
</group>
</workbench>
return true;
}
- std::list<AttributePtr> aPoints = aBaseFeature->data()->attributes(GeomDataAPI_Point2D::type());
+// ============================================================================
+// 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_hConstraint>();
+
+ 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);
+ // Make aMirrorEnt parameters to be symmetric with aBaseEnt
+ makeMirrorEntity(aBaseEnt, aMirrorEnt, aMirrorLineEnt);
+
+ 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()) {
+ // Workaround to avoid problems in SolveSpace.
+ // The symmetry of two arcs will be done using symmetry of three points on these arcs:
+ // start point, end point, and any other point on the arc
+ Slvs_hEntity aBaseArcPoints[3] = {
+ myEntities[aBasePos].point[1],
+ myEntities[aBasePos].point[2],
+ SLVS_E_UNKNOWN};
+ Slvs_hEntity aMirrorArcPoints[3] = { // indices of points of arc, center corresponds center, first point corresponds last point
+ myEntities[aMirrorPos].point[2],
+ myEntities[aMirrorPos].point[1],
+ SLVS_E_UNKNOWN};
+ Slvs_hEntity aBothArcs[2] = {aBaseEnt, aMirrorEnt};
+ Slvs_hEntity aBothMiddlePoints[2];
+ for (int i = 0; i < 2; i++) {
+ double x, y;
+ calculateMiddlePoint(aBothArcs[i], x, y);
+ std::vector<Slvs_Param>::iterator aParamIter = myParams.end();
+ Slvs_hParam u = changeParameter(x, aParamIter);
+ Slvs_hParam v = changeParameter(y, aParamIter);
+ Slvs_Entity aPoint = Slvs_MakePoint2d(++myEntityMaxID, myID, myWorkplane.h, u, v);
+ myEntities.push_back(aPoint);
+ aBothMiddlePoints[i] = aPoint.h;
+ // additional constraint point-on-curve
+ Slvs_Constraint aPonCircConstr = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, SLVS_C_PT_ON_CIRCLE, myWorkplane.h, 0.0,
+ aPoint.h, SLVS_E_UNKNOWN, aBothArcs[i], SLVS_E_UNKNOWN);
+ myConstraints.push_back(aPonCircConstr);
+ myConstraintMap[theConstraint].push_back(aPonCircConstr.h);
+ }
+
+ aBaseArcPoints[2] = aBothMiddlePoints[0];
+ aMirrorArcPoints[2] = aBothMiddlePoints[1];
+ for (int ind = 0; ind < 3; ind++) {
+ Slvs_Constraint aConstraint = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, aConstrType, myWorkplane.h, 0.0,
+ aBaseArcPoints[ind], aMirrorArcPoints[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);
+
+ // Add temporary constraints for initial objects to be unchanged
+ for (aBaseIter = aBaseList.begin(); aBaseIter != aBaseList.end(); aBaseIter++) {
+ aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aBaseIter);
+ aBaseFeature = aRC ? aRC->document()->feature(aRC) :
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(*aBaseIter);
+ if (!aBaseFeature) continue;
- aBaseFeature[indAttr]->data()->attributes(GeomDataAPI_Point2D::type());
++ std::list<AttributePtr> aPoints = aBaseFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
+ std::list<AttributePtr>::iterator anIt = aPoints.begin();
+ for ( ; anIt != aPoints.end(); anIt++) {
+ // Arcs are fixed by center and start points only (to avoid solving errors in SolveSpace)
+ if (aBaseFeature->getKind() == SketchPlugin_Arc::ID() &&
+ (*anIt)->id() == SketchPlugin_Arc::END_ID())
+ continue;
+ addTemporaryConstraintWhereDragged(*anIt);
+ }
+ }
+ }
+ return true;
+}
+
+// ============================================================================
+// Function: changeFilletConstraint
+// Class: SketchSolver_ConstraintGroup
+// Purpose: create/update the "Fillet" constraint in the group
+// ============================================================================
+bool SketchSolver_ConstraintGroup::changeFilletConstraint(
+ 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)
+ return false;
+ const std::vector<std::string>& aConstraintAttributes = aConstraint.getAttributes();
+
+ // Obtain hEntity for basic objects of fillet
+ Slvs_hEntity aBaseObject[2];
+ FeaturePtr aBaseFeature[2];
+ for (unsigned int indAttr = 0; indAttr < 2; indAttr++) {
+ AttributeRefAttrPtr aConstrAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstrData->attribute(aConstraintAttributes[indAttr]));
+ if (!aConstrAttr)
+ return false;
+ 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();
+ aBaseFeature[indAttr] = aDoc->feature(aRC);
+ }
+ aBaseObject[indAttr] = aConstrAttr->isObject() ?
+ changeEntityFeature(aBaseFeature[indAttr]) : changeEntity(aConstrAttr->attr());
+ }
+ // Check the base entities have a coincident point
+ int aBaseObjInd[2] = {
+ Search(aBaseObject[0], myEntities),
+ Search(aBaseObject[1], myEntities)
+ };
+ int aShift[2] = { // shift for calculating correct start and end points for different types of objects
+ myEntities[aBaseObjInd[0]].type == SLVS_E_ARC_OF_CIRCLE ? 1 : 0,
+ myEntities[aBaseObjInd[1]].type == SLVS_E_ARC_OF_CIRCLE ? 1 : 0,
+ };
+ Slvs_hEntity aFirstObjPoints[2] = { // indices of start and end point of first object
+ myEntities[aBaseObjInd[0]].point[aShift[0]],
+ myEntities[aBaseObjInd[0]].point[1+aShift[0]]
+ };
+ Slvs_hEntity aSecondObjPoints[2] = { // indices of start and end point of second object
+ myEntities[aBaseObjInd[1]].point[aShift[1]],
+ myEntities[aBaseObjInd[1]].point[1+aShift[1]]
+ };
+ bool isCoincidentFound = false;
+ int aBaseCoincInd[2] = {0, 0}; // indices in aFirstObjPoint and aSecondObjPoint identifying coincident points
+ std::vector<std::set<Slvs_hEntity> >::iterator aCPIter = myCoincidentPoints.begin();
+ for ( ; aCPIter != myCoincidentPoints.end() && !isCoincidentFound; aCPIter++)
+ for (int ind1 = 0; ind1 < 2 && !isCoincidentFound; ind1++)
+ for (int ind2 = 0; ind2 < 2 && !isCoincidentFound; ind2++)
+ if (aCPIter->find(aFirstObjPoints[ind1]) != aCPIter->end() &&
+ aCPIter->find(aSecondObjPoints[ind2]) != aCPIter->end()) {
+ aBaseCoincInd[0] = ind1;
+ aBaseCoincInd[1] = ind2;
+ isCoincidentFound = true;
+ }
+ if (!isCoincidentFound) {
+ // There is no coincident points between objects. Generate error message
+ Events_Error::send(SketchSolver_Error::NO_COINCIDENT_POINTS(), this);
+ return false;
+ }
+
+ // Create fillet entities
+ // - first object is placed on the first base
+ // - second object is on the second base
+ // - third object is a filleting arc
+ static const int aNbFilletEnt = 3;
+ Slvs_hEntity aFilletEnt[aNbFilletEnt];
+ int aFilletObjInd[aNbFilletEnt];
+ AttributeRefListPtr aFilletRefList = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
+ aConstrData->attribute(aConstraintAttributes[2]));
+ if (!aFilletRefList)
+ return false;
+ std::list<ObjectPtr> aFilletList = aFilletRefList->list();
+ if (aFilletList.size() < aNbFilletEnt)
+ return false;
+ FeaturePtr aFilletFeature;
+ ResultConstructionPtr aRC;
+ std::list<ObjectPtr>::iterator aFilIter = aFilletList.begin();
+ for (int indEnt = 0; aFilIter != aFilletList.end(); aFilIter++, indEnt++) {
+ aRC = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aFilIter);
+ aFilletFeature = aRC ? aRC->document()->feature(aRC) :
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFilIter);
+ if (!aFilletFeature)
+ return false;
+ aFilletEnt[indEnt] = changeEntityFeature(aFilletFeature);
+ aFilletObjInd[indEnt] = Search(aFilletEnt[indEnt], myEntities);
+ }
+ // At first time, for correct result, move floating points of fillet on the middle points of base objects
+ if (myConstraintMap.find(theConstraint) == myConstraintMap.end()) {
+ double anArcPoints[6];
+ for (int indEnt = 0; indEnt < aNbFilletEnt - 1; indEnt++) {
+ int anIndShift = myEntities[aFilletObjInd[indEnt]].type == SLVS_E_ARC_OF_CIRCLE ? 1 : 0;
+ int aPointsPos[2] = {
+ Search(myEntities[aFilletObjInd[indEnt]].point[anIndShift], myEntities),
+ Search(myEntities[aFilletObjInd[indEnt]].point[1+anIndShift], myEntities)
+ };
+ int aParamPos[2] = {
+ Search(myEntities[aPointsPos[0]].param[0], myParams),
+ Search(myEntities[aPointsPos[1]].param[0], myParams)
+ };
+ int anIndex = aParamPos[aBaseCoincInd[indEnt]];
+ if (anIndShift == 0) {
+ myParams[anIndex].val =
+ 0.5 * (myParams[aParamPos[0]].val + myParams[aParamPos[1]].val);
+ myParams[1 + anIndex].val =
+ 0.5 * (myParams[1 + aParamPos[0]].val + myParams[1 + aParamPos[1]].val);
+ } else { // place the changed point on the arc
+ double x = 0, y = 0;
+ calculateMiddlePoint(aFilletEnt[indEnt], x, y);
+ myParams[anIndex].val = x;
+ myParams[1 + anIndex].val = y;
+ }
+ anArcPoints[indEnt*2+2] = myParams[anIndex].val;
+ anArcPoints[indEnt*2+3] = myParams[1 + anIndex].val;
+ }
+ anArcPoints[0] = 0.5 * (anArcPoints[2] + anArcPoints[4]);
+ anArcPoints[1] = 0.5 * (anArcPoints[3] + anArcPoints[5]);
+ for (int indArcPt = 0; indArcPt < 3; indArcPt++) {
+ int aPtPos = Search(myEntities[aFilletObjInd[2]].point[indArcPt], myEntities);
+ int aParamPos = Search(myEntities[aPtPos].param[0], myParams);
+ myParams[aParamPos].val = anArcPoints[indArcPt * 2];
+ myParams[aParamPos + 1].val = anArcPoints[indArcPt * 2 + 1];
+ }
+ }
+
+ // Check the fillet arc which point to be connected to
+ bool isArcInversed = false; // indicates that start and end points of arc should be connected to second and first object respectively
+ Slvs_hEntity hEnt = myEntities[aFilletObjInd[2]].point[1];
+ int aPos = Search(hEnt, myEntities);
+ Slvs_hParam anArcStartPoint = myEntities[aPos].param[0];
+ aPos = Search(anArcStartPoint, myParams);
+ double anArcPtCoord[2] = {myParams[aPos].val, myParams[aPos+1].val};
+ double aSqDistances[2];
+ int aPtInd;
+ for (int indEnt = 0; indEnt < aNbFilletEnt - 1; indEnt++) {
+ aPtInd = aBaseCoincInd[indEnt]+aShift[indEnt];
+ hEnt = myEntities[aFilletObjInd[indEnt]].point[aPtInd];
+ aPos = Search(hEnt, myEntities);
+ Slvs_hParam anObjectPoint = myEntities[aPos].param[0];
+ aPos = Search(anObjectPoint, myParams);
+ double aPtCoord[2] = {myParams[aPos].val, myParams[aPos+1].val};
+ aSqDistances[indEnt] =
+ (anArcPtCoord[0] - aPtCoord[0]) * (anArcPtCoord[0] - aPtCoord[0]) +
+ (anArcPtCoord[1] - aPtCoord[1]) * (anArcPtCoord[1] - aPtCoord[1]);
+ }
+ if (aSqDistances[1] < aSqDistances[0])
+ isArcInversed = true;
+
+ // Create list of constraints to generate fillet
+ std::vector<Slvs_hConstraint> aConstrList;
+ bool isExists = myConstraintMap.find(theConstraint) != myConstraintMap.end(); // constraint already exists
+ std::vector<Slvs_hConstraint>::iterator aCMapIter =
+ isExists ? myConstraintMap[theConstraint].begin() : aConstrList.begin();
+ int aCurConstrPos = isExists ? Search(*aCMapIter, myConstraints) : 0;
+ for (int indEnt = 0; indEnt < aNbFilletEnt - 1; indEnt++) {
+ // one point of fillet object should be coincident with the point on base, non-coincident with another base object
+ aPtInd = 1-aBaseCoincInd[indEnt]+aShift[indEnt]; // (1-aBaseCoincInd[indEnt]) = index of non-coincident point, aShift is used to process all types of shapes
+ Slvs_hEntity aPtBase = myEntities[aBaseObjInd[indEnt]].point[aPtInd];
+ Slvs_hEntity aPtFillet = myEntities[aFilletObjInd[indEnt]].point[aPtInd];
+ if (isExists) {
+ myConstraints[aCurConstrPos].ptA = aPtBase;
+ myConstraints[aCurConstrPos].ptB = aPtFillet;
+ aCMapIter++;
+ aCurConstrPos = Search(*aCMapIter, myConstraints);
+ } else {
+ Slvs_Constraint aCoincConstr = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, SLVS_C_POINTS_COINCIDENT, myWorkplane.h,
+ 0, aPtBase, aPtFillet, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
+ myConstraints.push_back(aCoincConstr);
+ aConstrList.push_back(aCoincConstr.h);
+ }
+
+ // another point of fillet object should be placed on the base object
+ Slvs_Constraint aPonCurveConstr;
+ int aTangentType;
+ if (myEntities[aFilletObjInd[indEnt]].type == SLVS_E_ARC_OF_CIRCLE) {
+ // centers of arcs should be coincident
+ aPtBase = myEntities[aBaseObjInd[indEnt]].point[0];
+ aPtFillet = myEntities[aFilletObjInd[indEnt]].point[0];
+ if (isExists) {
+ myConstraints[aCurConstrPos].ptA = aPtBase;
+ myConstraints[aCurConstrPos].ptB = aPtFillet;
+ aCMapIter++;
+ aCurConstrPos = Search(*aCMapIter, myConstraints);
+ } else {
+ aPonCurveConstr = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, SLVS_C_POINTS_COINCIDENT, myWorkplane.h,
+ 0, aPtBase, aPtFillet, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
+ }
+ aPtFillet = myEntities[aFilletObjInd[indEnt]].point[1+aBaseCoincInd[indEnt]]; // !!! will be used below
+ aTangentType = SLVS_C_CURVE_CURVE_TANGENT;
+ } else {
+ aPtInd = aBaseCoincInd[indEnt];
+ aPtFillet = myEntities[aFilletObjInd[indEnt]].point[aPtInd];
+ if (isExists) {
+ myConstraints[aCurConstrPos].ptA = aPtFillet;
+ aCMapIter++;
+ aCurConstrPos = Search(*aCMapIter, myConstraints);
+ } else {
+ aPonCurveConstr = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, SLVS_C_PT_ON_LINE, myWorkplane.h,
+ 0, aPtFillet, SLVS_E_UNKNOWN, aBaseObject[indEnt], SLVS_E_UNKNOWN);
+ }
+ aTangentType = SLVS_C_ARC_LINE_TANGENT;
+ }
+ if (!isExists) {
+ myConstraints.push_back(aPonCurveConstr);
+ aConstrList.push_back(aPonCurveConstr.h);
+ }
+
+ // Bound point of fillet arc should be tangently coincident with a bound point of fillet object
+ aPtInd = 1 + (isArcInversed ? 1-indEnt : indEnt);
+ Slvs_hEntity aPtArc = myEntities[aFilletObjInd[2]].point[aPtInd];
+ if (isExists) {
+ myConstraints[aCurConstrPos].ptA = aPtArc;
+ myConstraints[aCurConstrPos].ptB = aPtFillet;
+ aCMapIter++;
+ aCurConstrPos = Search(*aCMapIter, myConstraints);
+ myConstraints[aCurConstrPos].entityA = aFilletEnt[2];
+ myConstraints[aCurConstrPos].entityB = aFilletEnt[indEnt];
+ myConstraints[aCurConstrPos].other = (isArcInversed ? 1-indEnt : indEnt);
+ aCMapIter++;
+ aCurConstrPos = Search(*aCMapIter, myConstraints);
+ } else {
+ Slvs_Constraint aCoincConstr = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, SLVS_C_POINTS_COINCIDENT, myWorkplane.h,
+ 0, aPtArc, aPtFillet, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN);
+ myConstraints.push_back(aCoincConstr);
+ aConstrList.push_back(aCoincConstr.h);
+ Slvs_Constraint aTangency = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, aTangentType, myWorkplane.h,
+ 0, SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aFilletEnt[2], aFilletEnt[indEnt]);
+ aTangency.other = (isArcInversed ? 1-indEnt : indEnt);
+ aTangency.other2 = aTangentType == SLVS_C_CURVE_CURVE_TANGENT ? aBaseCoincInd[indEnt] : 0;
+ myConstraints.push_back(aTangency);
+ aConstrList.push_back(aTangency.h);
+ }
+ }
+
+ // Additional constraint for fillet diameter
+ double aRadius = 0.0; // scalar value of the constraint
+ AttributeDoublePtr aDistAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
+ aConstrData->attribute(SketchPlugin_Constraint::VALUE()));
+ aRadius = aDistAttr->value();
+ if (isExists) {
+ myConstraints[aCurConstrPos].entityA = aFilletEnt[2];
+ myConstraints[aCurConstrPos].valA = aRadius * 2.0;
+ aCMapIter++;
+ } else {
+ Slvs_Constraint aDiamConstr = Slvs_MakeConstraint(
+ ++myConstrMaxID, myID, SLVS_C_DIAMETER, myWorkplane.h, aRadius * 2.0,
+ SLVS_E_UNKNOWN, SLVS_E_UNKNOWN, aFilletEnt[2], SLVS_E_UNKNOWN);
+ myConstraints.push_back(aDiamConstr);
+ aConstrList.push_back(aDiamConstr.h);
+
+ myConstraintMap[theConstraint] = aConstrList;
+ }
+
+ // Additional temporary constraints for base objects to be fixed
+ for (unsigned int indAttr = 0; indAttr < 2; indAttr++) {
+ if (!aBaseFeature[indAttr]) {
+ AttributeRefAttrPtr aConstrAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
+ aConstrData->attribute(aConstraintAttributes[indAttr]));
+ addTemporaryConstraintWhereDragged(aConstrAttr->attr());
+ continue;
+ }
+ std::list<AttributePtr> anAttributes =
++ aBaseFeature[indAttr]->data()->attributes(GeomDataAPI_Point2D::typeId());
+ std::list<AttributePtr>::iterator anIt = anAttributes.begin();
+ for ( ; anIt != anAttributes.end(); anIt++) {
+ // Arc should be fixed by center and start points only (to avoid "conflicting constraints" message)
+ if (aBaseFeature[indAttr]->getKind() == SketchPlugin_Arc::ID() &&
+ (*anIt)->id() == SketchPlugin_Arc::END_ID())
+ continue;
+ addTemporaryConstraintWhereDragged(*anIt);
+ }
+ }
+ return true;
+}
+
// ============================================================================
// Function: changeEntity
// Class: SketchSolver_ConstraintGroup