Salome HOME
Merge branch 'Dev_1.1.0' of newgeom:newgeom into Dev_1.1.0
authorsbh <sergey.belash@opencascade.com>
Wed, 1 Apr 2015 10:13:23 +0000 (13:13 +0300)
committersbh <sergey.belash@opencascade.com>
Wed, 1 Apr 2015 10:13:23 +0000 (13:13 +0300)
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/Model/Model_Session.cpp
src/SketchSolver/SketchSolver_ConstraintGroup.cpp
src/SketchSolver/SketchSolver_ConstraintManager.cpp

index c2da1a4799feb204aad3cc3a15cf99127ad447a9..ee8cebc14c9d0274a1dd486a1638fca540450c17 100644 (file)
@@ -84,10 +84,15 @@ static TCollection_ExtendedString DocFileName(const char* theFileName, const std
   return aPath;
 }
 
+bool Model_Document::isRoot() const
+{
+  return this == Model_Session::get()->moduleDocument().get();
+}
+
 bool Model_Document::load(const char* theFileName)
 {
   Handle(Model_Application) anApp = Model_Application::getApplication();
-  if (this == Model_Session::get()->moduleDocument().get()) {
+  if (isRoot()) {
     anApp->setLoadPath(theFileName);
   }
   TCollection_ExtendedString aPath(DocFileName(theFileName, myID));
@@ -161,7 +166,7 @@ bool Model_Document::load(const char* theFileName)
       std::dynamic_pointer_cast<Model_Session>(Model_Session::get());
     aSession->setActiveDocument(anApp->getDocument(myID), false);
     aSession->setCheckTransactions(false);
-    synchronizeFeatures(false, true);
+    synchronizeFeatures(false, true, true);
     aSession->setCheckTransactions(true);
     aSession->setActiveDocument(Model_Session::get()->moduleDocument(), false);
     aSession->setActiveDocument(anApp->getDocument(myID), true);
@@ -173,7 +178,7 @@ bool Model_Document::save(const char* theFileName, std::list<std::string>& theRe
 {
   // create a directory in the root document if it is not yet exist
   Handle(Model_Application) anApp = Model_Application::getApplication();
-  if (this == Model_Session::get()->moduleDocument().get()) {
+  if (isRoot()) {
 #ifdef WIN32
     CreateDirectory(theFileName, NULL);
 #else
@@ -241,9 +246,9 @@ bool Model_Document::save(const char* theFileName, std::list<std::string>& theRe
 void Model_Document::close(const bool theForever)
 {
   std::shared_ptr<ModelAPI_Session> aPM = Model_Session::get();
-  if (this != aPM->moduleDocument().get() && this == aPM->activeDocument().get()) {
+  if (!isRoot() && this == aPM->activeDocument().get()) {
     aPM->setActiveDocument(aPM->moduleDocument());
-  } else if (this == aPM->moduleDocument().get()) {
+  } else if (isRoot()) {
     // erase the active document if root is closed
     aPM->setActiveDocument(DocumentPtr());
   }
@@ -341,7 +346,7 @@ bool Model_Document::finishOperation()
   // this must be here just after everything is finished but before real transaction stop
   // to avoid messages about modifications outside of the transaction
   // and to rebuild everything after all updates and creates
-  if (Model_Session::get()->moduleDocument().get() == this) { // once for root document
+  if (isRoot()) { // once for root document
     Events_Loop::loop()->autoFlush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
     static std::shared_ptr<Events_Message> aFinishMsg
       (new Events_Message(Events_Loop::eventByName("FinishOperation")));
@@ -371,7 +376,7 @@ bool Model_Document::finishOperation()
   if (!aResult && !myTransactions.empty() /* it can be for just created part document */)
     aResult = myTransactions.rbegin()->myOCAFNum != 0;
 
-  if (!aResult && Model_Session::get()->moduleDocument().get() == this) {
+  if (!aResult && isRoot()) {
     // nothing inside in all documents, so remove this transaction from the transactions list
     undoInternal(true, false);
     myDoc->ClearRedos();
@@ -398,7 +403,8 @@ void Model_Document::abortOperation()
       myDoc->Undo();
     myDoc->ClearRedos();
   }
-  synchronizeFeatures(true, false); // references were not changed since transaction start
+  // references were not changed since transaction start
+  synchronizeFeatures(true, false, isRoot());
   // abort for all subs
   const std::set<std::string> aSubs = subDocuments(true);
   std::set<std::string>::iterator aSubIter = aSubs.begin();
@@ -446,8 +452,6 @@ void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchron
   for(int a = 0; a < aNumTransactions; a++)
     myDoc->Undo();
 
-  if (theSynchronize)
-    synchronizeFeatures(true, true);
   if (theWithSubs) {
     // undo for all subs
     const std::set<std::string> aSubs = subDocuments(true);
@@ -455,6 +459,9 @@ void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchron
     for (; aSubIter != aSubs.end(); aSubIter++)
       subDoc(*aSubIter)->undoInternal(theWithSubs, theSynchronize);
   }
+  // after redo of all sub-documents to avoid updates on not-modified data (issue 370)
+  if (theSynchronize)
+    synchronizeFeatures(true, true, isRoot());
 }
 
 void Model_Document::undo()
@@ -485,12 +492,14 @@ void Model_Document::redo()
   for(int a = 0; a < aNumRedos; a++)
     myDoc->Redo();
 
-  synchronizeFeatures(true, true);
   // redo for all subs
   const std::set<std::string> aSubs = subDocuments(true);
   std::set<std::string>::iterator aSubIter = aSubs.begin();
   for (; aSubIter != aSubs.end(); aSubIter++)
     subDoc(*aSubIter)->redo();
+
+  // after redo of all sub-documents to avoid updates on not-modified data (issue 370)
+  synchronizeFeatures(true, true, isRoot());
 }
 
 std::list<std::string> Model_Document::undoList() const
@@ -949,7 +958,8 @@ void Model_Document::initData(ObjectPtr theObj, TDF_Label theLab, const int theT
   theObj->initAttributes();
 }
 
-void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences)
+void Model_Document::synchronizeFeatures(
+  const bool theMarkUpdated, const bool theUpdateReferences, const bool theFlush)
 {
   std::shared_ptr<ModelAPI_Document> aThis = 
     Model_Application::getApplication()->getDocument(myID);
@@ -1040,11 +1050,13 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t
   myExecuteFeatures = false;
   aLoop->activateFlushes(true);
 
-  aLoop->flush(aCreateEvent);
-  aLoop->flush(aDeleteEvent);
-  aLoop->flush(anUpdateEvent);
-  aLoop->flush(aRedispEvent);
-  aLoop->flush(aToHideEvent);
+  if (theFlush) {
+    aLoop->flush(aCreateEvent);
+    aLoop->flush(aDeleteEvent);
+    aLoop->flush(anUpdateEvent);
+    aLoop->flush(aRedispEvent);
+    aLoop->flush(aToHideEvent);
+  }
   myExecuteFeatures = true;
 }
 
index ef7c98a109f9f3d3113cce26cbd4cf2c6342af18..59631304e0ee4bf0bc51293e51d4212f5fedcca5 100644 (file)
@@ -170,7 +170,9 @@ class Model_Document : public ModelAPI_Document
   //! Synchronizes myFeatures list with the updated document
   //! \param theMarkUpdated causes the "update" event for all features
   //! \param theUpdateReferences causes the update of back-references
-  void synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences);
+  //! \param theFlush makes flush all events in the end of all modifications of this method
+  void synchronizeFeatures(const bool theMarkUpdated, const bool theUpdateReferences,
+    const bool theFlush);
   //! Synchronizes the BackReferences list in Data of Features and Results
   void synchronizeBackRefs();
 
@@ -219,6 +221,9 @@ class Model_Document : public ModelAPI_Document
   /// Internally makes document know that feature was removed or added in history after creation
   MODEL_EXPORT virtual void addToHistory(const std::shared_ptr<ModelAPI_Object> theObject);
 
+  /// Returns true if the document is root module document
+  bool isRoot() const;
+
   friend class Model_Application;
   friend class Model_Session;
   friend class Model_Update;
index e7f21bf88a8470860d5c3bfba731f94b743dc564..8dcd0a11b0e04e008fc17b0d4f906fb9058be13e 100644 (file)
@@ -216,7 +216,7 @@ void Model_Session::setActiveDocument(
       if (aDoc.get()) {
         bool aWasChecked = myCheckTransactions;
         setCheckTransactions(false);
-        aDoc->synchronizeFeatures(false, true);
+        aDoc->synchronizeFeatures(false, true, true);
         if (aWasChecked)
             setCheckTransactions(true);
       }
@@ -266,7 +266,7 @@ std::shared_ptr<ModelAPI_Document> Model_Session::copy(
   aRT->SetRelocation(aSourceRoot, aTargetRoot);
   TDF_CopyTool::Copy(aDS, aRT);
 
-  aNew->synchronizeFeatures(false, true);
+  aNew->synchronizeFeatures(false, true, true);
   return aNew;
 }
 
index a3f083faf190c5ea113a901543db95c8b48b7ac4..f54067afa647d3c20c62e7a9d85a5bff5a328ade 100644 (file)
@@ -745,6 +745,7 @@ bool SketchSolver_ConstraintGroup::changeMirrorConstraint(
           Slvs_hParam v = changeParameter(y, aParamIter);
           Slvs_Entity aPoint = Slvs_MakePoint2d(++myEntityMaxID, myID, myWorkplane.h, u, v);
           myEntities.push_back(aPoint);
+          myEntOfConstr.push_back(true);
           aBothMiddlePoints[i] = aPoint.h;
           // additional constraint point-on-curve
           Slvs_Constraint aPonCircConstr = Slvs_MakeConstraint(
@@ -752,6 +753,7 @@ bool SketchSolver_ConstraintGroup::changeMirrorConstraint(
               aPoint.h, SLVS_E_UNKNOWN, aBothArcs[i], SLVS_E_UNKNOWN);
           myConstraints.push_back(aPonCircConstr);
           myConstraintMap[theConstraint].push_back(aPonCircConstr.h);
+          aNewConstraints.push_back(aPonCircConstr.h);
         }
 
         aBaseArcPoints[2] = aBothMiddlePoints[0];
@@ -809,13 +811,48 @@ bool SketchSolver_ConstraintGroup::changeMirrorConstraint(
           std::dynamic_pointer_cast<ModelAPI_Feature>(*aBaseIter);
       if (!aBaseFeature) continue;
       std::list<AttributePtr> aPoints = aBaseFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
-      std::list<AttributePtr>::iterator anIt = aPoints.begin();
-      for ( ; anIt != aPoints.end(); anIt++) {
+      if (aBaseFeature->getKind() != SketchPlugin_Arc::ID()) {
+        std::list<AttributePtr>::iterator anIt = aPoints.begin();
+        for ( ; anIt != aPoints.end(); anIt++) {
+          addTemporaryConstraintWhereDragged(*anIt);
+        }
+      } else {
         // Arcs are fixed by center and start points only (to avoid solving errors in SolveSpace)
-        if (aBaseFeature->getKind() == SketchPlugin_Arc::ID() &&
-            (*anIt)->id() == SketchPlugin_Arc::END_ID())
-          continue;
-        addTemporaryConstraintWhereDragged(*anIt);
+        AttributePtr aCenterAttr = aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID());
+        std::map<AttributePtr, Slvs_hEntity>::iterator aFound = myEntityAttrMap.find(aCenterAttr);
+        Slvs_hEntity anArcPoints[3] = {aFound->second, 0, 0};
+        AttributePtr aStartAttr = aBaseFeature->attribute(SketchPlugin_Arc::START_ID());
+        aFound = myEntityAttrMap.find(aStartAttr);
+        anArcPoints[1] = aFound->second;
+        AttributePtr aEndAttr = aBaseFeature->attribute(SketchPlugin_Arc::END_ID());
+        aFound = myEntityAttrMap.find(aEndAttr);
+        anArcPoints[2] = aFound->second;
+
+        bool isFixed[3] = {false, false, false};
+        int aNbFixed = 0; // number of already fixed points on the arc
+        for (int i = 0; i < 3; i++) {
+          std::vector<std::set<Slvs_hEntity> >::iterator aCoPtIter = myCoincidentPoints.begin();
+          for (; aCoPtIter != myCoincidentPoints.end() && !isFixed[i]; aCoPtIter++) {
+            if (aCoPtIter->find(anArcPoints[i]) == aCoPtIter->end())
+              continue;  // the entity was not found in current set
+
+            // Find one of already created SLVS_C_WHERE_DRAGGED constraints in current set of coincident points
+            std::vector<Slvs_Constraint>::iterator aConstrIter = myConstraints.begin();
+            for (; aConstrIter != myConstraints.end(); aConstrIter++)
+              if (aConstrIter->type == SLVS_C_WHERE_DRAGGED && 
+                  aCoPtIter->find(aConstrIter->ptA) != aCoPtIter->end()) {
+                isFixed[i] = true;
+                aNbFixed++;
+                break;  // the SLVS_C_WHERE_DRAGGED constraint already exists
+              }
+          }
+        }
+        if (aNbFixed < 2) { // append constraints
+          if (!isFixed[0])
+            addTemporaryConstraintWhereDragged(aCenterAttr);
+          if (!isFixed[1] && (isFixed[0] || aNbFixed == 0))
+            addTemporaryConstraintWhereDragged(aStartAttr);
+        }
       }
     }
   }
@@ -2143,9 +2180,16 @@ void SketchSolver_ConstraintGroup::makeMirrorEntity(const Slvs_hEntity& theBase,
   Slvs_Entity aBase = myEntities[Search(theBase, myEntities)];
   Slvs_Entity aMirror = myEntities[Search(theMirror, myEntities)];
   int i = 0;
-  while (aBase.point[i] != 0 && aMirror.point[i] != 0) {
-    makeMirrorEntity(aBase.point[i], aMirror.point[i], theMirrorLine);
-    i++;
+  if (aBase.type != SLVS_E_ARC_OF_CIRCLE) {
+    while (aBase.point[i] != 0 && aMirror.point[i] != 0) {
+      makeMirrorEntity(aBase.point[i], aMirror.point[i], theMirrorLine);
+      i++;
+    }
+  } else {
+    // swap mirroring first and last points of an arc
+    makeMirrorEntity(aBase.point[0], aMirror.point[0], theMirrorLine);
+    makeMirrorEntity(aBase.point[1], aMirror.point[2], theMirrorLine);
+    makeMirrorEntity(aBase.point[2], aMirror.point[1], theMirrorLine);
   }
   if (aBase.param[0] != 0 && aMirror.param[0] != 0) { // this is a point, copy it
     Slvs_Entity aMirrorLine = myEntities[Search(theMirrorLine, myEntities)];
index 1fafcf506b8e03cc5c2f5068d7e7f9febda211d1..bd346fb35fe35fac2343b7ff27b2600dae9c9544 100644 (file)
@@ -117,7 +117,7 @@ void SketchSolver_ConstraintManager::processEvent(
       for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) {
         std::shared_ptr<SketchPlugin_Feature> aFeature = 
           std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
-        if (!aFeature || aFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID())
+        if (!aFeature /*|| aFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()*/)
           continue;
         changeConstraintOrEntity(aFeature);
       }