1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include <SketchSolver_ConstraintFixed.h>
22 #include <SketchSolver_Error.h>
24 #include <PlaneGCSSolver_ConstraintWrapper.h>
25 #include <PlaneGCSSolver_EdgeWrapper.h>
26 #include <PlaneGCSSolver_EntityDestroyer.h>
27 #include <PlaneGCSSolver_FeatureBuilder.h>
28 #include <PlaneGCSSolver_PointWrapper.h>
30 #include <GeomDataAPI_Point2D.h>
31 #include <SketchPlugin_Feature.h>
35 // Verify the points are equal
36 static bool isEqual(const GCS::Point& thePoint1, const GCS::Point& thePoint2);
37 // Verify the entities are equal
38 static bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2);
39 // Convert entity to the list of parameters
40 static GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity);
43 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(ConstraintPtr theConstraint)
44 : SketchSolver_Constraint(theConstraint)
46 myType = CONSTRAINT_FIXED;
49 SketchSolver_ConstraintFixed::SketchSolver_ConstraintFixed(FeaturePtr theFeature)
50 : SketchSolver_Constraint(),
51 myBaseFeature(theFeature)
53 myType = CONSTRAINT_FIXED;
56 void SketchSolver_ConstraintFixed::blockEvents(bool isBlocked)
59 myBaseFeature->data()->blockSendAttributeUpdated(isBlocked);
61 SketchSolver_Constraint::blockEvents(isBlocked);
64 void SketchSolver_ConstraintFixed::process()
67 if ((!myBaseConstraint && !myBaseFeature) || !myStorage) {
68 // Not enough parameters are assigned
72 EntityWrapperPtr aBaseEntity;
73 getAttributes(aBaseEntity, myFixedEntity);
75 moveFeature(); // remove myFixed entity
76 myErrorMsg = SketchSolver_Error::ALREADY_FIXED();
78 if (!myErrorMsg.empty())
81 fixFeature(aBaseEntity);
84 void SketchSolver_ConstraintFixed::fixFeature(EntityWrapperPtr theFeature)
86 GCS::VEC_pD aParameters = toParameters(theFeature);
88 // Fix given list of parameters
89 std::list<GCSConstraintPtr> aConstraints;
90 myFixedValues.reserve(aParameters.size());
91 GCS::VEC_pD::const_iterator anIt = aParameters.begin();
92 for (int i = 0; anIt != aParameters.end(); ++anIt, ++i) {
93 myFixedValues.push_back(**anIt);
94 aConstraints.push_back(
95 GCSConstraintPtr(new GCS::ConstraintEqual(&myFixedValues[i], *anIt)));
98 myConstraint = ConstraintWrapperPtr(
99 new PlaneGCSSolver_ConstraintWrapper(aConstraints, getType()));
101 if (myBaseConstraint)
102 myStorage->addConstraint(myBaseConstraint, myConstraint);
104 myStorage->addTemporaryConstraint(myConstraint);
107 void SketchSolver_ConstraintFixed::getAttributes(EntityWrapperPtr& theBaseEntity,
108 EntityWrapperPtr& theFixedEntity)
111 // if the feature is copy, do not move it
112 std::shared_ptr<SketchPlugin_Feature> aSketchFeature =
113 std::dynamic_pointer_cast<SketchPlugin_Feature>(myBaseFeature);
114 if (aSketchFeature && aSketchFeature->isCopy()) {
115 myStorage->setNeedToResolve(true);
119 bool fixFullFeature = false;
120 theBaseEntity = EntityWrapperPtr();
121 theFixedEntity = EntityWrapperPtr();
123 // The feature is fixed.
124 PlaneGCSSolver_FeatureBuilder aBuilder;
125 std::list<AttributePtr> aBaseAttr = myBaseFeature->data()->attributes(std::string());
126 std::list<AttributePtr>::const_iterator anIt = aBaseAttr.begin();
127 for (; anIt != aBaseAttr.end(); ++anIt) {
128 EntityWrapperPtr anEntity = aBuilder.createAttribute(*anIt);
129 EntityWrapperPtr aBaseEntity = myStorage->entity(*anIt);
130 if (!anEntity || !aBaseEntity)
133 if (!fixFullFeature && anEntity->type() == ENTITY_POINT &&
134 !isEqual(anEntity, aBaseEntity)) {
136 fixFullFeature = true;
137 theFixedEntity = anEntity;
138 theBaseEntity = aBaseEntity;
142 if (fixFullFeature) {
143 theFixedEntity = aBuilder.createFeature(myBaseFeature);
144 theBaseEntity = myStorage->entity(myBaseFeature);
145 if (isEqual(theBaseEntity, theFixedEntity))
146 theBaseEntity = EntityWrapperPtr(); // do not want to fix already fixed entity
149 } else if (myBaseConstraint) {
150 // Constraint Fixed is added by user.
151 // Get the attribute of constraint (it should be alone in the list of constraints).
152 EntityWrapperPtr aValue;
153 std::vector<EntityWrapperPtr> anAttributes;
154 SketchSolver_Constraint::getAttributes(aValue, anAttributes);
155 std::vector<EntityWrapperPtr>::const_iterator anIt = anAttributes.begin();
156 for (; anIt != anAttributes.end(); ++anIt)
158 theBaseEntity = *anIt;
160 myErrorMsg = SketchSolver_Error::NOT_INITIALIZED();
163 void SketchSolver_ConstraintFixed::moveFeature()
168 GCS::VEC_pD aFixedParams = toParameters(myFixedEntity);
169 for (int i = 0; i < aFixedParams.size() && i < myFixedValues.size(); ++i)
170 myFixedValues[i] = *(aFixedParams[i]);
172 // Remove fixed entity due to its parameters already copied into the constraint
173 PlaneGCSSolver_EntityDestroyer aDestroyer;
174 aDestroyer.remove(myFixedEntity);
175 std::dynamic_pointer_cast<PlaneGCSSolver_Storage>(myStorage)->removeParameters(
176 aDestroyer.parametersToRemove());
178 myFixedEntity = EntityWrapperPtr();
184 // ==================== Auxiliary functions ===============================
185 GCS::VEC_pD toParameters(const EntityWrapperPtr& theEntity)
187 GCS::VEC_pD aParameters;
191 std::shared_ptr<PlaneGCSSolver_EdgeWrapper> anEntity =
192 std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity);
194 // Collect parameters for each type of entity
195 switch (theEntity->type()) {
197 std::shared_ptr<PlaneGCSSolver_PointWrapper> aPoint =
198 std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theEntity);
199 aParameters.push_back(aPoint->point()->x);
200 aParameters.push_back(aPoint->point()->y);
204 std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(anEntity->entity());
205 aParameters.push_back(aLine->p1.x);
206 aParameters.push_back(aLine->p1.y);
207 aParameters.push_back(aLine->p2.x);
208 aParameters.push_back(aLine->p2.y);
211 case ENTITY_CIRCLE: {
212 std::shared_ptr<GCS::Circle> aCircle =
213 std::dynamic_pointer_cast<GCS::Circle>(anEntity->entity());
214 aParameters.push_back(aCircle->center.x);
215 aParameters.push_back(aCircle->center.y);
216 aParameters.push_back(aCircle->rad);
220 std::shared_ptr<GCS::Arc> anArc = std::dynamic_pointer_cast<GCS::Arc>(anEntity->entity());
221 aParameters.push_back(anArc->center.x);
222 aParameters.push_back(anArc->center.y);
223 aParameters.push_back(anArc->rad);
224 aParameters.push_back(anArc->startAngle);
225 aParameters.push_back(anArc->endAngle);
235 bool isEqual(const GCS::Point& thePoint1, const GCS::Point& thePoint2)
237 return fabs((*thePoint1.x) - (*thePoint2.x)) <= tolerance &&
238 fabs((*thePoint1.y) - (*thePoint2.y)) <= tolerance;
241 bool isEqual(const EntityWrapperPtr& theEntity1, const EntityWrapperPtr& theEntity2)
243 GCS::VEC_pD aParamList1 = toParameters(theEntity1);
244 GCS::VEC_pD aParamList2 = toParameters(theEntity2);
246 GCS::VEC_pD::const_iterator anIt1 = aParamList1.begin();
247 GCS::VEC_pD::const_iterator anIt2 = aParamList2.begin();
248 for (; anIt1 != aParamList1.end() && anIt2 != aParamList2.end(); ++anIt1, ++anIt2)
249 if (fabs((**anIt1) - (**anIt2)) > tolerance)
252 return anIt1 == aParamList1.end() && anIt2 == aParamList2.end();