Find all parameters coincident to the returned by PlaneGCS.
Test2860.py
Test2894.py
Test3019.py
+ Test3087_1.py
+ Test3087_2.py
TestArcBehavior.py
TestChangeSketchPlane1.py
TestChangeSketchPlane2.py
--- /dev/null
+# Copyright (C) 2019 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+
+from EventsAPI import *
+from ModelAPI import *
+
+class FreeShapesListener(EventsAPI.Events_Listener):
+ def __init__(self):
+ Events_Listener.__init__(self)
+ # register as a listener
+ Events_Loop.loop().registerListener(self, Events_Loop.eventByName("DoFObjects"))
+ self.myEventProcessed = False
+
+ def __del__(self):
+ Events_Loop.loop().removeListener(self)
+
+ def processEvent(self, theMessage):
+ message = messageToUpdatedMessage(theMessage)
+ objs = message.objects()
+ assert(len(objs) == 3)
+ self.myEventProcessed = True
+
+
+if __name__ == "__main__":
+ # create the listener
+ listener = FreeShapesListener()
+
+ model.begin()
+ partSet = model.moduleDocument()
+ Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+ SketchLine_1 = Sketch_1.addLine(10, 10, -10, 10)
+ SketchLine_2 = Sketch_1.addLine(-10, 10, -10, -10)
+ SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+ SketchLine_3 = Sketch_1.addLine(-10, -10, 10, -10)
+ SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+ SketchConstraintRigid_1 = Sketch_1.setFixed(SketchLine_1.startPoint())
+ SketchConstraintRigid_2 = Sketch_1.setFixed(SketchLine_3.endPoint())
+ model.end()
+
+ # send message to find the free shapes in the sketch
+ event = Events_Loop.eventByName("GetDoFObjects")
+ ModelAPI_EventCreator.get().sendUpdated(Sketch_1.feature(), event);
+ Events_Loop.loop().flush(event);
+
+ assert(listener.myEventProcessed)
--- /dev/null
+# Copyright (C) 2019 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+from salome.shaper import model
+
+from EventsAPI import *
+from ModelAPI import *
+
+class FreeShapesListener(EventsAPI.Events_Listener):
+ def __init__(self):
+ Events_Listener.__init__(self)
+ # register as a listener
+ Events_Loop.loop().registerListener(self, Events_Loop.eventByName("DoFObjects"))
+ self.myEventProcessed = False
+
+ def __del__(self):
+ Events_Loop.loop().removeListener(self)
+
+ def processEvent(self, theMessage):
+ message = messageToUpdatedMessage(theMessage)
+ objs = message.objects()
+ assert(len(objs) == 4)
+ self.myEventProcessed = True
+
+
+if __name__ == "__main__":
+ # create the listener
+ listener = FreeShapesListener()
+
+ model.begin()
+ partSet = model.moduleDocument()
+ Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+ SketchLine_1 = Sketch_1.addLine(10, 10, -10, 10)
+ SketchLine_2 = Sketch_1.addLine(-10, 10, -10, -10)
+ SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+ SketchLine_3 = Sketch_1.addLine(-10, -10, 10, -10)
+ SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+ SketchConstraintRigid_1 = Sketch_1.setFixed(SketchLine_1.startPoint())
+ SketchConstraintRigid_2 = Sketch_1.setFixed(SketchLine_3.endPoint())
+ SketchCircle_1 = Sketch_1.addCircle(-10, 10, 10)
+ SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchCircle_1.center())
+ SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 10)
+ model.end()
+
+ # send message to find the free shapes in the sketch
+ event = Events_Loop.eventByName("GetDoFObjects")
+ ModelAPI_EventCreator.get().sendUpdated(Sketch_1.feature(), event);
+ Events_Loop.loop().flush(event);
+
+ assert(listener.myEventProcessed)
myDiagnoseBeforeSolve = false;
}
-void PlaneGCSSolver_Solver::getFreeParameters(GCS::VEC_pD& theFreeParams)
+void PlaneGCSSolver_Solver::getFreeParameters(GCS::SET_pD& theFreeParams)
{
if (myConstraints.empty())
- theFreeParams = myParameters;
+ theFreeParams.insert(myParameters.begin(), myParameters.end());
else {
GCS::VEC_pD aParametersCopy = myParameters;
ConstraintMap aConstraintCopy = myConstraints;
GCS::QRAlgorithm aQRAlgo = myEquationSystem->qrAlgorithm;
myEquationSystem->qrAlgorithm = GCS::EigenDenseQR;
diagnose();
- myEquationSystem->getDependentParams(theFreeParams);
+ GCS::VEC_pD aFreeParams;
+ myEquationSystem->getDependentParams(aFreeParams);
+ theFreeParams.insert(aFreeParams.begin(), aFreeParams.end());
// revert QR decomposition algorithm
myEquationSystem->qrAlgorithm = aQRAlgo;
}
+
+ if (theFreeParams.empty())
+ return;
+
+ // find all equal parameters too
+ struct EqualParameters
+ {
+ typedef std::map<double*, std::list<GCS::SET_pD>::iterator> MapParamGroup;
+
+ std::list<GCS::SET_pD> myEqualParams;
+ MapParamGroup myGroups;
+
+ void add(double* theParam1, double* theParam2)
+ {
+ MapParamGroup::iterator aFound1 = myGroups.find(theParam1);
+ MapParamGroup::iterator aFound2 = myGroups.find(theParam2);
+
+ if (aFound1 == myGroups.end()) {
+ if (aFound2 == myGroups.end()) {
+ // create new group
+ myEqualParams.push_back(GCS::SET_pD());
+ std::list<GCS::SET_pD>::iterator aGroup = --myEqualParams.end();
+ aGroup->insert(theParam1);
+ aGroup->insert(theParam2);
+ myGroups[theParam1] = aGroup;
+ myGroups[theParam2] = aGroup;
+ }
+ else {
+ // add first parameter to the second group
+ aFound2->second->insert(theParam1);
+ myGroups[theParam1] = aFound2->second;
+ }
+ }
+ else {
+ if (aFound2 == myGroups.end()) {
+ // add second parameter to the first group
+ aFound1->second->insert(theParam2);
+ myGroups[theParam2] = aFound1->second;
+ }
+ else if (aFound1 != aFound2) {
+ // merge two groups
+ GCS::SET_pD aCopy = *(aFound2->second);
+ myEqualParams.erase(aFound2->second);
+ for (GCS::SET_pD::iterator anIt = aCopy.begin(); anIt != aCopy.end(); ++anIt)
+ myGroups[*anIt] = aFound1->second;
+ aFound1->second->insert(aCopy.begin(), aCopy.end());
+ }
+ }
+ }
+ } anEqualParams;
+
+ for (ConstraintMap::iterator anIt = myConstraints.begin(); anIt != myConstraints.end(); ++anIt)
+ for (std::list<GCSConstraintPtr>::iterator aCIt = anIt->second.begin();
+ aCIt != anIt->second.end(); ++aCIt) {
+ if ((*aCIt)->getTypeId() == GCS::Equal)
+ anEqualParams.add((*aCIt)->params()[0], (*aCIt)->params()[1]);
+ }
+
+ GCS::SET_pD aFreeParamsCopy = theFreeParams;
+ for (GCS::SET_pD::iterator anIt = aFreeParamsCopy.begin();
+ anIt != aFreeParamsCopy.end(); ++anIt) {
+ EqualParameters::MapParamGroup::iterator aFound = anEqualParams.myGroups.find(*anIt);
+ if (aFound != anEqualParams.myGroups.end())
+ theFreeParams.insert(aFound->second->begin(), aFound->second->end());
+ }
}
void PlaneGCSSolver_Solver::addFictiveConstraintIfNecessary()
void diagnose(const GCS::Algorithm& theAlgo = GCS::DogLeg);
/// \brief Return the list of modifiable parameters
- void getFreeParameters(GCS::VEC_pD& theFreeParams);
+ void getFreeParameters(GCS::SET_pD& theFreeParams);
/// \brief Degrees of freedom
int dof();
void PlaneGCSSolver_Storage::getUnderconstrainedGeometry(std::set<ObjectPtr>& theFeatures) const
{
- std::vector<double*> aFreeParams;
+ std::set<double*> aFreeParams;
mySketchSolver->getFreeParameters(aFreeParams);
if (aFreeParams.empty())
return;
- std::map<double*, FeaturePtr> aParamOfFeatures;
for (std::map<FeaturePtr, EntityWrapperPtr>::const_iterator aFIt = myFeatureMap.begin();
aFIt != myFeatureMap.end(); ++aFIt) {
if (!aFIt->second)
continue;
GCS::SET_pD aParams = PlaneGCSSolver_Tools::parameters(aFIt->second);
for (GCS::SET_pD::iterator aPIt = aParams.begin(); aPIt != aParams.end(); ++aPIt)
- aParamOfFeatures[*aPIt] = aFIt->first;
- }
-
- for (std::vector<double*>::iterator anIt = aFreeParams.begin();
- anIt != aFreeParams.end(); ++anIt) {
- std::map<double*, FeaturePtr>::iterator aFound = aParamOfFeatures.find(*anIt);
- if (aFound != aParamOfFeatures.end())
- theFeatures.insert(aFound->second);
+ if (aFreeParams.find(*aPIt) != aFreeParams.end()) {
+ theFeatures.insert(aFIt->first);
+ break;
+ }
}
}