* Complete searching the non-constrained entities.
* Create unit test.
//
/* Events.i */
-%module EventsAPI
+%module(directors="1") EventsAPI
+%feature("director:except") {
+ if ($error != NULL) {
+ PyErr_Print();
+ std::cerr << std::endl;
+ throw Swig::DirectorMethodException();
+ }
+}
+
%{
#include "Events.h"
#include "Events_InfoMessage.h"
+ #include "Events_Listener.h"
+ #include "Events_Loop.h"
#include "Events_Message.h"
+ #include "Events_MessageGroup.h"
%}
%include "typemaps.i"
%include "std_string.i"
+// directors
+%feature("director") Events_Listener;
+
// all supported interfaces
%include "Events_Message.h"
%include "Events_InfoMessage.h"
+%include "Events_Listener.h"
+%include "Events_Loop.h"
+%include "Events_MessageGroup.h"
/// map from event ID to groupped messages (for flush for groupMessages=true listeners)
std::map<char*, std::shared_ptr<Events_Message> > myGroups;
- public:
+public:
+ virtual ~Events_Listener() {}
+
//! This method is called by loop when the event is started to process.
EVENTS_EXPORT virtual void processEvent(const std::shared_ptr<Events_Message>& theMessage) = 0;
INCLUDE_DIRECTORIES(
../GeomAPI # only for SWIG
+ ../Events # only for SWIG
../ModelAPI
)
#include <GeomAPI_swig.h>
#include <ModelAPI_swig.h>
+ #include <Events_MessageGroup.h>
#include "GeomDataAPI.h"
#include "GeomDataAPI_Point.h"
Config
GeomAPI
)
-SET(CMAKE_SWIG_FLAGS -threads -w325,321,362,383,302,403,473)
+SET(CMAKE_SWIG_FLAGS -threads -w325,321,362,383,302,403,451,473)
ADD_DEFINITIONS(-DMODELAPI_EXPORTS)
ADD_LIBRARY(ModelAPI SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
// import other modules
%import "GeomAPI.i"
+%import "Events.i"
// to avoid error on this
#define MODELAPI_EXPORT
%shared_ptr(ModelAPI_ResultField)
%shared_ptr(ModelAPI_ResultParameter)
%shared_ptr(ModelAPI_ResultCompSolid)
+%shared_ptr(ModelAPI_ObjectUpdatedMessage)
%typecheck(SWIG_TYPECHECK_POINTER) const ModelAPI_AttributeTables::Value {
$1 = (PyFloat_Check($input) || PyLong_Check($input) || PyUnicode_Check($input) || PyBool_Check($input)) ? 1 : 0;
// all supported interfaces
%include "ModelAPI_Entity.h"
+%include "ModelAPI_Events.h"
%include "ModelAPI_Document.h"
%include "ModelAPI_Session.h"
%include "ModelAPI_Plugin.h"
// std::set -> []
%template(AttributeSet) std::set<std::shared_ptr<ModelAPI_Attribute> >;
%template(FeatureSet) std::set<std::shared_ptr<ModelAPI_Feature> >;
+%template(ObjectSet) std::set<std::shared_ptr<ModelAPI_Object> >;
// std::dynamic_pointer_cast
template<class T1, class T2> std::shared_ptr<T1> shared_ptr_cast(std::shared_ptr<T2> theObject);
%template(modelAPI_ResultGroup) shared_ptr_cast<ModelAPI_ResultGroup, ModelAPI_Result>;
%template(modelAPI_ResultField) shared_ptr_cast<ModelAPI_ResultField, ModelAPI_Result>;
+%template(messageToUpdatedMessage) shared_ptr_cast<ModelAPI_ObjectUpdatedMessage, Events_Message>;
+
// Attribute casts
%template(modelAPI_AttributeDocRef) shared_ptr_cast<ModelAPI_AttributeDocRef, ModelAPI_Attribute>;
%template(modelAPI_AttributeDouble) shared_ptr_cast<ModelAPI_AttributeDouble, ModelAPI_Attribute>;
#include "ModelAPI.h"
#include "ModelAPI_Entity.h"
+ #include "ModelAPI_Events.h"
#include "ModelAPI_Document.h"
#include "ModelAPI_Session.h"
#include "ModelAPI_Object.h"
CompositeFeaturePtr aCompFeature = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
if (aCompFeature.get()) {
static const Events_ID anEvent = Events_Loop::eventByName(EVENT_GET_DOF_OBJECTS);
- ModelAPI_EventCreator::get()->sendUpdated(aCompFeature->subFeature(0), anEvent);
+ ModelAPI_EventCreator::get()->sendUpdated(aCompFeature, anEvent);
Events_Loop::loop()->flush(anEvent);
}
}
TestProjectionIntoResult.py
TestProjectionUpdate.py
TestRectangle.py
+ TestRemainingDoF.py
TestRemoveEllipse.py
TestRemoveEllipticArc.py
TestRemoveSketch.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) == 1)
+ assert(objectToFeature(objs[0]).getKind() == "SketchCircle")
+ self.myEventProcessed = True
+
+
+if __name__ == "__main__":
+ # create the listener
+ listener = FreeShapesListener()
+
+ model.begin()
+ partSet = model.moduleDocument()
+ Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+ SketchCircle_1 = Sketch_1.addCircle(-30, 0, 14)
+ SketchLine_1 = Sketch_1.addLine(-30, 0, 0, 0)
+ SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_1.startPoint())
+ SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "Origin"), False)
+ SketchPoint_1 = SketchProjection_1.createdFeature()
+ SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result())
+ SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+ SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30)
+ 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)
GCSConstraintPtr aConstraint = *anIt;
aConstraint->setTag(anID);
myEquationSystem->addConstraint(aConstraint.get());
- myConstraints[theMultiConstraintID].insert(aConstraint);
if (anID > CID_UNKNOWN)
++anID;
}
+ myConstraints[theMultiConstraintID] = theConstraints;
if (theMultiConstraintID >= CID_UNKNOWN)
myDOF = -1;
{
ConstraintMap::iterator aFound = myConstraints.find(theID);
if (aFound != myConstraints.end()) {
- for (std::set<GCSConstraintPtr>::iterator anIt = aFound->second.begin();
+ for (std::list<GCSConstraintPtr>::iterator anIt = aFound->second.begin();
anIt != aFound->second.end(); ++anIt)
myEquationSystem->clearByTag((*anIt)->getTag());
myDiagnoseBeforeSolve = false;
}
-void PlaneGCSSolver_Solver::getFreeParameters(GCS::VEC_pD& theFreeParams) const
+void PlaneGCSSolver_Solver::getFreeParameters(GCS::VEC_pD& theFreeParams)
{
if (myConstraints.empty())
theFreeParams = myParameters;
- else
+ else {
+ GCS::VEC_pD aParametersCopy = myParameters;
+ ConstraintMap aConstraintCopy = myConstraints;
+
+ // clear the set of equations
+ clear();
+ // reset constraints
+ myParameters = aParametersCopy;
+ for (ConstraintMap::iterator anIt = aConstraintCopy.begin();
+ anIt != aConstraintCopy.end(); ++anIt)
+ addConstraint(anIt->first, anIt->second);
+
+ // parameters detection works for Dense QR only
+ GCS::QRAlgorithm aQRAlgo = myEquationSystem->qrAlgorithm;
+ myEquationSystem->qrAlgorithm = GCS::EigenDenseQR;
+ diagnose();
myEquationSystem->getDependentParams(theFreeParams);
+ // revert QR decomposition algorithm
+ myEquationSystem->qrAlgorithm = aQRAlgo;
+ }
}
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) const;
+ void getFreeParameters(GCS::VEC_pD& theFreeParams);
/// \brief Degrees of freedom
int dof();
void removeFictiveConstraint();
private:
- typedef std::map<ConstraintID, std::set<GCSConstraintPtr> > ConstraintMap;
+ typedef std::map<ConstraintID, std::list<GCSConstraintPtr> > ConstraintMap;
GCS::VEC_pD myParameters; ///< list of unknowns
ConstraintMap myConstraints; ///< list of constraints
if (aObjects.size() == 1) {
std::set<ObjectPtr>::const_iterator aIt;
for (aIt = aObjects.cbegin(); aIt != aObjects.cend(); aIt++) {
- std::shared_ptr<SketchPlugin_Feature> aFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(*aIt);
+ CompositeFeaturePtr aFeature =
+ std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(*aIt);
if (aFeature) {
SketchGroupPtr aGroup = findGroup(aFeature);
aFeatures.push_back(*aIt);
}
- // TODO: send features to GUI
+ // send features to GUI
static const Events_ID anEvent = Events_Loop::eventByName(EVENT_DOF_OBJECTS);
ModelAPI_EventCreator::get()->sendUpdated(aFeatures, anEvent);
Events_Loop::loop()->flush(anEvent);
// Purpose: search groups of entities interacting with given feature
// ============================================================================
SketchGroupPtr SketchSolver_Manager::findGroup(
- std::shared_ptr<SketchPlugin_Feature> theFeature)
+ std::shared_ptr<SketchPlugin_Feature> theFeature)
{
if (!isFeatureValid(theFeature))
return SketchGroupPtr(); // do not process wrong features
break;
}
}
+ return findGroup(aSketch);
+}
- if (!aSketch)
+SketchGroupPtr SketchSolver_Manager::findGroup(CompositeFeaturePtr theSketch)
+{
+ if (!theSketch)
return SketchGroupPtr(); // not a sketch's feature
std::list<SketchGroupPtr>::const_iterator aGroupIt;
for (aGroupIt = myGroups.begin(); aGroupIt != myGroups.end(); ++aGroupIt)
- if ((*aGroupIt)->getWorkplane() == aSketch)
+ if ((*aGroupIt)->getWorkplane() == theSketch)
return *aGroupIt;
// group for the sketch does not created yet
- SketchGroupPtr aNewGroup = SketchGroupPtr(new SketchSolver_Group(aSketch));
+ SketchGroupPtr aNewGroup = SketchGroupPtr(new SketchSolver_Group(theSketch));
myGroups.push_back(aNewGroup);
return aNewGroup;
}
* \return Pointer to corresponding group or NULL if the group cannot be created.
*/
SketchGroupPtr findGroup(std::shared_ptr<SketchPlugin_Feature> theFeature);
+ /** \brief Searches group related to specified composite feature
+ * \param[in] theSketch sketch to be found
+ * \return Pointer to corresponding group or NULL if the group cannot be created.
+ */
+ SketchGroupPtr findGroup(std::shared_ptr<ModelAPI_CompositeFeature> theSketch);
/// \brief Stop sending the Update event until all features updated
/// \return \c true, if the last flushed event is Update