if (aStart.IsEqual(anEnd, Precision::Confusion()))
return boost::shared_ptr<GeomAPI_Shape>();
+ if (Abs(aStart.SquareDistance(anEnd)) > 1.e+100)
+ return boost::shared_ptr<GeomAPI_Shape>();
BRepBuilderAPI_MakeEdge anEdgeBuilder(aStart, anEnd);
boost::shared_ptr<GeomAPI_Shape> aRes(new GeomAPI_Shape);
TopoDS_Edge anEdge = anEdgeBuilder.Edge();
void Model_Data::setName(string theName)
{
- TDataStd_Name::Set(myLab, theName.c_str());
- static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
- Model_FeatureUpdatedMessage aMsg(myFeature, anEvent);
- Events_Loop::loop()->send(aMsg, false);
+ bool isModified = false;
+ Handle(TDataStd_Name) aName;
+ if (!myLab.FindAttribute(TDataStd_Name::GetID(), aName)) {
+ TDataStd_Name::Set(myLab, theName.c_str());
+ isModified = true;
+ } else {
+ isModified = !aName->Get().IsEqual(theName.c_str());
+ if (isModified)
+ aName->Set(theName.c_str());
+ }
+ if (isModified) {
+ static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
+ Model_FeatureUpdatedMessage aMsg(myFeature, anEvent);
+ Events_Loop::loop()->send(aMsg, false);
+ }
}
void Model_Data::addAttribute(string theID, string theAttrType)
if (myNestedNum == 0)
myNestedNum = -1;
myDoc->AbortCommand();
- synchronizeFeatures();
+ synchronizeFeatures(true);
// abort for all subs
set<string>::iterator aSubIter = mySubs.begin();
for(; aSubIter != mySubs.end(); aSubIter++)
if (myNestedNum > 0) myNestedNum--;
if (!myIsEmptyTr[myTransactionsAfterSave])
myDoc->Undo();
- synchronizeFeatures();
+ synchronizeFeatures(true);
// undo for all subs
set<string>::iterator aSubIter = mySubs.begin();
for(; aSubIter != mySubs.end(); aSubIter++)
if (!myIsEmptyTr[myTransactionsAfterSave])
myDoc->Redo();
myTransactionsAfterSave++;
- synchronizeFeatures();
+ synchronizeFeatures(true);
// redo for all subs
set<string>::iterator aSubIter = mySubs.begin();
for(; aSubIter != mySubs.end(); aSubIter++)
return boost::shared_ptr<ModelAPI_Feature>(); // not found
}
-void Model_Document::synchronizeFeatures()
+void Model_Document::synchronizeFeatures(const bool theMarkUpdated)
{
boost::shared_ptr<ModelAPI_Document> aThis = Model_Application::getApplication()->getDocument(myID);
// update features
aDSTag = aFLabIter.Value()->Label().Tag();
}
if (aDSTag > aFeatureTag) { // feature is removed
- Model_FeatureDeletedMessage aMsg1(aThis, FEATURES_GROUP);
- Model_FeatureDeletedMessage aMsg2(aThis, (*aFIter)->getGroup());
+ FeaturePtr aFeature = *aFIter;
aFIter = myFeatures.erase(aFIter);
// event: model is updated
- Events_Loop::loop()->send(aMsg1);
+ if (aFeature->isInHistory()) {
+ Model_FeatureDeletedMessage aMsg1(aThis, FEATURES_GROUP);
+ Events_Loop::loop()->send(aMsg1);
+ }
+ Model_FeatureDeletedMessage aMsg2(aThis, aFeature->getGroup());
Events_Loop::loop()->send(aMsg2);
} else if (aDSTag < aFeatureTag) { // a new feature is inserted
// create a feature
// feature for this label is added, so go to the next label
aFLabIter.Next();
} else { // nothing is changed, both iterators are incremented
+ if (theMarkUpdated) {
+ static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_UPDATED);
+ Model_FeatureUpdatedMessage aMsg(*aFIter, anEvent);
+ Events_Loop::loop()->send(aMsg);
+ }
aFIter++;
aFLabIter.Next();
}
boost::static_pointer_cast<Model_PluginManager>(Model_PluginManager::get())->
setCheckTransactions(false);
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_FEATURE_CREATED));
+ if (theMarkUpdated)
+ Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_FEATURE_UPDATED));
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_FEATURE_DELETED));
boost::static_pointer_cast<Model_PluginManager>(Model_PluginManager::get())->
setCheckTransactions(true);
const boost::shared_ptr<ModelAPI_Feature> theFeature);
//! Synchronizes myFeatures list with the updated document
- void synchronizeFeatures();
+ void synchronizeFeatures(const bool theMarkUpdated = false);
//! Creates new document with binary file format
Model_Document(const std::string theID);
#include <Model.h>
#include <ModelAPI_Object.h>
+#include <ModelAPI_Document.h>
#include <TDataStd_Name.hxx>
MODEL_EXPORT virtual const std::string& getKind() {return myRef->getKind();}
/// Returns to which group in the document must be added feature
- MODEL_EXPORT virtual const std::string& getGroup() {return myRef->getGroup();}
+ MODEL_EXPORT virtual const std::string& getGroup() {return FEATURES_GROUP;}
/// Returns document this feature belongs to
MODEL_EXPORT virtual boost::shared_ptr<ModelAPI_Document> document()
#include <XGUI_ViewPort.h>
#include <XGUI_ActionsMgr.h>
#include <XGUI_ViewerProxy.h>
+#include <XGUI_ContextMenuMgr.h>
#include <Config_PointerMessage.h>
#include <Config_ModuleReader.h>
connect(anOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)),
this, SLOT(onOperationStopped(ModuleBase_Operation*)));
+ XGUI_ContextMenuMgr* aContextMenuMgr = myWorkshop->contextMenuMgr();
+ connect(aContextMenuMgr, SIGNAL(actionTriggered(const QString&, bool)),
+ this, SLOT(onContextMenuCommand(const QString&, bool)));
+
connect(myWorkshop->viewer(), SIGNAL(mousePress(QMouseEvent*)),
this, SLOT(onMousePressed(QMouseEvent*)));
connect(myWorkshop->viewer(), SIGNAL(mouseRelease(QMouseEvent*)),
std::list<XGUI_ViewerPrs> aHighlighted = aDisplayer->GetHighlighted(TopAbs_VERTEX);
aPreviewOp->init(theFeature, aSelected, aHighlighted);
}
- myWorkshop->actionsMgr()->updateCheckState();
sendOperation(anOperation);
+ myWorkshop->actionsMgr()->updateCheckState();
}
void PartSet_Module::onMultiSelectionEnabled(bool theEnabled)
void PartSet_Module::editFeature(FeaturePtr theFeature)
{
- /*if (!theFeature)
+ if (!theFeature)
return;
if (theFeature->getKind() == "Sketch") {
onLaunchOperation(theFeature->getKind(), theFeature);
- visualizePreview(theFeature, true);
- }*/
+ updateCurrentPreview(theFeature->getKind());
+ }
}
}
void PartSet_OperationSketch::init(boost::shared_ptr<ModelAPI_Feature> theFeature,
- const std::list<XGUI_ViewerPrs>& thePresentations)
+ const std::list<XGUI_ViewerPrs>& /*theSelected*/,
+ const std::list<XGUI_ViewerPrs>& /*theHighlighted*/)
{
setFeature(theFeature);
}
return hasSketchPlane();
}
+void PartSet_OperationSketch::startOperation()
+{
+ if (!feature())
+ setFeature(createFeature());
+}
+
bool PartSet_OperationSketch::hasSketchPlane() const
{
bool aHasPlane = false;
if (feature()) {
- // set plane parameters to feature
boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
-
boost::shared_ptr<ModelAPI_AttributeDouble> anAttr;
- // temporary solution for main planes only
boost::shared_ptr<GeomDataAPI_Dir> aNormal =
boost::dynamic_pointer_cast<GeomDataAPI_Dir>(aData->attribute(SKETCH_ATTR_NORM));
- double aX = aNormal->x(), anY = aNormal->y(), aZ = aNormal->z();
-
aHasPlane = aNormal && !(aNormal->x() == 0 && aNormal->y() == 0 && aNormal->z() == 0);
}
return aHasPlane;
virtual std::list<int> getSelectionModes(boost::shared_ptr<ModelAPI_Feature> theFeature) const;
/// Initializes some fields accorging to the feature
- /// \param theFeature the feature
- /// \param thePresentations the list of additional presentations
+ /// \param theSelected the list of selected presentations
+ /// \param theHighlighted the list of highlighted presentations
virtual void init(boost::shared_ptr<ModelAPI_Feature> theFeature,
- const std::list<XGUI_ViewerPrs>& thePresentations);
+ const std::list<XGUI_ViewerPrs>& theSelected,
+ const std::list<XGUI_ViewerPrs>& theHighlighted);
/// Returns the operation sketch feature
/// \returns the sketch instance
void planeSelected(double theX, double theY, double theZ);
protected:
+ /// Virtual method called when operation started (see start() method for more description)
+ /// Default impl calls corresponding slot and commits immediately.
+ virtual void startOperation();
+
/// Returns whether the sketch plane is set
/// \return the boolean value whether the sketch is set
bool hasSketchPlane() const;
<group id="Operations">
<feature id="Part" title="New part" tooltip="Creates a new part" icon=":pictures/part_ico.png"/>
<feature id="duplicate" title="Duplicate" tooltip="Duplicate selected object" icon=":icons/duplicate.png"/>
- <feature id="remove" title="Remove" tooltip="Remove selected object" icon=":icons/remove.png"/>
+ <feature id="remove" title="Remove part" tooltip="Remove active part" icon=":icons/remove.png"/>
</group>
</workbench>
</plugin>
const boost::shared_ptr<GeomAPI_Shape>& SketchPlugin_Sketch::preview()
{
- std::list<boost::shared_ptr<GeomAPI_Shape> > aFaces;
-
- addPlane(1, 0, 0, aFaces); // YZ plane
- addPlane(0, 1, 0, aFaces); // XZ plane
- addPlane(0, 0, 1, aFaces); // XY plane
- boost::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aFaces);
- setPreview(aCompound);
+ if (isPlaneSet()) {
+ setPreview(boost::shared_ptr<GeomAPI_Shape>());
+ }
+ else {
+ std::list<boost::shared_ptr<GeomAPI_Shape> > aFaces;
+ addPlane(1, 0, 0, aFaces); // YZ plane
+ addPlane(0, 1, 0, aFaces); // XZ plane
+ addPlane(0, 0, 1, aFaces); // XY plane
+ boost::shared_ptr<GeomAPI_Shape> aCompound = GeomAlgoAPI_CompoundBuilder::compound(aFaces);
+ setPreview(aCompound);
+ }
return getPreview();
}
return boost::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(aSum));
}
+
+bool SketchPlugin_Sketch::isPlaneSet()
+{
+ boost::shared_ptr<GeomDataAPI_Dir> aNormal =
+ boost::dynamic_pointer_cast<GeomDataAPI_Dir>(data()->attribute(SKETCH_ATTR_NORM));
+
+ return aNormal && !(aNormal->x() == 0 && aNormal->y() == 0 && aNormal->z() == 0);
+}
/// \param theShapes the list of result shapes
void addPlane(double theX, double theY, double theZ,
std::list<boost::shared_ptr<GeomAPI_Shape> >& theShapes) const;
+
+ /// Checks whether the plane is set in the sketch.
+ /// \returns the boolean state
+ bool isPlaneSet();
};
#endif
#include <ModelAPI_Feature.h>
#include <ModelAPI_Data.h>
#include <Model_Events.h>
+#include <ModelAPI_Object.h>
#include <Events_Loop.h>
if (aDoc == myDocument) { // If root objects
if (aFeature->getGroup().compare(PARTS_GROUP) == 0) { // Update only Parts group
// Add a new part
- int aStart = myPartModels.size() + 1;
+ int aStart = myPartModels.size();
XGUI_PartDataModel* aModel = new XGUI_PartDataModel(myDocument, this);
aModel->setPartId(myPartModels.count());
myPartModels.append(aModel);
int aStart = myPartModels.size() - 1;
removeSubModel(aStart);
removeRow(aStart, partFolderNode());
+ if (myActivePart && (!isPartSubModel(myActivePart))) {
+ myActivePart = 0;
+ myActivePartIndex = QModelIndex();
+ myModel->setItemsColor(ACTIVE_COLOR);
+ }
} else { // Update top groups (other except parts
QModelIndex aIndex = myModel->findGroup(aGroup);
int aStart = myModel->rowCount(aIndex);
if (myActivePart)
myActivePart->setItemsColor(PASSIVE_COLOR);
myActivePart = 0;
+ myActivePartIndex = QModelIndex();
myModel->setItemsColor(ACTIVE_COLOR);
}
QModelIndex XGUI_DocumentDataModel::partIndex(const FeaturePtr& theFeature) const
{
+ FeaturePtr aFeature = theFeature;
+ if (!aFeature->data()) {
+ ObjectPtr aObject = boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature);
+ aFeature = aObject->featureRef();
+ }
int aRow = -1;
XGUI_PartModel* aModel = 0;
foreach (XGUI_PartModel* aPartModel, myPartModels) {
aRow++;
- if (aPartModel->part() == theFeature) {
+ if (aPartModel->part() == aFeature) {
aModel = aPartModel;
break;
}
if (aEditor) {
QString aRes = aEditor->text();
FeaturePtr aFeature = mySelectedData.first();
- aFeature->document()->startOperation();
+ PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
+ aMgr->rootDocument()->startOperation();
if (aFeature->data())
aFeature->data()->setName(qPrintable(aRes));
else
boost::dynamic_pointer_cast<ModelAPI_Object>(aFeature)->setName(qPrintable(aRes));
- aFeature->document()->finishOperation();
+ aMgr->rootDocument()->finishOperation();
}
}
connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)), SLOT(onOperationStopped(ModuleBase_Operation*)));
connect(myMainWindow, SIGNAL(exitKeySequence()), SLOT(onExit()));
connect(myOperationMgr, SIGNAL(operationStarted()), myActionsMgr, SLOT(update()));
- connect(myOperationMgr, SIGNAL(operationStopped()), myActionsMgr, SLOT(update()));
+ connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)), myActionsMgr, SLOT(update()));
connect(this, SIGNAL(errorOccurred(const QString&)), myErrorDlg, SLOT(addError(const QString&)));
}
Events_ID aFeatureUpdatedId = aLoop->eventByName(EVENT_FEATURE_UPDATED);
aLoop->registerListener(this, aFeatureUpdatedId);
aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_CREATED));
- aLoop->registerListener(this, Events_Loop::eventByName(EVENT_FEATURE_DELETED));
activateModule();
if (myMainWindow) {
}
}
- // Process deletion of a part
- if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_FEATURE_DELETED)) {
- PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
- if (aMgr->currentDocument() == aMgr->rootDocument())
- activatePart(FeaturePtr()); // Activate PartSet
- }
-
//Update property panel on corresponding message. If there is no current operation (no
//property panel), or received message has different feature to the current - do nothing.
static Events_ID aFeatureUpdatedId = Events_Loop::loop()->eventByName(EVENT_FEATURE_UPDATED);
myPropertyPanel->setModelWidgets(aFactory.getModelWidgets());
myPropertyPanel->setWindowTitle(aOperation->getDescription()->description());
}
+ updateCommandStatus();
}
//******************************************************
objectBrowser()->treeView()->setCurrentIndex(QModelIndex());
PluginManagerPtr aMgr = ModelAPI_PluginManager::get();
DocumentPtr aDoc = aMgr->rootDocument();
+ if (aDoc->isOperation())
+ operationMgr()->abortOperation();
aDoc->redo();
updateCommandStatus();
}