#include <ModelAPI_AttributeString.h>
#include <ModelAPI_AttributeRefAttr.h>
#include <ModelAPI_Tools.h>
+#include <ModelAPI_AttributeBoolean.h>
#include <ModelAPI_Validator.h>
#include <ModelAPI_Session.h>
#include <SketchPlugin_ConstraintMirror.h>
#include <SketchPlugin_MultiRotation.h>
#include <SketchPlugin_MultiTranslation.h>
+#include <SketchPlugin_ConstraintMiddle.h>
#include <ModelAPI_Events.h>
#include <SketchPlugin_Line.h>
#include <cmath>
+//#define CREATE_CONSTRAINTS
+
//#define DEBUG_SPLIT
#ifdef DEBUG_SPLIT
#include <iostream>
#endif
-#define CIRCLE_FEATURE_DELETE_WITHOUT_REFERENCES
-
static const double PI = 3.141592653589793238463;
SketchPlugin_ConstraintSplit::SketchPlugin_ConstraintSplit()
FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
std::set<FeaturePtr> aFeaturesToDelete, aFeaturesToUpdate;
- #ifdef CIRCLE_FEATURE_DELETE_WITHOUT_REFERENCES
- FeaturePtr aCircleFeatureToDelete;
- #endif
- 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()) {
- std::cout << std::endl;
- std::cout << "Tangencies to base feature[" << aTangentFeatures.size() << "]: " << std::endl;
- std::map<FeaturePtr, IdToPointPair>::const_iterator anIt = aTangentFeatures.begin(),
- aLast = aTangentFeatures.end();
- for (int i = 1; anIt != aLast; anIt++, i++) {
- FeaturePtr aFeature = (*anIt).first;
- std::string anAttributeId = (*anIt).second.first;
- std::shared_ptr<GeomDataAPI_Point2D> aPointAttr = (*anIt).second.second;
-
- std::cout << i << "-" << getFeatureInfo(aFeature) << std::endl;
- std::cout << " -Attribute to correct:" << anAttributeId << std::endl;
- std::cout << " -Point attribute:" <<
- ModelGeomAlgo_Point2D::getPointAttributeInfo(aPointAttr) << std::endl;
- }
- }
-
std::map<AttributePtr, std::list<AttributePtr> >::const_iterator
aRefIt = aBaseRefAttributes.begin(), aRefLast = aBaseRefAttributes.end();
std::cout << std::endl << "References to attributes of base feature [" <<
updateRefFeatureConstraints(getFeatureResult(aBaseFeature), aRefsToFeature);
AttributePtr aCenterAttr = aCircleFeature->attribute(SketchPlugin_Circle::CENTER_ID());
-#ifdef CIRCLE_FEATURE_DELETE_WITHOUT_REFERENCES
- aCircleFeatureToDelete = aCircleFeature;
-#else
aFeaturesToDelete.insert(aCircleFeature);
-#endif
// as circle is removed, temporary fill this attribute*/
aBaseObjectAttr->setObject(ResultPtr());
}
// coincidence to feature
updateCoincidenceConstraintsToFeature(aCoincidenceToFeature, aFurtherCoincidences,
aFeatureResults, aSplitFeature);
- // tangency
- updateTangentConstraintsToFeature(aTangentFeatures, aFurtherCoincidences);
updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes);
}
#endif
ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
-#ifdef CIRCLE_FEATURE_DELETE_WITHOUT_REFERENCES
- std::set<FeaturePtr> aCircleFeatures;
- aCircleFeatures.insert(aCircleFeatureToDelete);
- ModelAPI_Tools::removeFeatures(aCircleFeatures, false);
-#endif
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
#ifdef DEBUG_SPLIT
std::cout << "update features after split:" << std::endl;
std::set<std::shared_ptr<GeomAPI_Shape> > aSplitShapes;
- GeomAlgoAPI_ShapeTools::splitShape(aBaseShape, aPoints, aSplitShapes);
+ GeomAlgoAPI_ShapeTools::splitShape_p(aBaseShape, aPoints, aSplitShapes);
std::shared_ptr<GeomAPI_Shape> aShape =
GeomAlgoAPI_ShapeTools::findShape(aPoints, aSplitShapes);
if (!anAIS)
anAIS = AISObjectPtr(new GeomAPI_AISObject);
anAIS->createShape(aShape);
- anAIS->setWidth(5);
+ std::shared_ptr<ModelAPI_AttributeBoolean> anAuxiliaryAttr =
+ aBaseFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID());
+
+ bool isConstruction = anAuxiliaryAttr.get() != NULL && anAuxiliaryAttr->value();
+
std::vector<int> aColor;
- aColor = Config_PropManager::color("Visualization", "sketch_entity_color",
- SKETCH_ENTITY_COLOR);
- anAIS->setColor(aColor[0], aColor[1], aColor[2]);
+ double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH();
+ int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE();
+ if (isConstruction) {
+ aColor = Config_PropManager::color("Visualization", "sketch_auxiliary_color");
+ aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH_AUXILIARY();
+ aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY();
+ }
+ else {
+ aColor = Config_PropManager::color("Visualization", "sketch_entity_color");
+ }
+ anAIS->setColor(aColor[0], aColor[1], aColor[2]);
+ anAIS->setWidth(aWidth + 1);
+ anAIS->setLineStyle(aLineStyle);
}
return anAIS;
}
void SketchPlugin_ConstraintSplit::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete,
std::set<FeaturePtr>& theFeaturesToUpdate,
- std::map<FeaturePtr, IdToPointPair>& theTangentFeatures,
std::map<FeaturePtr, IdToPointPair>& theCoincidenceToFeature)
{
std::shared_ptr<ModelAPI_Data> aData = data();
std::string aRefFeatureKind = aRefFeature->getKind();
if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
- aRefFeatureKind == SketchPlugin_MultiTranslation::ID())
+ 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(ATTRIBUTE(i));
- 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()) {
- FeaturePtr aFeature1 = ModelAPI_Feature::feature(aResult1);
- std::string anAttributeToBeModified = aFeature1 == aBaseFeature
- ? SketchPlugin_Constraint::ENTITY_A() : SketchPlugin_Constraint::ENTITY_B();
- theTangentFeatures[aRefFeature] = std::make_pair(anAttributeToBeModified, aTangentPoint);
- }
- else /// there is not coincident point between tangent constraint
- theFeaturesToDelete.insert(aRefFeature);
- }
- }
else if (aRefFeatureKind == SketchPlugin_ConstraintCoincidence::ID()) {
std::string anAttributeToBeModified;
AttributePoint2DPtr aCoincidentPoint;
}
}
-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,
const std::list<AttributePtr>& theRefsToFeature)
thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
(theSplitFeature->attribute(SketchPlugin_Line::START_ID())));
+#ifdef CREATE_CONSTRAINTS
// additional constraints between split and base features
aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintParallel::ID(),
getFeatureResult(aBaseFeature),
getFeatureResult(theAfterFeature));
theCreatedFeatures.insert(aConstraintFeature);
}
+#endif
}
void SketchPlugin_ConstraintSplit::splitArc(FeaturePtr& theSplitFeature,
return;
}
- // manually change type of arc to avoid incorrect self-constrainting of the tangent arc
- aBaseFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue(
- SketchPlugin_Arc::ARC_TYPE_CENTER_START_END());
-
arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase,
aFirstPointAttrOfSplit, aSecondPointAttrOfSplit);
#ifdef DEBUG_SPLIT
(theSplitFeature->attribute(SketchPlugin_Arc::START_ID())));
// additional constraints between split and base features
+#ifdef CREATE_CONSTRAINTS
aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(),
getFeatureResult(aBaseFeature),
getFeatureResult(theSplitFeature));
getFeatureResult(theAfterFeature));
theCreatedFeatures.insert(aConstraintFeature);
}
+#endif
}
void SketchPlugin_ConstraintSplit::splitCircle(FeaturePtr& theSplitFeature,
theSplitFeature->attribute(SketchPlugin_Arc::START_ID()));
theCreatedFeatures.insert(aConstraintFeature);
+#ifdef CREATE_CONSTRAINTS
aConstraintFeature = createConstraintForObjects(SketchPlugin_ConstraintTangent::ID(),
getFeatureResult(theSplitFeature),
getFeatureResult(theBaseFeatureModified));
theCreatedFeatures.insert(aConstraintFeature);
+#endif
}
void SketchPlugin_ConstraintSplit::arrangePointsOnLine(
std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
- bool isReversed = theArc->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
+ bool isReversed = theArc->boolean(SketchPlugin_Arc::REVERSED_ID())->value();
// collect directions to each point
std::shared_ptr<GeomAPI_Dir2d> aStartDir(
void SketchPlugin_ConstraintSplit::fillAttribute(const AttributePtr& theModifiedAttribute,
const AttributePtr& theSourceAttribute)
{
- AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theModifiedAttribute);
- AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
- theSourceAttribute);
-
- if (aModifiedAttribute.get() && aSourceAttribute.get())
- aModifiedAttribute->setValue(aSourceAttribute->pnt());
+ std::string anAttributeType = theModifiedAttribute->attributeType();
+ if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
+ AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theModifiedAttribute);
+ AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+ theSourceAttribute);
+
+ if (aModifiedAttribute.get() && aSourceAttribute.get())
+ aModifiedAttribute->setValue(aSourceAttribute->pnt());
+ }
+ else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) {
+ AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
+ theModifiedAttribute);
+ AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
+ theSourceAttribute);
+
+ if (aModifiedAttribute.get() && aSourceAttribute.get())
+ aModifiedAttribute->setValue(aSourceAttribute->value());
+ }
}
FeaturePtr SketchPlugin_ConstraintSplit::createLineFeature(const FeaturePtr& theBaseFeature,
fillAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPointAttr);
fillAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPointAttr);
+
+ fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
+ theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
+
aFeature->execute(); // to obtain result
return aFeature;
// update fillet arc: make the arc correct for sure, so, it is not needed to process
// the "attribute updated"
// by arc; moreover, it may cause cyclicity in hte mechanism of updater
- aFeature->data()->blockSendAttributeUpdated(true);
-
- aFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue(
- SketchPlugin_Arc::ARC_TYPE_CENTER_START_END());
+ bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true);
fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
theBaseFeature->attribute(aCenterAttributeId));
fillAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPointAttr);
fillAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPointAttr);
+ fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
+ theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
+
/// fill referersed state of created arc as it is on the base arc
if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
- bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
- aFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->setValue(aReversed);
+ bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->value();
+ aFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(aReversed);
}
- aFeature->data()->blockSendAttributeUpdated(false);
+ aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
aFeature->execute(); // to obtain result
return aFeature;
return anAttributes;
}
-
+#ifdef _DEBUG
std::string SketchPlugin_ConstraintSplit::getFeatureInfo(
const std::shared_ptr<ModelAPI_Feature>& theFeature,
const bool isUseAttributesInfo)
}
return anInfo;
}
-
+#endif