1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: PlaneGCSSolver_Storage.cpp
4 // Created: 14 Dec 2015
5 // Author: Artem ZHIDKOV
7 #include <PlaneGCSSolver_Storage.h>
8 #include <PlaneGCSSolver_Builder.h>
9 #include <PlaneGCSSolver_Solver.h>
10 #include <PlaneGCSSolver_ConstraintWrapper.h>
11 #include <PlaneGCSSolver_EntityWrapper.h>
12 #include <PlaneGCSSolver_PointWrapper.h>
13 #include <PlaneGCSSolver_ScalarWrapper.h>
14 #include <PlaneGCSSolver_ParameterWrapper.h>
16 #include <GeomAPI_Edge.h>
17 #include <GeomAPI_Dir2d.h>
18 #include <GeomAPI_Pnt2d.h>
19 #include <GeomAPI_XY.h>
20 #include <GeomDataAPI_Point2D.h>
21 ////#include <ModelAPI_AttributeRefAttr.h>
22 ////#include <ModelAPI_Feature.h>
23 ////#include <ModelAPI_ResultConstruction.h>
25 #include <SketchPlugin_Arc.h>
26 ////#include <SketchPlugin_Circle.h>
27 ////#include <SketchPlugin_Line.h>
28 ////#include <SketchPlugin_Point.h>
31 ////#include <SketchPlugin_ConstraintAngle.h>
37 /////** \brief Search the entity/parameter with specified ID in the list of elements
38 //// * \param[in] theEntityID unique ID of the element
39 //// * \param[in] theEntities list of elements
40 //// * \return position of the found element or -1 if the element is not found
42 ////template<typename T>
43 ////static int Search(const uint32_t& theEntityID, const std::vector<T>& theEntities);
45 /////// \brief Compare two parameters to be different
46 ////static bool IsNotEqual(const Slvs_Param& theParam1, const Slvs_Param& theParam2);
47 /////// \brief Compare two entities to be different
48 ////static bool IsNotEqual(const Slvs_Entity& theEntity1, const Slvs_Entity& theEntity2);
49 /////// \brief Compare two constriants to be different
50 ////static bool IsNotEqual(const Slvs_Constraint& theConstraint1, const Slvs_Constraint& theConstraint2);
54 PlaneGCSSolver_Storage::PlaneGCSSolver_Storage(const GroupID& theGroup)
55 : SketchSolver_Storage(theGroup),
56 myEntityLastID(EID_SKETCH)
60 void PlaneGCSSolver_Storage::addConstraint(
61 ConstraintPtr theConstraint,
62 std::list<ConstraintWrapperPtr> theSolverConstraints)
64 SketchSolver_Storage::addConstraint(theConstraint, theSolverConstraints);
66 // update point-point coincidence
67 if (!theSolverConstraints.empty() &&
68 theSolverConstraints.front()->type() == CONSTRAINT_PT_PT_COINCIDENT) {
69 std::list<ConstraintWrapperPtr>::iterator aCIt = theSolverConstraints.begin();
70 for (; aCIt != theSolverConstraints.end(); ++aCIt)
76 bool PlaneGCSSolver_Storage::update(ConstraintWrapperPtr theConstraint)
78 bool isUpdated = false;
79 std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aConstraint =
80 std::dynamic_pointer_cast<PlaneGCSSolver_ConstraintWrapper>(theConstraint);
82 // point-Line distance should be positive
83 if (aConstraint->type() == CONSTRAINT_PT_LINE_DISTANCE && aConstraint->value() < 0.0)
84 aConstraint->setValue(-aConstraint->value());
86 // make value of constraint unchangeable
87 ParameterWrapperPtr aValue = aConstraint->valueParameter();
89 isUpdated = update(aValue) || isUpdated;
91 // update constrained entities
92 std::list<EntityWrapperPtr> anEntities = theConstraint->entities();
93 std::list<EntityWrapperPtr>::iterator anIt = anEntities.begin();
94 for (; anIt != anEntities.end(); ++anIt)
95 isUpdated = update(*anIt) || isUpdated;
100 /// \brief Update coordinates of the point or scalar using its base attribute
101 static bool updateValues(EntityWrapperPtr& theEntity)
103 bool isUpdated = false;
104 AttributePtr anAttr = theEntity->baseAttribute();
105 const std::list<ParameterWrapperPtr> aParams = theEntity->parameters();
109 std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
110 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr);
112 aCoord[0] = aPoint2D->x();
113 aCoord[1] = aPoint2D->y();
115 AttributeDoublePtr aScalar = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anAttr);
117 aCoord[0] = aScalar->value();
120 std::list<ParameterWrapperPtr>::const_iterator anIt = aParams.begin();
121 for (int i = 0; anIt != aParams.end(); ++anIt, ++i)
122 if (fabs((*anIt)->value() - aCoord[i]) > tolerance) {
123 (*anIt)->setValue(aCoord[i]);
129 bool PlaneGCSSolver_Storage::update(EntityWrapperPtr theEntity)
131 if (theEntity->type() == ENTITY_SKETCH)
132 return true; // sketch is not necessary for PlaneGCS, so it is always says true
134 bool isUpdated = false;
136 if (theEntity->baseAttribute()) {
137 isUpdated = updateValues(theEntity);
139 setNeedToResolve(true);
143 std::list<ParameterWrapperPtr> aParams = theEntity->parameters();
144 std::list<ParameterWrapperPtr>::iterator aPIt = aParams.begin();
145 for (; aPIt != aParams.end(); ++aPIt)
146 isUpdated = update(*aPIt) || isUpdated;
148 // update sub-entities
149 std::list<EntityWrapperPtr> aSubEntities = theEntity->subEntities();
150 std::list<EntityWrapperPtr>::iterator aSIt = aSubEntities.begin();
151 for (; aSIt != aSubEntities.end(); ++aSIt)
152 isUpdated = update(*aSIt) || isUpdated;
154 // additional constraints for the arc processing
155 if (theEntity->type() == ENTITY_ARC)
156 processArc(theEntity);
158 // Change entity's ID, if necessary
159 if (theEntity->id() == EID_UNKNOWN) {
160 if (theEntity->type() == ENTITY_POINT) {
161 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
162 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theEntity);
163 aPoint->setId(++myEntityLastID);
164 } else if (theEntity->type() == ENTITY_SCALAR) {
165 std::shared_ptr<PlaneGCSSolver_ScalarWrapper> aScalar =
166 std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(theEntity);
167 aScalar->setId(++myEntityLastID);
169 std::shared_ptr<PlaneGCSSolver_EntityWrapper> aGCSEnt =
170 std::dynamic_pointer_cast<PlaneGCSSolver_EntityWrapper>(theEntity);
171 aGCSEnt->setId(++myEntityLastID);
177 bool PlaneGCSSolver_Storage::update(ParameterWrapperPtr theParameter)
179 std::shared_ptr<PlaneGCSSolver_ParameterWrapper> aParam =
180 std::dynamic_pointer_cast<PlaneGCSSolver_ParameterWrapper>(theParameter);
181 if (aParam->isProcessed())
183 if (theParameter->group() != myGroupID || theParameter->isParametric())
184 myConst.push_back(aParam->parameter());
186 myParameters.push_back(aParam->parameter());
187 aParam->setProcessed(true);
192 bool PlaneGCSSolver_Storage::remove(ConstraintWrapperPtr theConstraint)
194 std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aConstraint =
195 std::dynamic_pointer_cast<PlaneGCSSolver_ConstraintWrapper>(theConstraint);
197 bool isFullyRemoved = true;
198 const std::list<EntityWrapperPtr>& aSubs = aConstraint->entities();
199 std::list<EntityWrapperPtr>::const_iterator aSIt = aSubs.begin();
200 for (; aSIt != aSubs.end(); ++ aSIt)
201 isFullyRemoved = remove(*aSIt) && isFullyRemoved;
203 if (aConstraint->valueParameter())
204 isFullyRemoved = remove(aConstraint->valueParameter()) && isFullyRemoved;
205 if (!isFullyRemoved &&
206 (!aConstraint->baseConstraint()->data() || !aConstraint->baseConstraint()->data()->isValid()))
207 isFullyRemoved = true;
208 if (isFullyRemoved) {
209 setNeedToResolve(true);
210 myRemovedConstraints.insert(myRemovedConstraints.end(),
211 aConstraint->constraints().begin(), aConstraint->constraints().end());
213 return isFullyRemoved;
216 bool PlaneGCSSolver_Storage::remove(EntityWrapperPtr theEntity)
218 if ((theEntity->baseAttribute() && isUsed(theEntity->baseAttribute())) ||
219 (theEntity->baseFeature() && isUsed(theEntity->baseFeature())))
222 bool isFullyRemoved = SketchSolver_Storage::remove(theEntity);
223 if (isFullyRemoved && theEntity->id() == myEntityLastID)
225 return isFullyRemoved;
228 bool PlaneGCSSolver_Storage::remove(ParameterWrapperPtr theParameter)
230 std::shared_ptr<PlaneGCSSolver_ParameterWrapper> aParam =
231 std::dynamic_pointer_cast<PlaneGCSSolver_ParameterWrapper>(theParameter);
232 if (aParam->isProcessed()) {
233 double* aValPtr = aParam->parameter();
234 GCS::VEC_pD::iterator anIt = myParameters.begin();
235 for (; anIt != myParameters.end(); ++anIt)
236 if (*anIt == aValPtr)
238 if (anIt != myParameters.end()) {
239 myParameters.erase(anIt);
240 setNeedToResolve(true);
243 for (anIt = myConst.begin(); anIt != myConst.end(); ++anIt)
244 if (*anIt == aValPtr)
246 if (anIt != myConst.end()) {
248 setNeedToResolve(true);
252 aParam->setProcessed(false);
257 void PlaneGCSSolver_Storage::addCoincidentPoints(
258 EntityWrapperPtr theMaster, EntityWrapperPtr theSlave)
260 if (theMaster->type() != ENTITY_POINT || theSlave->type() != ENTITY_POINT)
263 // Search available coincidence
264 CoincidentPointsMap::iterator aMasterFound = myCoincidentPoints.find(theMaster);
265 CoincidentPointsMap::iterator aSlaveFound = myCoincidentPoints.find(theSlave);
266 if (aMasterFound == myCoincidentPoints.end() && aSlaveFound == myCoincidentPoints.end()) {
267 // try to find master and slave points in the lists of slaves of already existent coincidences
268 CoincidentPointsMap::iterator anIt = myCoincidentPoints.begin();
269 for (; anIt != myCoincidentPoints.end(); ++anIt) {
270 if (anIt->second.find(theMaster) != anIt->second.end())
272 else if (anIt->second.find(theSlave) != anIt->second.end())
275 if (aMasterFound != myCoincidentPoints.end() && aSlaveFound != myCoincidentPoints.end())
280 if (aMasterFound == myCoincidentPoints.end()) {
282 myCoincidentPoints[theMaster] = std::set<EntityWrapperPtr>();
283 aMasterFound = myCoincidentPoints.find(theMaster);
284 } else if (aMasterFound == aSlaveFound)
285 return; // already coincident
287 if (aSlaveFound != myCoincidentPoints.end()) {
288 // A slave has been found, we need to attach all points coincident with it to the new master
289 std::set<EntityWrapperPtr> aNewSlaves = aSlaveFound->second;
290 aNewSlaves.insert(aSlaveFound->first);
291 myCoincidentPoints.erase(aSlaveFound);
293 std::set<EntityWrapperPtr>::const_iterator aSlIt = aNewSlaves.begin();
294 for (; aSlIt != aNewSlaves.end(); ++aSlIt)
295 addCoincidentPoints(theMaster, *aSlIt);
297 //// std::list<ParameterWrapperPtr> aSlaveParams = theSlave->parameters();
298 //// theSlave->setParameters(theMaster->parameters());
300 //// // Remove slave's parameters
301 //// std::list<ParameterWrapperPtr>::iterator aParIt = aSlaveParams.begin();
302 //// for (; aParIt != aSlaveParams.end(); ++aParIt)
303 //// remove(*aParIt);
305 aMasterFound->second.insert(theSlave);
310 void PlaneGCSSolver_Storage::changeGroup(EntityWrapperPtr theEntity, const GroupID& theGroup)
312 theEntity->setGroup(theGroup);
313 if (theGroup == myGroupID)
314 makeVariable(theEntity);
316 makeConstant(theEntity);
319 void PlaneGCSSolver_Storage::changeGroup(ParameterWrapperPtr theParam, const GroupID& theGroup)
324 void PlaneGCSSolver_Storage::verifyFixed()
332 ////void PlaneGCSSolver_Storage::changeConstraint(
333 //// const ConstraintPtr& theConstraint,
334 //// const std::vector<GCSConstraintPtr>& theGCSConstraints)
336 //// myConstraintsMap[theConstraint] = theGCSConstraints;
339 ////void PlaneGCSSolver_Storage::addConstraint(GCSConstraintPtr theConstraint)
341 //// std::map<ConstraintPtr, std::vector<GCSConstraintPtr> >::iterator
342 //// aFound = myConstraintsMap.find(ConstraintPtr());
343 //// if (aFound != myConstraintsMap.end())
344 //// aFound->second.push_back(theConstraint);
346 //// std::vector<GCSConstraintPtr> aConstrVec(1, theConstraint);
347 //// myConstraintsMap[ConstraintPtr()] = aConstrVec;
351 ////EntityID PlaneGCSSolver_Storage::changeEntity(const FeaturePtr& theEntity)
353 //// if (!theEntity || !theEntity->data() || !theEntity->data()->isValid())
354 //// return ENTITY_UNKNOWN;
356 //// // Firstly, try to find entity
357 //// std::map<FeaturePtr, EntityID>::const_iterator aFound = myFeatureEntityMap.find(theEntity);
359 //// EntityID aNewEntID;
360 //// if (aFound != myFeatureEntityMap.end())
361 //// aNewEntID = aFound->second;
363 //// const std::string& aFeatureKind = theEntity->getKind();
364 //// // SketchPlugin features
365 //// if (aFeatureKind == SketchPlugin_Line::ID())
366 //// updateLine(theEntity, aNewEntID);
368 //// else if (aFeatureKind == SketchPlugin_Circle::ID())
369 //// updateCircle(theEntity, aNewEntID);
371 //// else if (aFeatureKind == SketchPlugin_Arc::ID())
372 //// updateArc(theEntity, aNewEntID);
373 //// // Point (it has low probability to be an attribute of constraint, so it is checked at the end)
374 //// else if (aFeatureKind == SketchPlugin_Point::ID()) {
375 //// AttributePtr anAttribute = theEntity->attribute(SketchPlugin_Point::COORD_ID());
376 //// if (!anAttribute->isInitialized())
377 //// return ENTITY_UNKNOWN;
378 //// // Both the sketch point and its attribute (coordinates) link to the same SolveSpace point identifier
379 //// aNewEntID = changeEntity(anAttribute);
381 //// else // NOTE: Other types of entities are unsupported
382 //// aNewEntID = ENTITY_UNKNOWN;
384 //// if (aNewEntID != ENTITY_UNKNOWN)
385 //// myFeatureEntityMap[theEntity] = aNewEntID;
386 //// return aNewEntID;
389 ////EntityID PlaneGCSSolver_Storage::changeEntity(const AttributePtr& theEntity)
392 //// return ENTITY_UNKNOWN;
394 //// AttributeRefAttrPtr aRefAttr =
395 //// std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theEntity);
397 //// if (aRefAttr->isObject()) {
398 //// ResultConstructionPtr aRC =
399 //// std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aRefAttr->object());
401 //// return ENTITY_UNKNOWN;
402 //// return changeEntity(ModelAPI_Feature::feature(aRC));
405 //// return changeEntity(aRefAttr->attr());
408 //// EntityID aNewEntID = ENTITY_UNKNOWN;
410 //// // Firstly, try to find entity
411 //// std::map<AttributePtr, EntityID>::const_iterator aFound = myAttributeEntityMap.find(theEntity);
412 //// // Check type of attribute and create corresponding entity
413 //// std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
414 //// std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theEntity);
416 //// if (aFound != myAttributeEntityMap.end())
417 //// aNewEntID = aFound->second;
418 //// updatePoint(aPoint2D, aNewEntID);
420 //// AttributeDoublePtr aScalar = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theEntity);
422 //// // Check the scalar represents an angular value
423 //// bool isAngular = false;
424 //// FeaturePtr anOwner = ModelAPI_Feature::feature(aScalar->owner());
425 //// if (anOwner && anOwner->getKind() == SketchPlugin_ConstraintAngle::ID())
426 //// isAngular = true;
428 //// if (aFound != myAttributeEntityMap.end())
429 //// aNewEntID = aFound->second;
431 //// updateAngle(aScalar, aNewEntID);
433 //// updateScalar(aScalar, aNewEntID);
436 //// // NOTE: Other types of attributes are not supported
438 //// // Map attribute and new entity ID
439 //// if (aFound == myAttributeEntityMap.end() && aNewEntID != ENTITY_UNKNOWN)
440 //// myAttributeEntityMap[theEntity] = aNewEntID;
441 //// return aNewEntID;
445 ////bool PlaneGCSSolver_Storage::removeConstraint(const ConstraintPtr& theConstraint)
447 //// std::map<ConstraintPtr, std::vector<GCSConstraintPtr> >::iterator
448 //// aFound = myConstraintsMap.find(theConstraint);
449 //// if (aFound == myConstraintsMap.end())
450 //// return true; // no constraint - nothing to remove
452 //// std::vector<GCSConstraintPtr> aConstrList = aFound->second;
453 //// myConstraintsMap.erase(aFound);
454 //// bool isFullyRemoved = removeEntity(theConstraint->attribute(SketchPlugin_Constraint::VALUE()));
455 //// for (int ind = 0; ind < CONSTRAINT_ATTR_SIZE; ++ind)
456 //// isFullyRemoved = removeEntity(theConstraint->attribute(SketchPlugin_Constraint::ATTRIBUTE(ind)))
457 //// && isFullyRemoved;
459 //// myRemovedConstraints.insert(myRemovedConstraints.end(), aConstrList.begin(), aConstrList.end());
461 //// return isFullyRemoved;
464 ////bool PlaneGCSSolver_Storage::removeConstraint(GCSConstraintPtr theConstraint)
466 //// std::map<ConstraintPtr, std::vector<GCSConstraintPtr> >::iterator
467 //// aFound = myConstraintsMap.find(ConstraintPtr());
468 //// if (aFound != myConstraintsMap.end()) {
469 //// std::vector<GCSConstraintPtr>::iterator anIt = aFound->second.begin();
470 //// for (; anIt != aFound->second.end(); ++anIt)
471 //// if (*anIt == theConstraint) {
472 //// aFound->second.erase(anIt);
477 //// myRemovedConstraints.push_back(theConstraint);
481 ////bool PlaneGCSSolver_Storage::removeEntity(const FeaturePtr& theFeature)
483 //// if (!theFeature)
485 //// if (isUsed(theFeature))
488 //// // remove feature and corresponding entity
489 //// std::map<FeaturePtr, EntityID>::iterator aFound = myFeatureEntityMap.find(theFeature);
490 //// if (aFound != myFeatureEntityMap.end()) {
491 //// if (aFound->second.type == ARC) {
492 //// // remove additional arc constraints
493 //// std::map<EntityID, std::vector<GCSConstraintPtr> >::iterator aFoundArc =
494 //// myArcConstraintMap.find(aFound->second);
495 //// if (aFoundArc != myArcConstraintMap.end()) {
496 //// myRemovedConstraints.insert(myRemovedConstraints.end(),
497 //// aFoundArc->second.begin(), aFoundArc->second.end());
498 //// myArcConstraintMap.erase(aFoundArc);
501 //// myGCSEntities.erase(aFound->second);
502 //// myFeatureEntityMap.erase(aFound);
505 //// // remove feature's attributes
506 //// bool isFullyRemoved = true;
507 //// std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
508 //// std::list<AttributePtr>::iterator anAttrIt = anAttributes.begin();
509 //// for (; anAttrIt != anAttributes.end(); ++anAttrIt)
510 //// isFullyRemoved = removeEntity(*anAttrIt) && isFullyRemoved;
511 //// return isFullyRemoved;
514 ////bool PlaneGCSSolver_Storage::removeEntity(const AttributePtr& theAttribute)
516 //// if (!theAttribute)
518 //// if (isUsed(theAttribute))
521 //// AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
523 //// if (aRefAttr->isObject()) {
524 //// FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
525 //// return removeEntity(aFeature);
527 //// return removeEntity(aRefAttr->attr());
530 //// // remove attribute and corresponding entity
531 //// std::map<AttributePtr, EntityID>::iterator aFound = myAttributeEntityMap.find(theAttribute);
532 //// if (aFound == myAttributeEntityMap.end())
533 //// return true; // no attribute, nothing to remove
535 //// if (aFound->second.type == SCALAR || aFound->second.type == ANGLE) {
536 //// std::map<EntityID, double*>::iterator aFoundScalar = myGCSScalars.find(aFound->second);
537 //// if (aFoundScalar != myGCSScalars.end()) {
538 //// removeParameters(aFoundScalar->second);
539 //// myGCSScalars.erase(aFoundScalar);
542 //// else if (aFound->second.type == POINT) {
543 //// std::map<EntityID, GCSPointPtr>::iterator aFoundPoint = myGCSPoints.find(aFound->second);
544 //// if (aFoundPoint != myGCSPoints.end()) {
545 //// removeParameters(aFoundPoint->second->x, aFoundPoint->second->y);
546 //// myGCSPoints.erase(aFoundPoint);
550 //// myAttributeEntityMap.erase(aFound);
554 ////void PlaneGCSSolver_Storage::removeParameters(double* theParam1, double* theParam2)
556 //// int aNbRemoved = 2;
557 //// for (int ind = 0; ind < 2 && aNbRemoved > 0; ++ind) {
558 //// GCS::VEC_pD& aList = ind ==0 ? myParameters : myConst;
560 //// GCS::VEC_pD::iterator aParIt = aList.begin();
561 //// while (aNbRemoved > 0 && aParIt != aList.end()) {
562 //// if (*aParIt != theParam1 && *aParIt != theParam2) {
567 //// myRemovedParameters.push_back(*aParIt);
568 //// int aShift = aParIt - aList.begin();
569 //// aList.erase(aParIt);
570 //// aParIt = aList.begin() + aShift;
577 ////double* PlaneGCSSolver_Storage::createScalar(const AttributeDoublePtr& theScalar)
579 //// double* aResult = new double;
581 //// *aResult = theScalar->value();
582 //// myParameters.push_back(aResult);
583 //// myNeedToResolve = true;
587 ////void PlaneGCSSolver_Storage::updateScalar(const AttributeDoublePtr& theScalar, EntityID& theID)
589 //// std::map<EntityID, double*>::const_iterator aFound = myGCSScalars.find(theID);
590 //// if (aFound == myGCSScalars.end()) {
592 //// theID = ++myEntityLastID;
593 //// theID.type = SCALAR;
594 //// myGCSScalars[theID] = createScalar(theScalar);
596 //// else if (fabs(*(myGCSScalars[theID]) - theScalar->value()) > tolerance) {
597 //// *(myGCSScalars[theID]) = theScalar->value();
598 //// myNeedToResolve = true;
602 ////void PlaneGCSSolver_Storage::updateAngle(const AttributeDoublePtr& theAngle, EntityID& theID)
604 //// std::map<EntityID, double*>::const_iterator aFound = myGCSScalars.find(theID);
605 //// if (aFound == myGCSScalars.end()) {
607 //// theID = ++myEntityLastID;
608 //// theID.type = ANGLE;
609 //// myGCSScalars[theID] = createScalar(theAngle);
611 //// else if (fabs(*(myGCSScalars[theID]) - theAngle->value()) > tolerance) {
612 //// *(myGCSScalars[theID]) = theAngle->value();
613 //// myNeedToResolve = true;
615 //// // Convert degrees to radians
616 //// *(myGCSScalars[theID]) *= M_PI / 180.0;
619 ////GCS::Point PlaneGCSSolver_Storage::createPoint(const std::shared_ptr<GeomDataAPI_Point2D>& thePoint)
621 //// GCS::Point aResult;
622 //// aResult.x = new double(thePoint->x());
623 //// aResult.y = new double(thePoint->y());
625 //// myParameters.push_back(aResult.x);
626 //// myParameters.push_back(aResult.y);
628 //// myNeedToResolve = true;
632 ////void PlaneGCSSolver_Storage::updatePoint(const std::shared_ptr<GeomDataAPI_Point2D>& thePoint,
633 //// EntityID& theID)
635 //// std::map<EntityID, GCSPointPtr>::iterator aFound = myGCSPoints.find(theID);
636 //// if (aFound == myGCSPoints.end()) {
638 //// theID = ++myEntityLastID;
639 //// theID.type = POINT;
640 //// myGCSPoints[theID] = GCSPointPtr(new GCS::Point(createPoint(thePoint)));
642 //// else if (fabs(*(aFound->second->x) - thePoint->x()) > tolerance ||
643 //// fabs(*(aFound->second->y) - thePoint->y()) > tolerance) {
645 //// *(aFound->second->x) = thePoint->x();
646 //// *(aFound->second->y) = thePoint->y();
647 //// myNeedToResolve = true;
651 ////void PlaneGCSSolver_Storage::updateLine(const FeaturePtr& theLine, EntityID& theID)
653 //// std::shared_ptr<GeomDataAPI_Point2D> aStartAttr =
654 //// std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
655 //// theLine->attribute(SketchPlugin_Line::START_ID()));
656 //// std::shared_ptr<GeomDataAPI_Point2D> aEndAttr =
657 //// std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
658 //// theLine->attribute(SketchPlugin_Line::END_ID()));
659 //// if (!aStartAttr->isInitialized() || !aEndAttr->isInitialized()) {
660 //// theID = ENTITY_UNKNOWN;
664 //// std::map<EntityID, GCSCurvePtr>::iterator aFound = myGCSEntities.find(theID);
665 //// if (aFound == myGCSEntities.end()) {
667 //////// theID = ++myEntityLastID;
668 //////// theID.type = LINE;
670 //////// EntityID aStartID = changeEntity(aStartAttr);
671 //////// EntityID aEndID = changeEntity(aEndAttr);
672 //////// GCS::Point* aStart = getPoint(aStartID);
673 //////// GCS::Point* aEnd = getPoint(aEndID);
675 //////// std::shared_ptr<GCS::Line> aLine(new GCS::Line);
676 //////// aLine->p1 = *aStart;
677 //////// aLine->p2 = *aEnd;
678 //////// myGCSEntities[theID] = aLine;
681 //// // update line parameters
682 //// std::map<AttributePtr, EntityID>::iterator aFoundAttr = myAttributeEntityMap.find(aStartAttr);
683 //// if (aFoundAttr != myAttributeEntityMap.end())
684 //// updatePoint(aStartAttr, aFoundAttr->second);
685 //// aFoundAttr = myAttributeEntityMap.find(aEndAttr);
686 //// if (aFoundAttr != myAttributeEntityMap.end())
687 //// updatePoint(aEndAttr, aFoundAttr->second);
691 ////void PlaneGCSSolver_Storage::updateCircle(const FeaturePtr& theCircle, EntityID& theID)
693 //// std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr =
694 //// std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
695 //// theCircle->attribute(SketchPlugin_Circle::CENTER_ID()));
696 //// AttributeDoublePtr aRadiusAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
697 //// theCircle->attribute(SketchPlugin_Circle::RADIUS_ID()));
698 //// if (!aCenterAttr->isInitialized() || !aRadiusAttr->isInitialized()) {
699 //// theID = ENTITY_UNKNOWN;
703 //// std::map<EntityID, GCSCurvePtr>::iterator aFound = myGCSEntities.find(theID);
704 //// if (aFound == myGCSEntities.end()) {
705 //////// // new circle
706 //////// theID = ++myEntityLastID;
707 //////// theID.type = CIRCLE;
709 //////// EntityID aCenterID = changeEntity(aCenterAttr);
710 //////// EntityID aRadiusID = changeEntity(aRadiusAttr);
711 //////// GCS::Point* aCenter = getPoint(aCenterID);
712 //////// double* aRadius = getScalar(aRadiusID);
714 //////// std::shared_ptr<GCS::Circle> aCircle(new GCS::Circle);
715 //////// aCircle->center = *aCenter;
716 //////// aCircle->rad = aRadius;
717 //////// myGCSEntities[theID] = aCircle;
720 //// // update circle parameters
721 //// std::map<AttributePtr, EntityID>::iterator aFoundAttr = myAttributeEntityMap.find(aCenterAttr);
722 //// if (aFoundAttr != myAttributeEntityMap.end())
723 //// updatePoint(aCenterAttr, aFoundAttr->second);
724 //// aFoundAttr = myAttributeEntityMap.find(aRadiusAttr);
725 //// if (aFoundAttr != myAttributeEntityMap.end())
726 //// updateScalar(aRadiusAttr, aFoundAttr->second);
730 ////void PlaneGCSSolver_Storage::updateArc(const FeaturePtr& theArc, EntityID& theID)
732 //// std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr =
733 //// std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
734 //// theArc->attribute(SketchPlugin_Arc::CENTER_ID()));
735 //// std::shared_ptr<GeomDataAPI_Point2D> aStartAttr =
736 //// std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
737 //// theArc->attribute(SketchPlugin_Arc::START_ID()));
738 //// std::shared_ptr<GeomDataAPI_Point2D> aEndAttr =
739 //// std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
740 //// theArc->attribute(SketchPlugin_Arc::END_ID()));
741 //// if (!aCenterAttr->isInitialized() ||
742 //// !aStartAttr->isInitialized() ||
743 //// !aEndAttr->isInitialized()) {
744 //// theID = ENTITY_UNKNOWN;
748 //// std::shared_ptr<GCS::Arc> anArc;
749 //// std::map<EntityID, GCSCurvePtr>::iterator aFound = myGCSEntities.find(theID);
750 //// if (aFound == myGCSEntities.end()) {
752 //// theID = ++myEntityLastID;
753 //// theID.type = ARC;
755 //// EntityID aCenterID = changeEntity(aCenterAttr);
756 //// EntityID aStartID = changeEntity(aStartAttr);
757 //// EntityID aEndID = changeEntity(aEndAttr);
758 //// GCS::Point* aCenter = getPoint(aCenterID);
759 //// GCS::Point* aStart = getPoint(aStartID);
760 //// GCS::Point* aEnd = getPoint(aEndID);
762 //// anArc = std::shared_ptr<GCS::Arc>(new GCS::Arc);
763 //// anArc->center = *aCenter;
764 //// anArc->start = *aStart;
765 //// anArc->end = *aEnd;
766 //// anArc->startAngle = createScalar();
767 //// anArc->endAngle = createScalar();
768 //// anArc->rad = createScalar();
769 //// myGCSEntities[theID] = anArc;
771 //// // Additional constraints for new arc
772 //// processArc(theID);
775 //// // update arc parameters
776 //// anArc = std::dynamic_pointer_cast<GCS::Arc>(aFound->second);
777 //// std::map<AttributePtr, EntityID>::iterator aFoundAttr = myAttributeEntityMap.find(aCenterAttr);
778 //// if (aFoundAttr != myAttributeEntityMap.end())
779 //// updatePoint(aCenterAttr, aFoundAttr->second);
780 //// aFoundAttr = myAttributeEntityMap.find(aStartAttr);
781 //// if (aFoundAttr != myAttributeEntityMap.end())
782 //// updatePoint(aStartAttr, aFoundAttr->second);
783 //// aFoundAttr = myAttributeEntityMap.find(aEndAttr);
784 //// if (aFoundAttr != myAttributeEntityMap.end())
785 //// updatePoint(aEndAttr, aFoundAttr->second);
788 //// // Calculate additional parameters necessary for FreeGCS
789 //// std::shared_ptr<GeomAPI_Pnt2d> aCenterPnt = aCenterAttr->pnt();
790 //// std::shared_ptr<GeomAPI_Pnt2d> aStartPnt = aStartAttr->pnt();
791 //// std::shared_ptr<GeomAPI_Pnt2d> aEndPnt = aEndAttr->pnt();
793 //// *(anArc->rad) = aCenterPnt->distance(aStartPnt);
794 //// std::shared_ptr<GeomAPI_Edge> anArcEdge =
795 //// std::dynamic_pointer_cast<GeomAPI_Edge>(theArc->lastResult()->shape());
796 //// if (!anArcEdge) {
797 //// theID = ENTITY_UNKNOWN;
800 //// anArcEdge->getRange(*(anArc->startAngle), *(anArc->endAngle));
804 ////double* PlaneGCSSolver_Storage::getScalar(const EntityID& theID) const
806 //// std::map<EntityID, double*>::const_iterator aFound = myGCSScalars.find(theID);
807 //// if (aFound == myGCSScalars.end())
809 //// return aFound->second;
812 ////GCS::Point* PlaneGCSSolver_Storage::getPoint(const EntityID& theID) const
814 //// std::map<EntityID, GCSPointPtr>::const_iterator aFound = myGCSPoints.find(theID);
815 //// if (aFound == myGCSPoints.end())
817 //// return aFound->second.get();
820 ////GCS::Line* PlaneGCSSolver_Storage::getLine(const EntityID& theID) const
822 //// std::map<EntityID, GCSCurvePtr>::const_iterator aFound = myGCSEntities.find(theID);
823 //// if (aFound == myGCSEntities.end())
825 //// std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(aFound->second);
828 //// return aLine.get();
831 ////GCS::Circle* PlaneGCSSolver_Storage::getCircle(const EntityID& theID) const
833 //// std::map<EntityID, GCSCurvePtr>::const_iterator aFound = myGCSEntities.find(theID);
834 //// if (aFound == myGCSEntities.end())
836 //// std::shared_ptr<GCS::Circle> aCircle = std::dynamic_pointer_cast<GCS::Circle>(aFound->second);
839 //// return aCircle.get();
842 ////GCS::Arc* PlaneGCSSolver_Storage::getArc(const EntityID& theID) const
844 //// std::map<EntityID, GCSCurvePtr>::const_iterator aFound = myGCSEntities.find(theID);
845 //// if (aFound == myGCSEntities.end())
847 //// std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(aFound->second);
850 //// return anArc.get();
853 void PlaneGCSSolver_Storage::processArc(const EntityWrapperPtr& theArc)
855 // Calculate additional parameters necessary for PlaneGCS
856 const std::list<EntityWrapperPtr>& aSubs = theArc->subEntities();
857 std::list<EntityWrapperPtr>::const_iterator aSubIt = aSubs.begin();
858 while ((*aSubIt)->type() == ENTITY_POINT) // search scalar entities
860 double* aStartAngle = std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(*aSubIt++)->scalar();
861 double* aEndAngle = std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(*aSubIt++)->scalar();
862 double* aRadius = std::dynamic_pointer_cast<PlaneGCSSolver_ScalarWrapper>(*aSubIt)->scalar();
864 FeaturePtr anArcFeature = theArc->baseFeature();
865 std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
866 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
867 std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
868 anArcFeature->attribute(SketchPlugin_Arc::START_ID()));
869 std::shared_ptr<GeomDataAPI_Point2D> aEndAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
870 anArcFeature->attribute(SketchPlugin_Arc::END_ID()));
871 std::shared_ptr<GeomAPI_Pnt2d> aCenterPnt = aCenterAttr->pnt();
872 std::shared_ptr<GeomAPI_Pnt2d> aStartPnt = aStartAttr->pnt();
873 std::shared_ptr<GeomAPI_Pnt2d> aEndPnt = aEndAttr->pnt();
875 *aRadius = aCenterPnt->distance(aStartPnt);
876 if (!anArcFeature->lastResult())
878 std::shared_ptr<GeomAPI_Edge> anArcEdge =
879 std::dynamic_pointer_cast<GeomAPI_Edge>(anArcFeature->lastResult()->shape());
882 anArcEdge->getRange(*aStartAngle, *aEndAngle);
884 // No need to add constraints if they are already exist
885 std::map<EntityWrapperPtr, std::vector<GCSConstraintPtr> >::const_iterator
886 aFound = myArcConstraintMap.find(theArc);
887 if (aFound != myArcConstraintMap.end())
890 // Prepare additional constraints to produce the arc
891 std::vector<GCSConstraintPtr> anArcConstraints;
892 std::shared_ptr<PlaneGCSSolver_EntityWrapper> anArcEnt =
893 std::dynamic_pointer_cast<PlaneGCSSolver_EntityWrapper>(theArc);
894 std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anArcEnt->entity());
895 // Distances from center till start and end points are equal to radius
896 anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
897 anArc->center, anArc->start, anArc->rad)));
898 anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PDistance(
899 anArc->center, anArc->end, anArc->rad)));
900 // Angles of start and end points should be equal to given angles
901 anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
902 anArc->center, anArc->start, anArc->startAngle)));
903 anArcConstraints.push_back(GCSConstraintPtr(new GCS::ConstraintP2PAngle(
904 anArc->center, anArc->end, anArc->endAngle)));
906 myArcConstraintMap[theArc] = anArcConstraints;
909 ////const std::vector<GCSConstraintPtr>& PlaneGCSSolver_Storage::getConstraint(
910 //// const ConstraintPtr& theConstraint) const
912 //// static const std::vector<GCSConstraintPtr> aDummy;
914 //// std::map<ConstraintPtr, std::vector<GCSConstraintPtr> >::const_iterator
915 //// aFound = myConstraintsMap.find(theConstraint);
916 //// if (aFound == myConstraintsMap.end())
918 //// return aFound->second;
922 void PlaneGCSSolver_Storage::makeConstant(const EntityWrapperPtr& theEntity)
924 toggleEntity(theEntity, myParameters, myConst);
927 void PlaneGCSSolver_Storage::makeVariable(const EntityWrapperPtr& theEntity)
929 toggleEntity(theEntity, myConst, myParameters);
932 static void getParametersToMove(const EntityWrapperPtr& theEntity, std::set<double*>& theParamList)
934 const std::list<ParameterWrapperPtr> aParams = theEntity->parameters();
935 std::list<ParameterWrapperPtr>::const_iterator aPIt = aParams.begin();
936 for (; aPIt != aParams.end(); ++aPIt)
938 std::dynamic_pointer_cast<PlaneGCSSolver_ParameterWrapper>(*aPIt)->parameter());
940 const std::list<EntityWrapperPtr> aSubs = theEntity->subEntities();
941 std::list<EntityWrapperPtr>::const_iterator aSIt = aSubs.begin();
942 for (; aSIt != aSubs.end(); ++aSIt)
943 getParametersToMove(*aSIt, theParamList);
946 void PlaneGCSSolver_Storage::toggleEntity(
947 const EntityWrapperPtr& theEntity, GCS::VEC_pD& theFrom, GCS::VEC_pD& theTo)
949 std::set<double*> aParamsToMove;
950 getParametersToMove(theEntity, aParamsToMove);
952 GCS::VEC_pD::iterator anIt = theFrom.begin();
953 while (anIt != theFrom.end()) {
954 if (aParamsToMove.find(*anIt) == aParamsToMove.end()) {
959 theTo.push_back(*anIt);
960 int aShift = anIt - theFrom.begin();
962 anIt = theFrom.begin() + aShift;
967 void PlaneGCSSolver_Storage::initializeSolver(SolverPtr theSolver)
969 std::shared_ptr<PlaneGCSSolver_Solver> aSolver =
970 std::dynamic_pointer_cast<PlaneGCSSolver_Solver>(theSolver);
972 // initialize constraints
973 std::map<ConstraintPtr, std::list<ConstraintWrapperPtr> >::const_iterator
974 aCIt = myConstraintMap.begin();
975 for (; aCIt != myConstraintMap.end(); ++aCIt) {
976 std::list<ConstraintWrapperPtr>::const_iterator aCWIt = aCIt->second.begin();
977 for (; aCWIt != aCIt->second.end(); ++ aCWIt) {
978 std::shared_ptr<PlaneGCSSolver_ConstraintWrapper> aGCS =
979 std::dynamic_pointer_cast<PlaneGCSSolver_ConstraintWrapper>(*aCWIt);
980 std::list<GCSConstraintPtr>::const_iterator anIt = aGCS->constraints().begin();
981 for (; anIt != aGCS->constraints().end(); ++anIt)
982 aSolver->addConstraint(*anIt);
985 // additional constraints for arcs
986 std::map<EntityWrapperPtr, std::vector<GCSConstraintPtr> >::const_iterator
987 anArcIt = myArcConstraintMap.begin();
988 for (; anArcIt != myArcConstraintMap.end(); ++anArcIt) {
989 std::vector<GCSConstraintPtr>::const_iterator anIt = anArcIt->second.begin();
990 for (; anIt != anArcIt->second.end(); ++anIt)
991 aSolver->addConstraint(*anIt);
993 // removed waste constraints
994 std::list<GCSConstraintPtr>::const_iterator aRemIt = myRemovedConstraints.begin();
995 for (; aRemIt != myRemovedConstraints.end(); ++aRemIt)
996 aSolver->removeConstraint(*aRemIt);
997 myRemovedConstraints.clear();
998 //// // remove waste parameters
999 //// std::list<double*>::const_iterator aRemParIt = myRemovedParameters.begin();
1000 //// for (; aRemParIt != myRemovedParameters.end(); ++aRemParIt)
1001 //// delete *aRemParIt;
1002 //// myRemovedParameters.clear();
1003 // initialize unknowns
1004 aSolver->setParameters(myParameters);
1007 void PlaneGCSSolver_Storage::refresh(bool theFixedOnly) const
1009 //blockEvents(true);
1011 std::map<AttributePtr, EntityWrapperPtr>::const_iterator anIt = myAttributeMap.begin();
1012 std::list<ParameterWrapperPtr> aParams;
1013 std::list<ParameterWrapperPtr>::const_iterator aParIt;
1014 for (; anIt != myAttributeMap.end(); ++anIt) {
1015 // the external feature always should keep the up to date values, so,
1016 // refresh from the solver is never needed
1017 if (anIt->first.get()) {
1018 std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
1019 std::dynamic_pointer_cast<SketchPlugin_Feature>(anIt->first->owner());
1020 if (aSketchFeature.get() && aSketchFeature->isExternal())
1024 // update parameter wrappers and obtain values of attributes
1025 aParams = anIt->second->parameters();
1027 bool isUpd[3] = {false};
1029 for (aParIt = aParams.begin(); i < 3 && aParIt != aParams.end(); ++aParIt, ++i) {
1030 if (!theFixedOnly || (*aParIt)->group() == GID_OUTOFGROUP || (*aParIt)->isParametric()) {
1031 aCoords[i] = (*aParIt)->value();
1035 if (!isUpd[0] && !isUpd[1] && !isUpd[2])
1036 continue; // nothing is updated
1038 std::shared_ptr<GeomDataAPI_Point2D> aPoint2D =
1039 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anIt->first);
1041 if ((isUpd[0] && fabs(aPoint2D->x() - aCoords[0]) > tolerance) ||
1042 (isUpd[1] && fabs(aPoint2D->y() - aCoords[1]) > tolerance)) {
1043 if (!isUpd[0]) aCoords[0] = aPoint2D->x();
1044 if (!isUpd[1]) aCoords[1] = aPoint2D->y();
1045 aPoint2D->setValue(aCoords[0], aCoords[1]);
1046 // Find points coincident with this one (probably not in GID_OUTOFGROUP)
1047 std::map<AttributePtr, EntityWrapperPtr>::const_iterator aLocIt =
1048 theFixedOnly ? myAttributeMap.begin() : anIt;
1049 for (++aLocIt; aLocIt != myAttributeMap.end(); ++aLocIt)
1050 if (anIt->second->id() == aLocIt->second->id()) {
1051 aPoint2D = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aLocIt->first);
1053 aPoint2D->setValue(aCoords[0], aCoords[1]);
1058 AttributeDoublePtr aScalar = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(anIt->first);
1060 if (isUpd[0] && fabs(aScalar->value() - aCoords[0]) > tolerance)
1061 aScalar->setValue(aCoords[0]);
1066 //blockEvents(false);
1069 EntityWrapperPtr PlaneGCSSolver_Storage::calculateMiddlePoint(
1070 EntityWrapperPtr theBase, double theCoeff)
1072 std::shared_ptr<PlaneGCSSolver_Builder> aBuilder =
1073 std::dynamic_pointer_cast<PlaneGCSSolver_Builder>(PlaneGCSSolver_Builder::getInstance());
1075 std::shared_ptr<GeomAPI_XY> aMidPoint;
1076 if (theBase->type() == ENTITY_LINE) {
1077 std::shared_ptr<GeomAPI_Pnt2d> aPoints[2];
1078 const std::list<EntityWrapperPtr>& aSubs = theBase->subEntities();
1079 std::list<EntityWrapperPtr>::const_iterator anIt = aSubs.begin();
1080 for (int i = 0; i < 2; ++i, ++anIt)
1081 aPoints[i] = aBuilder->point(*anIt);
1082 aMidPoint = aPoints[0]->xy()->multiplied(1.0 - theCoeff)->added(
1083 aPoints[1]->xy()->multiplied(theCoeff));
1085 else if (theBase->type() == ENTITY_ARC) {
1087 double anArcPoint[3][2];
1088 const std::list<EntityWrapperPtr>& aSubs = theBase->subEntities();
1089 std::list<EntityWrapperPtr>::const_iterator anIt = aSubs.begin();
1090 for (int i = 0; i < 3; ++i, ++anIt) {
1091 std::shared_ptr<GeomAPI_Pnt2d> aPoint = aBuilder->point(*anIt);
1092 anArcPoint[i][0] = aPoint->x();
1093 anArcPoint[i][1] = aPoint->y();
1095 // project last point of arc on the arc
1096 double x = anArcPoint[1][0] - anArcPoint[0][0];
1097 double y = anArcPoint[1][1] - anArcPoint[0][1];
1098 double aRad = sqrt(x*x + y*y);
1099 x = anArcPoint[2][0] - anArcPoint[0][0];
1100 y = anArcPoint[2][1] - anArcPoint[0][1];
1101 double aNorm = sqrt(x*x + y*y);
1102 if (aNorm >= tolerance) {
1103 anArcPoint[2][0] = x * aRad / aNorm;
1104 anArcPoint[2][1] = y * aRad / aNorm;
1106 anArcPoint[1][0] -= anArcPoint[0][0];
1107 anArcPoint[1][1] -= anArcPoint[0][1];
1108 if (theCoeff < tolerance) {
1109 theX = anArcPoint[0][0] + anArcPoint[1][0];
1110 theY = anArcPoint[0][1] + anArcPoint[1][1];
1111 } else if (1 - theCoeff < tolerance) {
1112 theX = anArcPoint[0][0] + anArcPoint[2][0];
1113 theY = anArcPoint[0][1] + anArcPoint[2][1];
1115 std::shared_ptr<GeomAPI_Dir2d> aStartDir(new GeomAPI_Dir2d(anArcPoint[1][0], anArcPoint[1][1]));
1116 std::shared_ptr<GeomAPI_Dir2d> aEndDir(new GeomAPI_Dir2d(anArcPoint[2][0], anArcPoint[2][1]));
1117 double anAngle = aStartDir->angle(aEndDir);
1119 anAngle += 2.0 * PI;
1120 anAngle *= theCoeff;
1121 double aCos = cos(anAngle);
1122 double aSin = sin(anAngle);
1123 theX = anArcPoint[0][0] + anArcPoint[1][0] * aCos - anArcPoint[1][1] * aSin;
1124 theY = anArcPoint[0][1] + anArcPoint[1][0] * aSin + anArcPoint[1][1] * aCos;
1126 aMidPoint = std::shared_ptr<GeomAPI_XY>(new GeomAPI_XY(theX, theY));
1130 return EntityWrapperPtr();
1132 std::list<ParameterWrapperPtr> aParameters;
1133 aParameters.push_back(aBuilder->createParameter(myGroupID, aMidPoint->x()));
1134 aParameters.push_back(aBuilder->createParameter(myGroupID, aMidPoint->y()));
1135 // Create entity (parameters are not filled)
1136 GCSPointPtr aPnt(new GCS::Point);
1137 aPnt->x = std::dynamic_pointer_cast<PlaneGCSSolver_ParameterWrapper>(aParameters.front())->parameter();
1138 aPnt->y = std::dynamic_pointer_cast<PlaneGCSSolver_ParameterWrapper>(aParameters.back())->parameter();
1140 EntityWrapperPtr aResult(new PlaneGCSSolver_PointWrapper(AttributePtr(), aPnt));
1141 aResult->setGroup(myGroupID);
1142 aResult->setParameters(aParameters);
1148 ////bool PlaneGCSSolver_Storage::isInteract(AttributePtr theAttribute) const
1150 //// std::map<AttributePtr, EntityID>::const_iterator aFound = myAttributeEntityMap.find(theAttribute);
1151 //// if (aFound != myAttributeEntityMap.end())
1154 //// AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
1157 //// if (aRefAttr->isObject()) {
1158 //// FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->object());
1161 //// return isInteract(aFeature);
1164 //// return isInteract(aRefAttr->attr());
1167 ////bool PlaneGCSSolver_Storage::isInteract(FeaturePtr theFeature) const
1169 //// if (myFeatureEntityMap.find(theFeature) != myFeatureEntityMap.end())
1171 //// std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
1172 //// std::list<AttributePtr>::iterator anIt = anAttributes.begin();
1173 //// for (; anIt != anAttributes.end(); ++anIt)
1174 //// if (isInteract(*anIt))
1180 ////bool PlaneGCSSolver_Storage::isUsed(const FeaturePtr& theFeature) const
1182 //// // There is checked only the feature itself, not its attributes.
1183 //// // The attributes should be checked separately.
1185 //// std::map<ConstraintPtr, std::vector<GCSConstraintPtr> >::const_iterator
1186 //// aCIt = myConstraintsMap.begin();
1187 //// for (; aCIt != myConstraintsMap.end(); ++aCIt) {
1188 //// if (!aCIt->first)
1190 //// for (int ind = 0; ind < CONSTRAINT_ATTR_SIZE; ++ind) {
1191 //// AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1192 //// aCIt->first->attribute(SketchPlugin_Constraint::ATTRIBUTE(ind)));
1193 //// if (aRefAttr && aRefAttr->isObject()) {
1194 //// FeaturePtr aFeat = ModelAPI_Feature::feature(aRefAttr->object());
1195 //// if (aFeat == theFeature)
1203 ////bool PlaneGCSSolver_Storage::isUsed(const AttributePtr& theAttribute) const
1205 //// // Check whether the attribute is used by constraints
1206 //// std::map<ConstraintPtr, std::vector<GCSConstraintPtr> >::const_iterator
1207 //// aCIt = myConstraintsMap.begin();
1208 //// for (; aCIt != myConstraintsMap.end(); ++aCIt) {
1209 //// if (!aCIt->first)
1211 //// if (aCIt->first->attribute(SketchPlugin_Constraint::VALUE()) == theAttribute)
1213 //// for (int ind = 0; ind < CONSTRAINT_ATTR_SIZE; ++ind) {
1214 //// AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1215 //// aCIt->first->attribute(SketchPlugin_Constraint::ATTRIBUTE(ind)));
1218 //// if (aRefAttr == theAttribute ||
1219 //// (!aRefAttr->isObject() && aRefAttr->attr() == theAttribute))
1224 //// // Check whether the attribute is used by features
1225 //// std::map<FeaturePtr, EntityID>::const_iterator aFIt = myFeatureEntityMap.begin();
1226 //// for (; aFIt != myFeatureEntityMap.end(); ++aFIt) {
1227 //// std::list<AttributePtr> anAttrs =
1228 //// aFIt->first->data()->attributes(GeomDataAPI_Point2D::typeId());
1229 //// std::list<AttributePtr>::const_iterator anIt = anAttrs.begin();
1230 //// for (; anIt != anAttrs.end(); ++anIt)
1231 //// if (*anIt == theAttribute)
1239 ////void PlaneGCSSolver_Storage::blockEvents(bool isBlocked)
1241 //// std::map<FeaturePtr, EntityID>::iterator aFIt = myFeatureEntityMap.begin();
1242 //// for (; aFIt != myFeatureEntityMap.end(); ++aFIt)
1243 //// if (aFIt->first->data() && aFIt->first->data()->isValid())
1244 //// aFIt->first->data()->blockSendAttributeUpdated(isBlocked);
1246 //// std::map<AttributePtr, EntityID>::iterator anAIt = myAttributeEntityMap.begin();
1247 //// for (; anAIt != myAttributeEntityMap.end(); ++anAIt)
1248 //// if (anAIt->first->owner() && anAIt->first->owner()->data() &&
1249 //// anAIt->first->owner()->data()->isValid())
1250 //// anAIt->first->owner()->data()->blockSendAttributeUpdated(isBlocked);