return aFPoint;
}
-void PartSet_Tools::setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature,
- const std::string& theAttribute, double theClickedX,
- double theClickedY)
+std::shared_ptr<GeomDataAPI_Point2D> PartSet_Tools::findFirstEqualPointInSketch(
+ const CompositeFeaturePtr& theSketch,
+ const std::shared_ptr<GeomDataAPI_Point2D>& theFeaturePoint,
+ const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
{
- if (!theFeature.get())
- return;
-
- std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = std::shared_ptr<GeomAPI_Pnt2d>(
- new GeomAPI_Pnt2d(theClickedX, theClickedY));
-
- // find a feature point by the selection mode
- std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint;
- if (theFeature->isMacro()) {
- // the macro feature will be removed after the operation is stopped, so we need to build
- // coicidence to possible sub-features
- aFeaturePoint = PartSet_Tools::findFirstEqualPointInArgumentFeatures(theFeature, aClickedPoint);
- }
- else {
- aFeaturePoint = std::dynamic_pointer_cast<
- GeomDataAPI_Point2D>(theFeature->data()->attribute(theAttribute));
- }
- if (!aFeaturePoint)
- return;
-
// get all sketch features. If the point with the given coordinates belong to any sketch feature,
// the constraint is created between the feature point and the found sketch point
std::shared_ptr<ModelAPI_Data> aData = theSketch->data();
std::list<ObjectPtr> aFeatures = aRefList->list();
std::list<ObjectPtr>::const_iterator anIt = aFeatures.begin(), aLast = aFeatures.end();
std::list<std::shared_ptr<ModelAPI_Attribute> > anAttiributes;
+
+ FeaturePtr aFeatureOfPoint = ModelAPI_Feature::feature(theFeaturePoint->owner());
+ std::shared_ptr<GeomDataAPI_Point2D> aFPoint;
for (; anIt != aLast; anIt++) {
FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anIt);
- if (!aFeature.get() || (theFeature == aFeature) || (aFeaturePoint->owner() == aFeature))
+ if (!aFeature.get() || aFeatureOfPoint == aFeature)
continue;
- std::shared_ptr<GeomDataAPI_Point2D> aFPoint = PartSet_Tools::findFirstEqualPoint(aFeature,
- aClickedPoint);
- if (aFPoint)
- PartSet_Tools::createConstraint(theSketch, aFPoint, aFeaturePoint);
+ aFPoint = PartSet_Tools::findFirstEqualPoint(aFeature, thePoint);
+ if (aFPoint.get())
+ break;
}
+ return aFPoint;
}
std::shared_ptr<GeomAPI_Pln> PartSet_Tools::sketchPlane(CompositeFeaturePtr theSketch)
static std::shared_ptr<GeomDataAPI_Point2D> findFirstEqualPoint(const FeaturePtr& theFeature,
const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
- /// Creates constrains of the current
- /// \param theSketch a sketch feature
- /// \param theFeature a source feature
- /// \param theAttribute a name of the requried attribute attribute
- /// \param theClickedX the horizontal coordnate of the point
- /// \param theClickedY the vertical coordnate of the point
- static void setConstraints(CompositeFeaturePtr theSketch, FeaturePtr theFeature,
- const std::string& theAttribute, double theClickedX,
- double theClickedY);
+ static std::shared_ptr<GeomDataAPI_Point2D> findFirstEqualPointInSketch(
+ const CompositeFeaturePtr& theSketch,
+ const std::shared_ptr<GeomDataAPI_Point2D>& theFeaturePoint,
+ const std::shared_ptr<GeomAPI_Pnt2d>& thePoint);
/// Create a sketch plane instance
/// \param theSketch a sketch feature
#include <Events_Loop.h>
#include <ModelAPI_Events.h>
#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeRefAttr.h>
#include <ModelAPI_Feature.h>
#include <ModelAPI_Data.h>
myValueIsCashed(false), myIsFeatureVisibleInCash(true),
myXValueInCash(0), myYValueInCash(0)
{
+ myRefAttribute = theData->getProperty("reference_attribute");
if (MyFeaturesForCoincedence.isEmpty()) {
MyFeaturesForCoincedence << SketchPlugin_Line::ID().c_str()
<< SketchPlugin_Arc::ID().c_str()
const TopoDS_Shape& aTDShape = aShape->impl<TopoDS_Shape>();
if (getPoint2d(aView, aTDShape, aX, aY)) {
isDone = setPoint(aX, aY);
- PartSet_Tools::setConstraints(mySketch, feature(), attributeID(), aX, aY);
+ setConstraintTo(aX, aY);
+ //PartSet_Tools::setConstraints(mySketch, feature(), attributeID(), aX, aY);
}
}
return isDone;
return false;
}
+bool PartSet_WidgetPoint2D::setConstraintTo(double theClickedX, double theClickedY)
+{
+ FeaturePtr aFeature = feature();
+ std::string anAttribute = attributeID();
+
+ if (!aFeature.get())
+ return false;
+
+ std::shared_ptr<GeomAPI_Pnt2d> aClickedPoint = std::shared_ptr<GeomAPI_Pnt2d>(
+ new GeomAPI_Pnt2d(theClickedX, theClickedY));
+
+ // find a feature point by the selection mode
+ std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint;
+ if (aFeature->isMacro()) {
+ // the macro feature will be removed after the operation is stopped, so we need to build
+ // coicidence to possible sub-features
+ aFeaturePoint = PartSet_Tools::findFirstEqualPointInArgumentFeatures(aFeature, aClickedPoint);
+ }
+ else {
+ aFeaturePoint = std::dynamic_pointer_cast<
+ GeomDataAPI_Point2D>(aFeature->data()->attribute(anAttribute));
+ }
+ if (!aFeaturePoint.get())
+ return false;
+
+ std::shared_ptr<GeomDataAPI_Point2D> aFPoint = PartSet_Tools::findFirstEqualPointInSketch(
+ mySketch, aFeaturePoint, aClickedPoint);
+ if (!aFPoint.get())
+ return false;
+
+ AttributeRefAttrPtr aRefAttr = attributeRefAttr();
+ if (aRefAttr.get())
+ aRefAttr->setAttr(aFPoint);
+ else
+ PartSet_Tools::createConstraint(mySketch, aFPoint, aFeaturePoint);
+
+ return true;
+}
+
bool PartSet_WidgetPoint2D::setConstraintWith(const ObjectPtr& theObject)
{
std::shared_ptr<GeomDataAPI_Point2D> aFeaturePoint;
+
if (feature()->isMacro()) {
AttributePtr aThisAttr = feature()->data()->attribute(attributeID());
std::shared_ptr<GeomDataAPI_Point2D> anAttrPoint =
if (!aFeaturePoint.get())
return false;
- // Create point-edge coincedence
- FeaturePtr aFeature = mySketch->addFeature(SketchPlugin_ConstraintCoincidence::ID());
- std::shared_ptr<ModelAPI_Data> aData = aFeature->data();
-
- std::shared_ptr<ModelAPI_AttributeRefAttr> aRef1 = std::dynamic_pointer_cast<
- ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ AttributeRefAttrPtr aRefAttr = attributeRefAttr();
+ if (aRefAttr.get())
+ aRefAttr->setObject(theObject);
+ else {
+ // Create point-edge coincedence
+ FeaturePtr aFeature = mySketch->addFeature(SketchPlugin_ConstraintCoincidence::ID());
+ std::shared_ptr<ModelAPI_Data> aData = aFeature->data();
- aRef1->setAttr(aFeaturePoint);
+ std::shared_ptr<ModelAPI_AttributeRefAttr> aRef1 = std::dynamic_pointer_cast<
+ ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_A()));
- std::shared_ptr<ModelAPI_AttributeRefAttr> aRef2 = std::dynamic_pointer_cast<
- ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
- aRef2->setObject(theObject);
+ aRef1->setAttr(aFeaturePoint);
- // we need to flush created signal in order to coincidence is processed by solver
- Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+ std::shared_ptr<ModelAPI_AttributeRefAttr> aRef2 = std::dynamic_pointer_cast<
+ ModelAPI_AttributeRefAttr>(aData->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ aRef2->setObject(theObject);
+ // we need to flush created signal in order to coincidence is processed by solver
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
+ }
return true;
}
if (getPoint2d(aView, aShape, aX, aY)) {
setPoint(aX, aY);
feature()->execute();
- PartSet_Tools::setConstraints(mySketch, feature(), attributeID(), aX, aY);
+
+ setConstraintTo(aX, aY);
+ //PartSet_Tools::setConstraints(mySketch, feature(), attributeID(), aX, aY);
}
else if (aShape.ShapeType() == TopAbs_EDGE) {
// point is taken from mouse event and set in attribute. It should be done before setting
}
return aContainPoint;
}
+
+AttributeRefAttrPtr PartSet_WidgetPoint2D::attributeRefAttr() const
+{
+ AttributeRefAttrPtr anAttribute;
+ if (myRefAttribute.empty())
+ return anAttribute;
+
+ AttributePtr anAttributeRef = feature()->attribute(myRefAttribute);
+ if (!anAttributeRef.get())
+ return anAttribute;
+
+ return std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttributeRef);
+}
#include <V3d_View.hxx>
class ModelAPI_Feature;
+class ModelAPI_AttributeRefAttr;
class ModuleBase_IWorkshop;
class ModuleBase_ParamSpinBox;
class ModuleBase_IViewWindow;
bool getPoint2d(const Handle(V3d_View)& theView, const TopoDS_Shape& theShape,
double& theX, double& theY) const;
+ /// Creates constrains of the clicked point
+ /// \param theClickedX the horizontal coordnate of the point
+ /// \param theClickedY the vertical coordnate of the point
+ bool setConstraintTo(double theClickedX, double theClickedY);
+
/// Create a coincidence constraint between the attribute and the parameter object
/// \theObject a result object
/// \return true if succed
const std::shared_ptr<GeomAPI_Pnt2d>& thePoint,
const CompositeFeaturePtr& theSketch);
+ std::shared_ptr<ModelAPI_AttributeRefAttr> attributeRefAttr() const;
+
protected:
ModuleBase_IWorkshop* myWorkshop; ///< workshop
private:
-
QGroupBox* myGroupBox; ///< the parent group box for all intenal widgets
//ModuleBase_ParamSpinBox* myXSpin; ///< the spin box for the X coordinate
//ModuleBase_ParamSpinBox* myYSpin; ///< the spin box for the Y coordinate
/// it is important during restart operation
CompositeFeaturePtr mySketch;
+ std::string myRefAttribute; /// if not empty, coincidences are not set but attribute is filled
bool myValueIsCashed; /// boolean state if the value is cashed during value state change
bool myIsFeatureVisibleInCash; /// boolean value if the feature was visible when cash if filled
double myXValueInCash; /// the cashed X value during value state change
Test1924.py
Test1966.py
Test1967.py
- TestTrimCircle.py )
+ TestTrimArc.py
+ TestTrimCircle.py
+ TestTrimLine.py )
if (!isInversed->isInitialized())
isInversed->setValue(false);
anArcType->setValue(ARC_TYPE_CENTER_START_END());
+
+ data()->addAttribute(CENTER_REF_ID(), ModelAPI_AttributeRefAttr::typeId());
+ ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), CENTER_REF_ID());
}
void SketchPlugin_Arc::execute()
static const std::string MY_CENTER_ID = "ArcCenter";
return MY_CENTER_ID;
}
+
+ inline static const std::string& CENTER_REF_ID()
+ {
+ static const std::string MY_CENTER_REF_ID = "ArcCenterRef";
+ return MY_CENTER_REF_ID;
+ }
+
/// Start 2D point of the arc
inline static const std::string& START_ID()
{
ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
std::set<FeaturePtr> aFeaturesToDelete, aFeaturesToUpdate;
- std::map<FeaturePtr, IdToPointPair> aTangentFeatures;
+ //std::map<FeaturePtr, IdToPointPair> aTangentFeatures;
std::map<FeaturePtr, IdToPointPair> aCoincidenceToFeature;
- getConstraints(aFeaturesToDelete, aFeaturesToUpdate, aTangentFeatures, aCoincidenceToFeature);
+ getConstraints(aFeaturesToDelete, aFeaturesToUpdate, /*aTangentFeatures, */
+ aCoincidenceToFeature);
std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
std::list<AttributePtr> aRefsToFeature;
}
}
- if (!aTangentFeatures.empty()) {
+ /*if (!aTangentFeatures.empty()) {
std::cout << std::endl;
std::cout << "Tangencies to base feature[" << aTangentFeatures.size() << "]: " << std::endl;
std::map<FeaturePtr, IdToPointPair>::const_iterator anIt = aTangentFeatures.begin(),
std::cout << " -Point attribute:" <<
ModelGeomAlgo_Point2D::getPointAttributeInfo(aPointAttr) << std::endl;
}
- }
+ }*/
std::map<AttributePtr, std::list<AttributePtr> >::const_iterator
aRefIt = aBaseRefAttributes.begin(), aRefLast = aBaseRefAttributes.end();
updateCoincidenceConstraintsToFeature(aCoincidenceToFeature, aFurtherCoincidences,
aFeatureResults, aSplitFeature);
// tangency
- updateTangentConstraintsToFeature(aTangentFeatures, aFurtherCoincidences);
+ //updateTangentConstraintsToFeature(aTangentFeatures, aFurtherCoincidences);
updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes);
void SketchPlugin_ConstraintSplit::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete,
std::set<FeaturePtr>& theFeaturesToUpdate,
- std::map<FeaturePtr, IdToPointPair>& theTangentFeatures,
+ //std::map<FeaturePtr, IdToPointPair>& theTangentFeatures,
std::map<FeaturePtr, IdToPointPair>& theCoincidenceToFeature)
{
std::shared_ptr<ModelAPI_Data> aData = data();
theFeaturesToDelete.insert(aRefFeature);
else if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID())
theFeaturesToUpdate.insert(aRefFeature);
- else if (aRefFeatureKind == SketchPlugin_ConstraintTangent::ID()) {
+ /*else if (aRefFeatureKind == SketchPlugin_ConstraintTangent::ID()) {
if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) /// TEMPORARY limitaion
/// until tangency between arc and line is implemented
theFeaturesToDelete.insert(aRefFeature);
theFeaturesToDelete.insert(aRefFeature);
}
}
- else if (aRefFeatureKind == SketchPlugin_ConstraintCoincidence::ID()) {
+ */else if (aRefFeatureKind == SketchPlugin_ConstraintCoincidence::ID()) {
std::string anAttributeToBeModified;
AttributePoint2DPtr aCoincidentPoint;
AttributeRefAttrPtr anAttrA = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A());
}
}
-void SketchPlugin_ConstraintSplit::updateTangentConstraintsToFeature(
- const std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theTangentFeatures,
- const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences)
-{
- if (theTangentFeatures.empty())
- return;
-
- std::map<FeaturePtr, IdToPointPair>::const_iterator aTIt = theTangentFeatures.begin(),
- aTLast = theTangentFeatures.end();
-#ifdef DEBUG_SPLIT
- std::cout << std::endl;
- std::cout << "Tangencies to feature(modified):"<< std::endl;
-#endif
- for (; aTIt != aTLast; aTIt++) {
- FeaturePtr aTangentFeature = aTIt->first;
- std::string anAttributeId = aTIt->second.first;
- AttributePoint2DPtr aTangentPoint = aTIt->second.second;
- std::set<AttributePoint2DPtr>::const_iterator aFCIt = theFurtherCoincidences.begin(),
- aFCLast = theFurtherCoincidences.end();
- std::shared_ptr<GeomAPI_Pnt2d> aCoincPnt = aTangentPoint->pnt();
- AttributePoint2DPtr aFeaturePointAttribute;
- /// here we rely on created coincidence between further coincidence point and tangent result
- for (; aFCIt != aFCLast && !aFeaturePointAttribute.get(); aFCIt++) {
- AttributePoint2DPtr aFCAttribute = *aFCIt;
- if (aCoincPnt->isEqual(aFCAttribute->pnt()))
- aFeaturePointAttribute = aFCAttribute;
- }
- if (aFeaturePointAttribute.get()) {
- FeaturePtr aFeature =
- std::dynamic_pointer_cast<ModelAPI_Feature>(aFeaturePointAttribute->owner());
- aTangentFeature->refattr(anAttributeId)->setObject(getFeatureResult(aFeature));
- }
-#ifdef DEBUG_SPLIT
- std::cout << " -" << getFeatureInfo(aTangentFeature) << std::endl;
-#endif
- }
-}
+//void SketchPlugin_ConstraintSplit::updateTangentConstraintsToFeature(
+// const std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theTangentFeatures,
+// const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences)
+//{
+// if (theTangentFeatures.empty())
+// return;
+//
+// std::map<FeaturePtr, IdToPointPair>::const_iterator aTIt = theTangentFeatures.begin(),
+// aTLast = theTangentFeatures.end();
+//#ifdef DEBUG_SPLIT
+// std::cout << std::endl;
+// std::cout << "Tangencies to feature(modified):"<< std::endl;
+//#endif
+// for (; aTIt != aTLast; aTIt++) {
+// FeaturePtr aTangentFeature = aTIt->first;
+// std::string anAttributeId = aTIt->second.first;
+// AttributePoint2DPtr aTangentPoint = aTIt->second.second;
+// std::set<AttributePoint2DPtr>::const_iterator aFCIt = theFurtherCoincidences.begin(),
+// aFCLast = theFurtherCoincidences.end();
+// std::shared_ptr<GeomAPI_Pnt2d> aCoincPnt = aTangentPoint->pnt();
+// AttributePoint2DPtr aFeaturePointAttribute;
+// /// here we rely on created coincidence between further coincidence point and tangent result
+// for (; aFCIt != aFCLast && !aFeaturePointAttribute.get(); aFCIt++) {
+// AttributePoint2DPtr aFCAttribute = *aFCIt;
+// if (aCoincPnt->isEqual(aFCAttribute->pnt()))
+// aFeaturePointAttribute = aFCAttribute;
+// }
+// if (aFeaturePointAttribute.get()) {
+// FeaturePtr aFeature =
+// std::dynamic_pointer_cast<ModelAPI_Feature>(aFeaturePointAttribute->owner());
+// aTangentFeature->refattr(anAttributeId)->setObject(getFeatureResult(aFeature));
+// }
+//#ifdef DEBUG_SPLIT
+// std::cout << " -" << getFeatureInfo(aTangentFeature) << std::endl;
+//#endif
+// }
+//}
void SketchPlugin_ConstraintSplit::updateRefFeatureConstraints(
const ResultPtr& theFeatureBaseResult,
/// \param theCoincidenceToPoint [out] coincidence to point be connected to new feature
void getConstraints(std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToDelete,
std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToUpdate,
- std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theTangentFeatures,
+ //std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theTangentFeatures,
std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theCoincidenceToFeature/*,
std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theCoincidenceToPoint*/);
/// Move tangency constraint to the nearest split feature that has a coincidence to the tangent
/// \param theTangentFeatures tangencies to feature to be connected to nearest feature
/// \param theFurtherCoincidences a list of points where coincidences is built
- void updateTangentConstraintsToFeature(
- const std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theTangentFeatures,
- const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences);
+ //void updateTangentConstraintsToFeature(
+ // const std::map<std::shared_ptr<ModelAPI_Feature>, IdToPointPair>& theTangentFeatures,
+ // const std::set<std::shared_ptr<GeomDataAPI_Point2D> >& theFurtherCoincidences);
/// Move constraints from base feature to given feature
std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint2d = convertPoint(aLastShapePoint);
- std::set<FeaturePtr> aFeaturesToDelete, aFeaturesToUpdate;
- getConstraints(aFeaturesToDelete, aFeaturesToUpdate);
+ std::set<FeaturePtr> aFeaturesToDelete;
+ getConstraints(aFeaturesToDelete);
std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
std::list<AttributePtr> aRefsToFeature;
getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature);
+
+ // coincidence to result points
+ // find coincidences to the base object, it should be used when attribute is found
+ // in myObjectToPoints
+ std::map<AttributePtr, FeaturePtr> aCoincidencesToBaseFeature;
+ getCoincidencesToObject(aBaseObject, aCoincidencesToBaseFeature);
+
std::set<AttributePoint2DPtr> aFurtherCoincidences;
- std::set<FeaturePtr> aCreatedFeatures;
std::set<std::pair<AttributePtr, AttributePtr>> aModifiedAttributes;
const std::string& aKind = aBaseFeature->getKind();
+ FeaturePtr aReplacingFeature;
if (aKind == SketchPlugin_Circle::ID()) {
- trimCircle(aStartShapePoint2d, aLastShapePoint2d,
- aFurtherCoincidences, aCreatedFeatures, aModifiedAttributes);
- updateRefFeatureConstraints(getFeatureResult(aBaseFeature), aRefsToFeature);
+ aReplacingFeature = trimCircle(aStartShapePoint2d, aLastShapePoint2d,
+ aFurtherCoincidences, aModifiedAttributes);
aFeaturesToDelete.insert(aBaseFeature);
// as circle is removed, temporary fill this attribute
}
else if (aKind == SketchPlugin_Line::ID()) {
trimLine(aStartShapePoint2d, aLastShapePoint2d,
- aFurtherCoincidences, aCreatedFeatures, aModifiedAttributes);
+ aFurtherCoincidences, aModifiedAttributes);
}
else if (aKind == SketchPlugin_Arc::ID()) {
trimArc(aStartShapePoint2d, aLastShapePoint2d,
- aFurtherCoincidences, aCreatedFeatures, aModifiedAttributes);
+ aFurtherCoincidences, aModifiedAttributes);
}
- // coincidence to result points
+ //
const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
std::set<AttributePoint2DPtr>::const_iterator anIt = aFurtherCoincidences.begin(),
aLast = aFurtherCoincidences.end();
}
const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
for (std::list<AttributePoint2DPtr>::const_iterator anAttrIt = anAttributes.begin();
- anAttrIt != anAttributes.end(); anAttrIt++) {
- createConstraint(SketchPlugin_ConstraintCoincidence::ID(), aPointAttribute, *anAttrIt);
+ anAttrIt != anAttributes.end(); anAttrIt++) {
+ AttributePtr anAttribute = *anAttrIt;
+ if (aCoincidencesToBaseFeature.find(anAttribute) != aCoincidencesToBaseFeature.end())
+ {
+ FeaturePtr anAttrFeature = aCoincidencesToBaseFeature.at(anAttribute);
+ AttributePtr anOtherAttribute;
+ if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
+ (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()))->attr() == anAttribute)
+ anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
+ else if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
+ (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()))->attr() == anAttribute)
+ anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
+ else
+ continue;
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
+ (anOtherAttribute);
+ if (aRefAttr.get())
+ aRefAttr->setAttr(aPointAttribute);
+ }
}
const std::list<ObjectPtr>& anObjects = anInfo.second;
}
}
+ // move constraints from base feature to replacing feature: ignore coincidences to feature
+ // if attributes of coincidence participated in split
+ if (aReplacingFeature.get()) {
+ ResultPtr aReplacingResult = getFeatureResult(aReplacingFeature);
+ std::list<AttributePtr>::const_iterator anIt = aRefsToFeature.begin(),
+ aLast = aRefsToFeature.end();
+ for (; anIt != aLast; anIt++) {
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
+ if (!aRefAttr.get())
+ continue;
+ FeaturePtr anAttrFeature = ModelAPI_Feature::feature(aRefAttr->owner());
+ if (anAttrFeature.get() &&
+ anAttrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID())
+ {
+ if (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()) == aRefAttr ||
+ anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()) == aRefAttr)
+ continue;
+ }
+ aRefAttr->setObject(aReplacingResult);
+ }
+ }
+
// Wait all constraints being created, then send update events
static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent);
}
}
-void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete,
- std::set<FeaturePtr>& theFeaturesToUpdate)
+void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete)
{
std::shared_ptr<ModelAPI_Data> aData = data();
aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
theFeaturesToDelete.insert(aRefFeature);
- else if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID())
- theFeaturesToUpdate.insert(aRefFeature);
- else if (aRefFeatureKind == SketchPlugin_ConstraintTangent::ID()) {
- if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) /// TEMPORARY limitaion
- /// until tangency between arc and line is implemented
- theFeaturesToDelete.insert(aRefFeature);
- else {
- std::string anAttributeToBeModified;
- AttributePoint2DPtr aTangentPoint;
- ObjectPtr aResult1 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A())->object();
- ObjectPtr aResult2 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B())->object();
- if (aResult1.get() && aResult2.get()) {
- FeaturePtr aCoincidenceFeature =
- SketchPlugin_ConstraintCoincidence::findCoincidenceFeature
- (ModelAPI_Feature::feature(aResult1),
- ModelAPI_Feature::feature(aResult2));
- // get the point not lying on the splitting feature
- for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
- AttributeRefAttrPtr aRefAttr = aCoincidenceFeature->refattr(
- SketchPlugin_Trim::BASE_OBJECT());
- if (!aRefAttr || aRefAttr->isObject())
- continue;
- AttributePoint2DPtr aPoint =
- std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
- if (!aPoint)
- continue;
- if (aPoint->owner() != aBaseFeature) {
- aTangentPoint = aPoint;
- break;
- }
- }
- }
- if (aTangentPoint.get()) {
- // collect tangent feaures
- }
- else /// there is not coincident point between tangent constraint
- theFeaturesToDelete.insert(aRefFeature);
- }
- }
}
}
}
}
-void SketchPlugin_Trim::updateRefFeatureConstraints(
- const ResultPtr& theFeatureBaseResult,
- const std::list<AttributePtr>& theRefsToFeature)
+void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject,
+ std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature)
{
- std::list<AttributePtr>::const_iterator anIt = theRefsToFeature.begin(),
- aLast = theRefsToFeature.end();
- for (; anIt != aLast; anIt++) {
- AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
- if (aRefAttr.get())
- aRefAttr->setObject(theFeatureBaseResult);
+ const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aIt;
+ for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
+ std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
+ FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
+ if (aRefFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
+ continue;
+ AttributePtr anAttribute;
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
+ (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ if (aRefAttr->isObject() && aRefAttr->object() == theObject)
+ {
+ anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
+ }
+ else {
+ aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
+ (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ if (aRefAttr->isObject() && aRefAttr->object() == theObject)
+ {
+ anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
+ }
+ if (anAttribute.get())
+ {
+ aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
+ (anAttribute);
+ anAttribute = aRefAttr->attr();
+ if (anAttribute.get())
+ theCoincidencesToBaseFeature[anAttribute] = aRefFeature;
+ }
+ }
}
}
void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
std::set<AttributePoint2DPtr>& thePoints,
- std::set<FeaturePtr>& theCreatedFeatures,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
{
// Check the base objects are initialized.
void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
std::set<AttributePoint2DPtr>& thePoints,
- std::set<FeaturePtr>& theCreatedFeatures,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
{
// Check the base objects are initialized.
}
}
-void SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
+FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
std::set<AttributePoint2DPtr>& thePoints,
- std::set<FeaturePtr>& theCreatedFeatures,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
{
// Check the base objects are initialized.
FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
/// points of trim
- AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
- getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
+ //AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
+ //getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
/// trim feature
FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
(anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
(anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
+
+ return anArcFeature;
}
void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr,
/// Obtains those constraints of the feature that should be modified. output maps contain
/// point of coincidence and attribute id to be modified after split
/// \param theFeaturesToDelete [out] constrains that will be deleted after split
- /// \param theFeaturesToUpdate [out] constrains that will be updated after split
- void getConstraints(std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToDelete,
- std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToUpdate);
+ void getConstraints(std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToDelete);
/// Obtains references to feature point attributes and to feature,
/// e.g. for feature line: 1st container is
std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
std::list<AttributePtr>& theRefsToFeature);
- /// Move constraints from base feature to given feature
- /// \param theFeature a base feature
- /// \param theRefsToFeature list of attributes referenced to base feature
- void updateRefFeatureConstraints(const std::shared_ptr<ModelAPI_Result>& theFeatureBaseResult,
- const std::list<AttributePtr>& theRefsToFeature);
+ /// Obtains coincident features to the given object. It is collected in a container
+ /// by the coincident attribute
+ /// \param theObject an investigated object
+ /// \param theCoincidencesToBaseFeature a container of list of referenced attributes
+ void getCoincidencesToObject(const ObjectPtr& theObject,
+ std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature);
/// Move constraints from attribute of base feature to attribute after modification
/// \param theBaseRefAttributes container of references to the attributes of base feature
const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes,
std::set<std::shared_ptr<ModelAPI_Feature>>& theFeaturesToDelete);
-// /// Make the base object is splitted by the point attributes
-// /// \param theSplitFeature a result split feature
-// /// \param theBeforeFeature a feature between start point and the 1st point of split feature
-// /// \param theAfterFeature a feature between last point of split feature and the end point
-// /// \param thePoints a list of points where coincidences will be build
-// /// \param theCreatedFeatures a container of created features
-// /// \param theModifiedAttributes a container of attribute on base
-// /// feature to attribute on new feature
+ /// Make the base object is splitted by the point attributes
+ /// \param theSplitFeature a result split feature
+ /// \param theBeforeFeature a feature between start point and the 1st point of split feature
+ /// \param theAfterFeature a feature between last point of split feature and the end point
+ /// \param thePoints a list of points where coincidences will be build
+ /// \param theModifiedAttributes a container of attribute on base
+ /// feature to attribute on new feature
void trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
std::set<std::shared_ptr<GeomDataAPI_Point2D> >& thePoints,
- std::set<std::shared_ptr<ModelAPI_Feature>>& theCreatedFeatures,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
/// Make the base object is splitted by the point attributes
/// \param theBeforeFeature a feature between start point and the 1st point of split feature
/// \param theAfterFeature a feature between last point of split feature and the end point
/// \param thePoints a list of points where coincidences will be build
- /// \param theCreatedFeatures a container of created features
void trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
std::set<std::shared_ptr<GeomDataAPI_Point2D> >& thePoints,
- std::set<std::shared_ptr<ModelAPI_Feature>>& theCreatedFeatures,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
/// Make the base object is splitted by the point attributes
/// \param theBeforeFeature a feature between start point and the 1st point of split feature
/// \param theAfterFeature a feature between last point of split feature and the end point
/// \param thePoints a list of points where coincidences will be build
- /// \param theCreatedFeatures a container of created features
- void trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
+ FeaturePtr trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
std::set<std::shared_ptr<GeomDataAPI_Point2D> >& thePoints,
- std::set<std::shared_ptr<ModelAPI_Feature>>& theCreatedFeatures,
std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes);
/// Correct the first and the second point to provide condition that the first is closer to
assert(idList.count(SketchLineId) == 2)
assert(idList.count(SketchPointId) == 1)
assert(idList.count(SketchConstraintCoincidenceId) == 3)
-assert(idList.count(SketchConstraintParallelId) == 1)
+assert(idList.count(SketchConstraintParallelId) == 0)
# Test end
# Test split on line with two points
assert(idList.count(SketchLineId) == 3)
assert(idList.count(SketchPointId) == 2)
assert(idList.count(SketchConstraintCoincidenceId) == 6)
-assert(idList.count(SketchConstraintParallelId) == 2)
+assert(idList.count(SketchConstraintParallelId) == 0)
# Test end
# Test split on circle with two points
assert(idList.count(SketchArcId) == 2)
assert(idList.count(SketchPointId) == 2)
assert(idList.count(SketchConstraintCoincidenceId) == 6)
-assert(idList.count(SketchConstraintTangentId) == 1)
+assert(idList.count(SketchConstraintTangentId) == 0)
# Test end
# Test split on arc with one point
assert(idList.count(SketchArcId) == 2)
assert(idList.count(SketchPointId) == 1)
assert(idList.count(SketchConstraintCoincidenceId) == 3)
-assert(idList.count(SketchConstraintEqualId) == 1)
-assert(idList.count(SketchConstraintTangentId) == 1)
+assert(idList.count(SketchConstraintEqualId) == 0)
+assert(idList.count(SketchConstraintTangentId) == 0)
# Test end
# Test split on arc with two points
assert(idList.count(SketchArcId) == 3)
assert(idList.count(SketchPointId) == 0)
assert(idList.count(SketchConstraintCoincidenceId) == 6)
-assert(idList.count(SketchConstraintEqualId) == 2)
-assert(idList.count(SketchConstraintTangentId) == 2)
+assert(idList.count(SketchConstraintEqualId) == 0)
+assert(idList.count(SketchConstraintTangentId) == 0)
# Test end
model.end()
--- /dev/null
+from salome.shaper import model
+
+from ModelAPI import *
+from GeomDataAPI import *
+from salome.shaper import geom
+import math
+
+TOLERANCE = 1.e-7
+
+SketchPointId = 'SketchPoint'
+SketchLineId = 'SketchLine'
+SketchArcId = 'SketchArc'
+SketchCircleId = 'SketchCircle'
+SketchConstraintCoincidenceId = 'SketchConstraintCoincidence'
+SketchConstraintMirrorId = 'SketchConstraintMirror'
+SketchConstraintTangentId = 'SketchConstraintTangent'
+SketchConstraintEqualId = 'SketchConstraintEqual'
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+# Test1:begin split on circle with coincident point and intersection line : smaller part
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchArc_1_1 = Sketch_1.addArc(50, 50, 55, 70, 30, 45, True)
+SketchLine_1_1 = Sketch_1.addLine(50, 30, 100, 30)
+SketchLine_1_2 = Sketch_1.addLine(60, 50, 100, 30)
+
+SketchConstraintCoincidence_1_1 = Sketch_1.setCoincident(SketchLine_1_1.startPoint(), SketchArc_1_1.results()[1])
+SketchConstraintCoincidence_1_2 = Sketch_1.setCoincident(SketchLine_1_1.endPoint(), SketchLine_1_2.endPoint())
+GeomPoint_1_1 = geom.Pnt2d(60, 35)
+
+#check number of features before trim
+Sketch_1_feature = featureToCompositeFeature(Sketch_1.feature())
+idList_before_1 = []
+for index in range(Sketch_1_feature.numberOfSubs()):
+ idList_before_1.append(Sketch_1_feature.subFeature(index).getKind())
+assert(idList_before_1.count(SketchArcId) == 1)
+assert(idList_before_1.count(SketchLineId) == 2)
+assert(idList_before_1.count(SketchConstraintCoincidenceId) == 2)
+assert(idList_before_1.count(SketchConstraintEqualId) == 0)
+
+#perform trim
+SketchTrim_1_1 = Sketch_1.addTrim(SketchArc_1_1, GeomPoint_1_1)
+SketchTrim_1_1.execute()
+model.do()
+
+#check number of features after trim
+SketchFeatures = featureToCompositeFeature(Sketch_1.feature())
+idList_after_1 = []
+for SubIndex in range(SketchFeatures.numberOfSubs()):
+ SubFeature = SketchFeatures.subFeature(SubIndex)
+ idList_after_1.append(SubFeature.getKind())
+
+assert(idList_after_1.count(SketchArcId) == 2)
+assert(idList_after_1.count(SketchLineId) == 2)
+aCount = idList_after_1.count(SketchConstraintCoincidenceId)
+
+assert(idList_after_1.count(SketchConstraintCoincidenceId) == 4)
+assert(idList_after_1.count(SketchConstraintEqualId) == 1)
+# Test1:end
+
+# Test2: split on circle with coincident point and intersection line : largest part
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+move_test_delta_y = 100
+move_test_delta_x = 0
+SketchCircle_2_1 = Sketch_2.addCircle(50, 50 + move_test_delta_y, 20)
+SketchLine_2_1 = Sketch_2.addLine(50, 30 + move_test_delta_y, 100, 30 + move_test_delta_y)
+SketchLine_2_2 = Sketch_2.addLine(60, 50 + move_test_delta_y, 100, 30 + move_test_delta_y)
+
+SketchConstraintCoincidence_2_1 = Sketch_2.setCoincident(SketchLine_2_1.startPoint(), SketchCircle_2_1.results()[1])
+SketchConstraintCoincidence_2_2 = Sketch_2.setCoincident(SketchLine_2_1.endPoint(), SketchLine_2_2.endPoint())
+GeomPoint_2_1 = geom.Pnt2d(50, 75 + move_test_delta_y)
+
+#check number of features before trim
+Sketch_2_feature = featureToCompositeFeature(Sketch_2.feature())
+idList_before_2 = []
+for index in range(Sketch_2_feature.numberOfSubs()):
+ idList_before_2.append(Sketch_2_feature.subFeature(index).getKind())
+assert(idList_before_2.count(SketchCircleId) == 1)
+assert(idList_before_2.count(SketchArcId) == 0)
+assert(idList_before_2.count(SketchLineId) == 2)
+assert(idList_before_2.count(SketchConstraintCoincidenceId) == 2)
+
+#perform trim
+SketchTrim_2_1 = Sketch_2.addTrim(SketchCircle_2_1, GeomPoint_2_1)
+SketchTrim_2_1.execute()
+model.do()
+
+#check number of features after trim
+SketchFeatures = featureToCompositeFeature(Sketch_2.feature())
+idList_after_2 = []
+for SubIndex in range(SketchFeatures.numberOfSubs()):
+ SubFeature = SketchFeatures.subFeature(SubIndex)
+ idList_after_2.append(SubFeature.getKind())
+ if SubFeature.getKind() == SketchArcId:
+ ArcFeature_2 = SubFeature
+
+
+assert(idList_after_2.count(SketchCircleId) == 0)
+assert(idList_after_2.count(SketchArcId) == 1)
+assert(idList_after_2.count(SketchLineId) == 2)
+assert(idList_after_2.count(SketchConstraintCoincidenceId) == 3)
+
+#test created arc : it is not inversed, has coincidence to start line point
+anInversed_2 = ArcFeature_2.boolean("InversedArc").value()
+assert(anInversed_2 == False)
+ArcPoint_2 = geomDataAPI_Point2D(ArcFeature_2.attribute("ArcStartPoint"))
+LinePoint_2 = geomDataAPI_Point2D(SketchLine_2_1.startPoint())
+aDistance_2 = math.hypot(LinePoint_2.x() - ArcPoint_2.x(), LinePoint_2.y() - ArcPoint_2.y())
+#print "Distance " + repr(aDistance_2)
+assert (math.fabs(aDistance_2) <= TOLERANCE)
+# Test2:end
+
+
+# Test3: constraints to circle
+Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_3_1 = Sketch_3.addCircle(150, 50, 25)
+SketchLine_3_1 = Sketch_3.addLine(160, 30, 200, 30)
+SketchLine_3_2 = Sketch_3.addLine(160, 50, 200, 30)
+SketchLine_3_3 = Sketch_3.addLine(240, 120, 280, 100)
+SketchCircle_3_2 = Sketch_3.addCircle(150, 120, 20)
+aSketchPoint_3 = Sketch_3.addPoint(145, 70)
+SketchLine_3_4 = Sketch_3.addLine(120, 25, 120, 70)
+
+SketchConstraintCoincidence_3_1 = Sketch_3.setCoincident(SketchLine_3_1.startPoint(), SketchCircle_3_1.results()[1])
+SketchConstraintCoincidence_3_2 = Sketch_3.setCoincident(SketchLine_3_1.endPoint(), SketchLine_3_2.endPoint())
+GeomPoint_3_1 = geom.Pnt2d(165, 40)
+
+#Constraints
+aConstraint_3_1 = Sketch_3.setDistance(SketchLine_3_1.endPoint(), SketchCircle_3_1.center(), 50)
+aConstraint_3_2 = Sketch_3.setEqual(SketchCircle_3_1.results()[1], SketchCircle_3_2.results()[1])
+aConstraint_3_3 = Sketch_3.setRadius(SketchCircle_3_1.results()[1], 25)
+aConstraint_3_4 = Sketch_3.setCoincident(SketchCircle_3_1.results()[1], aSketchPoint_3.results()[0])
+aConstraint_3_4 = Sketch_3.setTangent(SketchCircle_3_1.results()[1], SketchLine_3_4.results()[0])
+
+MirrorObjects_3 = [SketchCircle_3_1.results()[1], SketchCircle_3_2.results()[1]]
+aConstraint_3_5 = Sketch_3.addMirror(SketchLine_3_3.result(), MirrorObjects_3)
+
+#check number of features before trim
+Sketch_3_feature = featureToCompositeFeature(Sketch_3.feature())
+idList_before_3 = []
+for index in range(Sketch_3_feature.numberOfSubs()):
+ idList_before_3.append(Sketch_3_feature.subFeature(index).getKind())
+
+assert(idList_before_3.count(SketchCircleId) == 4)
+assert(idList_before_3.count(SketchArcId) == 0)
+assert(idList_before_3.count(SketchLineId) == 4)
+assert(idList_before_3.count(SketchConstraintCoincidenceId) == 3)
+assert(idList_before_3.count(SketchConstraintMirrorId) == 1)
+assert(idList_before_3.count(SketchConstraintTangentId) == 1)
+assert(idList_before_3.count(SketchConstraintEqualId) == 1)
+
+#perform trim
+SketchTrim_3_1 = Sketch_3.addTrim(SketchCircle_3_1, GeomPoint_3_1)
+SketchTrim_3_1.execute()
+model.do()
+
+#check number of features after trim
+SketchFeatures = featureToCompositeFeature(Sketch_3.feature())
+idList_after_3 = []
+for SubIndex in range(SketchFeatures.numberOfSubs()):
+ SubFeature = SketchFeatures.subFeature(SubIndex)
+ idList_after_3.append(SubFeature.getKind())
+
+
+assert(idList_after_3.count(SketchCircleId) == 3)
+assert(idList_after_3.count(SketchArcId) == 1)
+assert(idList_after_3.count(SketchLineId) == 4)
+assert(idList_after_3.count(SketchConstraintCoincidenceId) == 3)
+assert(idList_after_3.count(SketchConstraintMirrorId) == 0)
+assert(idList_after_3.count(SketchConstraintTangentId) == 1)
+assert(idList_after_3.count(SketchConstraintEqualId) == 1)
+# Test3:end
+
+
+model.end()
+
+#assert(model.checkPythonDump())
SketchArcId = 'SketchArc'
SketchCircleId = 'SketchCircle'
SketchConstraintCoincidenceId = 'SketchConstraintCoincidence'
-SketchConstraintParallelId = 'SketchConstraintParallel'
+SketchConstraintMirrorId = 'SketchConstraintMirror'
SketchConstraintTangentId = 'SketchConstraintTangent'
SketchConstraintEqualId = 'SketchConstraintEqual'
assert (math.fabs(aDistance_2) <= TOLERANCE)
# Test2:end
+
+# Test3: constraints to circle
+Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_3_1 = Sketch_3.addCircle(150, 50, 25)
+SketchLine_3_1 = Sketch_3.addLine(160, 30, 200, 30)
+SketchLine_3_2 = Sketch_3.addLine(160, 50, 200, 30)
+SketchLine_3_3 = Sketch_3.addLine(240, 120, 280, 100)
+SketchCircle_3_2 = Sketch_3.addCircle(150, 120, 20)
+aSketchPoint_3 = Sketch_3.addPoint(145, 70)
+SketchLine_3_4 = Sketch_3.addLine(120, 25, 120, 70)
+
+SketchConstraintCoincidence_3_1 = Sketch_3.setCoincident(SketchLine_3_1.startPoint(), SketchCircle_3_1.results()[1])
+SketchConstraintCoincidence_3_2 = Sketch_3.setCoincident(SketchLine_3_1.endPoint(), SketchLine_3_2.endPoint())
+GeomPoint_3_1 = geom.Pnt2d(165, 40)
+
+#Constraints
+aConstraint_3_1 = Sketch_3.setDistance(SketchLine_3_1.endPoint(), SketchCircle_3_1.center(), 50)
+aConstraint_3_2 = Sketch_3.setEqual(SketchCircle_3_1.results()[1], SketchCircle_3_2.results()[1])
+aConstraint_3_3 = Sketch_3.setRadius(SketchCircle_3_1.results()[1], 25)
+aConstraint_3_4 = Sketch_3.setCoincident(SketchCircle_3_1.results()[1], aSketchPoint_3.results()[0])
+aConstraint_3_4 = Sketch_3.setTangent(SketchCircle_3_1.results()[1], SketchLine_3_4.results()[0])
+
+MirrorObjects_3 = [SketchCircle_3_1.results()[1], SketchCircle_3_2.results()[1]]
+aConstraint_3_5 = Sketch_3.addMirror(SketchLine_3_3.result(), MirrorObjects_3)
+
+#check number of features before trim
+Sketch_3_feature = featureToCompositeFeature(Sketch_3.feature())
+idList_before_3 = []
+for index in range(Sketch_3_feature.numberOfSubs()):
+ idList_before_3.append(Sketch_3_feature.subFeature(index).getKind())
+
+assert(idList_before_3.count(SketchCircleId) == 4)
+assert(idList_before_3.count(SketchArcId) == 0)
+assert(idList_before_3.count(SketchLineId) == 4)
+assert(idList_before_3.count(SketchConstraintCoincidenceId) == 3)
+assert(idList_before_3.count(SketchConstraintMirrorId) == 1)
+assert(idList_before_3.count(SketchConstraintTangentId) == 1)
+assert(idList_before_3.count(SketchConstraintEqualId) == 1)
+
+#perform trim
+SketchTrim_3_1 = Sketch_3.addTrim(SketchCircle_3_1, GeomPoint_3_1)
+SketchTrim_3_1.execute()
+model.do()
+
+#check number of features after trim
+SketchFeatures = featureToCompositeFeature(Sketch_3.feature())
+idList_after_3 = []
+for SubIndex in range(SketchFeatures.numberOfSubs()):
+ SubFeature = SketchFeatures.subFeature(SubIndex)
+ idList_after_3.append(SubFeature.getKind())
+
+
+assert(idList_after_3.count(SketchCircleId) == 3)
+assert(idList_after_3.count(SketchArcId) == 1)
+assert(idList_after_3.count(SketchLineId) == 4)
+assert(idList_after_3.count(SketchConstraintCoincidenceId) == 3)
+assert(idList_after_3.count(SketchConstraintMirrorId) == 0)
+assert(idList_after_3.count(SketchConstraintTangentId) == 1)
+assert(idList_after_3.count(SketchConstraintEqualId) == 1)
+# Test3:end
+
+
model.end()
#assert(model.checkPythonDump())
--- /dev/null
+from salome.shaper import model
+
+from ModelAPI import *
+from GeomDataAPI import *
+from salome.shaper import geom
+import math
+
+TOLERANCE = 1.e-7
+
+SketchPointId = 'SketchPoint'
+SketchLineId = 'SketchLine'
+SketchArcId = 'SketchArc'
+SketchCircleId = 'SketchCircle'
+SketchConstraintCoincidenceId = 'SketchConstraintCoincidence'
+SketchConstraintMirrorId = 'SketchConstraintMirror'
+SketchConstraintTangentId = 'SketchConstraintTangent'
+SketchConstraintEqualId = 'SketchConstraintEqual'
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+
+# Test1:begin split on circle with coincident point and intersection line : smaller part
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1_1 = Sketch_1.addCircle(50, 50, 20)
+SketchLine_1_1 = Sketch_1.addLine(50, 30, 100, 30)
+SketchLine_1_2 = Sketch_1.addLine(60, 50, 100, 30)
+
+SketchConstraintCoincidence_1_1 = Sketch_1.setCoincident(SketchLine_1_1.startPoint(), SketchCircle_1_1.results()[1])
+SketchConstraintCoincidence_1_2 = Sketch_1.setCoincident(SketchLine_1_1.endPoint(), SketchLine_1_2.endPoint())
+GeomPoint_1_1 = geom.Pnt2d(60, 35)
+
+#check number of features before trim
+Sketch_1_feature = featureToCompositeFeature(Sketch_1.feature())
+idList_before_1 = []
+for index in range(Sketch_1_feature.numberOfSubs()):
+ idList_before_1.append(Sketch_1_feature.subFeature(index).getKind())
+assert(idList_before_1.count(SketchCircleId) == 1)
+assert(idList_before_1.count(SketchArcId) == 0)
+assert(idList_before_1.count(SketchLineId) == 2)
+assert(idList_before_1.count(SketchConstraintCoincidenceId) == 2)
+
+#perform trim
+SketchTrim_1_1 = Sketch_1.addTrim(SketchCircle_1_1, GeomPoint_1_1)
+SketchTrim_1_1.execute()
+model.do()
+
+#check number of features after trim
+SketchFeatures = featureToCompositeFeature(Sketch_1.feature())
+idList_after_1 = []
+for SubIndex in range(SketchFeatures.numberOfSubs()):
+ SubFeature = SketchFeatures.subFeature(SubIndex)
+ idList_after_1.append(SubFeature.getKind())
+ if SubFeature.getKind() == SketchArcId:
+ ArcFeature_1 = SubFeature
+
+
+assert(idList_after_1.count(SketchCircleId) == 0)
+assert(idList_after_1.count(SketchArcId) == 1)
+assert(idList_after_1.count(SketchLineId) == 2)
+assert(idList_after_1.count(SketchConstraintCoincidenceId) == 3)
+
+#test created arc: it is not inversed, has coincidence to end line point
+anInversed_1 = ArcFeature_1.boolean("InversedArc").value()
+assert(anInversed_1 == False)
+ArcPoint_1 = geomDataAPI_Point2D(ArcFeature_1.attribute("ArcEndPoint"))
+LinePoint_1 = geomDataAPI_Point2D(SketchLine_1_1.startPoint())
+aDistance_1 = math.hypot(LinePoint_1.x() - ArcPoint_1.x(), LinePoint_1.y() - ArcPoint_1.y())
+#print "Distance " + repr(aDistance)
+assert (math.fabs(aDistance_1) <= TOLERANCE)
+# Test1:end
+
+
+# Test2: split on circle with coincident point and intersection line : largest part
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+move_test_delta_y = 100
+move_test_delta_x = 0
+SketchCircle_2_1 = Sketch_2.addCircle(50, 50 + move_test_delta_y, 20)
+SketchLine_2_1 = Sketch_2.addLine(50, 30 + move_test_delta_y, 100, 30 + move_test_delta_y)
+SketchLine_2_2 = Sketch_2.addLine(60, 50 + move_test_delta_y, 100, 30 + move_test_delta_y)
+
+SketchConstraintCoincidence_2_1 = Sketch_2.setCoincident(SketchLine_2_1.startPoint(), SketchCircle_2_1.results()[1])
+SketchConstraintCoincidence_2_2 = Sketch_2.setCoincident(SketchLine_2_1.endPoint(), SketchLine_2_2.endPoint())
+GeomPoint_2_1 = geom.Pnt2d(50, 75 + move_test_delta_y)
+
+#check number of features before trim
+Sketch_2_feature = featureToCompositeFeature(Sketch_2.feature())
+idList_before_2 = []
+for index in range(Sketch_2_feature.numberOfSubs()):
+ idList_before_2.append(Sketch_2_feature.subFeature(index).getKind())
+assert(idList_before_2.count(SketchCircleId) == 1)
+assert(idList_before_2.count(SketchArcId) == 0)
+assert(idList_before_2.count(SketchLineId) == 2)
+assert(idList_before_2.count(SketchConstraintCoincidenceId) == 2)
+
+#perform trim
+SketchTrim_2_1 = Sketch_2.addTrim(SketchCircle_2_1, GeomPoint_2_1)
+SketchTrim_2_1.execute()
+model.do()
+
+#check number of features after trim
+SketchFeatures = featureToCompositeFeature(Sketch_2.feature())
+idList_after_2 = []
+for SubIndex in range(SketchFeatures.numberOfSubs()):
+ SubFeature = SketchFeatures.subFeature(SubIndex)
+ idList_after_2.append(SubFeature.getKind())
+ if SubFeature.getKind() == SketchArcId:
+ ArcFeature_2 = SubFeature
+
+
+assert(idList_after_2.count(SketchCircleId) == 0)
+assert(idList_after_2.count(SketchArcId) == 1)
+assert(idList_after_2.count(SketchLineId) == 2)
+assert(idList_after_2.count(SketchConstraintCoincidenceId) == 3)
+
+#test created arc : it is not inversed, has coincidence to start line point
+anInversed_2 = ArcFeature_2.boolean("InversedArc").value()
+assert(anInversed_2 == False)
+ArcPoint_2 = geomDataAPI_Point2D(ArcFeature_2.attribute("ArcStartPoint"))
+LinePoint_2 = geomDataAPI_Point2D(SketchLine_2_1.startPoint())
+aDistance_2 = math.hypot(LinePoint_2.x() - ArcPoint_2.x(), LinePoint_2.y() - ArcPoint_2.y())
+#print "Distance " + repr(aDistance_2)
+assert (math.fabs(aDistance_2) <= TOLERANCE)
+# Test2:end
+
+
+# Test3: constraints to circle
+Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_3_1 = Sketch_3.addCircle(150, 50, 25)
+SketchLine_3_1 = Sketch_3.addLine(160, 30, 200, 30)
+SketchLine_3_2 = Sketch_3.addLine(160, 50, 200, 30)
+SketchLine_3_3 = Sketch_3.addLine(240, 120, 280, 100)
+SketchCircle_3_2 = Sketch_3.addCircle(150, 120, 20)
+aSketchPoint_3 = Sketch_3.addPoint(145, 70)
+SketchLine_3_4 = Sketch_3.addLine(120, 25, 120, 70)
+
+SketchConstraintCoincidence_3_1 = Sketch_3.setCoincident(SketchLine_3_1.startPoint(), SketchCircle_3_1.results()[1])
+SketchConstraintCoincidence_3_2 = Sketch_3.setCoincident(SketchLine_3_1.endPoint(), SketchLine_3_2.endPoint())
+GeomPoint_3_1 = geom.Pnt2d(165, 40)
+
+#Constraints
+aConstraint_3_1 = Sketch_3.setDistance(SketchLine_3_1.endPoint(), SketchCircle_3_1.center(), 50)
+aConstraint_3_2 = Sketch_3.setEqual(SketchCircle_3_1.results()[1], SketchCircle_3_2.results()[1])
+aConstraint_3_3 = Sketch_3.setRadius(SketchCircle_3_1.results()[1], 25)
+aConstraint_3_4 = Sketch_3.setCoincident(SketchCircle_3_1.results()[1], aSketchPoint_3.results()[0])
+aConstraint_3_4 = Sketch_3.setTangent(SketchCircle_3_1.results()[1], SketchLine_3_4.results()[0])
+
+MirrorObjects_3 = [SketchCircle_3_1.results()[1], SketchCircle_3_2.results()[1]]
+aConstraint_3_5 = Sketch_3.addMirror(SketchLine_3_3.result(), MirrorObjects_3)
+
+#check number of features before trim
+Sketch_3_feature = featureToCompositeFeature(Sketch_3.feature())
+idList_before_3 = []
+for index in range(Sketch_3_feature.numberOfSubs()):
+ idList_before_3.append(Sketch_3_feature.subFeature(index).getKind())
+
+assert(idList_before_3.count(SketchCircleId) == 4)
+assert(idList_before_3.count(SketchArcId) == 0)
+assert(idList_before_3.count(SketchLineId) == 4)
+assert(idList_before_3.count(SketchConstraintCoincidenceId) == 3)
+assert(idList_before_3.count(SketchConstraintMirrorId) == 1)
+assert(idList_before_3.count(SketchConstraintTangentId) == 1)
+assert(idList_before_3.count(SketchConstraintEqualId) == 1)
+
+#perform trim
+SketchTrim_3_1 = Sketch_3.addTrim(SketchCircle_3_1, GeomPoint_3_1)
+SketchTrim_3_1.execute()
+model.do()
+
+#check number of features after trim
+SketchFeatures = featureToCompositeFeature(Sketch_3.feature())
+idList_after_3 = []
+for SubIndex in range(SketchFeatures.numberOfSubs()):
+ SubFeature = SketchFeatures.subFeature(SubIndex)
+ idList_after_3.append(SubFeature.getKind())
+
+
+assert(idList_after_3.count(SketchCircleId) == 3)
+assert(idList_after_3.count(SketchArcId) == 1)
+assert(idList_after_3.count(SketchLineId) == 4)
+assert(idList_after_3.count(SketchConstraintCoincidenceId) == 3)
+assert(idList_after_3.count(SketchConstraintMirrorId) == 0)
+assert(idList_after_3.count(SketchConstraintTangentId) == 1)
+assert(idList_after_3.count(SketchConstraintEqualId) == 1)
+# Test3:end
+
+
+model.end()
+
+#assert(model.checkPythonDump())
<toolbox id="ArcType">
<box id="CenterStartEnd" title="Center and two points" icon="icons/Sketch/arc_base_32x32.png">
<sketch-2dpoint_selector id="ArcCenter" accept_expressions="0" title="Center" tooltip="Center of a circle"
- enable_value="enable_by_preferences"/>
+ enable_value="enable_by_preferences" reference_attribute="ArcCenterRef"/>
<sketch-2dpoint_selector id="ArcStartPoint" accept_expressions="0" title="Start point" tooltip="Start point"
enable_value="enable_by_preferences"/>
<sketch-2dpoint_selector id="ArcEndPoint" accept_expressions="0" title="End point" tooltip="End point"