SET(PROJECT_SOURCES
Events_Message.cpp
+ Events_MessageGroup.cpp
Events_Listener.cpp
Events_Loop.cpp
Events_Error.cpp
--- /dev/null
+// File: Events_MessageGroup.cpp
+// Created: Thu Mar 13 2014
+// Author: Mikhail PONIKAROV
+
+#include <Events_MessageGroup.h>
+
+Events_MessageGroup::Events_MessageGroup(const Events_ID theID, const void* theSender)
+: Events_Message(theID, theSender)
+{}
+
+Events_MessageGroup::~Events_MessageGroup()
+{}
+
public:
//! Creates the message
- Events_MessageGroup(const Events_ID theID, const void* theSender = 0)
- : Events_Message(theID, theSender)
- {
- }
+ Events_MessageGroup(const Events_ID theID, const void* theSender = 0);
//! do nothing in the destructor yet
- virtual ~Events_MessageGroup()
- {
- }
+ virtual ~Events_MessageGroup();
//! Creates a new empty group (to store it in the loop before flush)
virtual boost::shared_ptr<Events_MessageGroup> newEmpty() = 0;
#include <ModelAPI_Document.h>
#include <ModelAPI_Object.h>
#include <ModelAPI_ResultBody.h>
-
#include <TCollection_AsciiString.hxx>
#include <TDF_Label.hxx>
#include <TopoDS_Shape.hxx>
#endif
return false;
}
+ //
// Pass the results into the model
std::string anObjectName = aPath.Name().ToCString();
data()->setName(anObjectName);
- boost::shared_ptr<ModelAPI_ResultBody> aResult = document()->createBody(data());
+ boost::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
boost::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
aGeomShape->setImpl(new TopoDS_Shape(aShape));
- aResult->store(aGeomShape);
- setResult(aResult);
+
+ //LoadNamingDS of the imported shape
+ loadNamingDS(aGeomShape, aResultBody);
+
+ setResult(aResultBody);
return true;
}
+//============================================================================
+void ExchangePlugin_ImportFeature::loadNamingDS(
+ boost::shared_ptr<GeomAPI_Shape> theGeomShape,
+ boost::shared_ptr<ModelAPI_ResultBody> theResultBody)
+{
+ //load result
+ theResultBody->store(theGeomShape);
+ int aTag(1);
+ theResultBody->loadFirstLevel(theGeomShape, aTag);
+ theResultBody->loadDisconnectedEdges(theGeomShape, aTag);
+ theResultBody->loadDisconnectedVertexes(theGeomShape, aTag);
+}
+
LibHandle ExchangePlugin_ImportFeature::loadImportPlugin(const std::string& theFormatName)
{
std::string aLibName = library(theFormatName + ID());
protected:
EXCHANGEPLUGIN_EXPORT bool importFile(const std::string& theFileName);
EXCHANGEPLUGIN_EXPORT LibHandle loadImportPlugin(const std::string& theFormatName);
-
+
+private:
+ /// Loads Naming data structure to the document
+ void loadNamingDS(boost::shared_ptr<GeomAPI_Shape> theGeomShape,
+ boost::shared_ptr<ModelAPI_ResultBody> theResultBody);
};
#endif /* IMPORT_IMPORTFEATURE_H_ */
Events_Error::send(aFeatureError, this);
return;
}
+ // if result of Boolean operation is same as was before it means that Boolean operation has no sence
+ // and naming provides no result, so, generate an error in this case
+ if (anObject->isEqual(aFeature->shape())) {
+ std::string aFeatureError = "Boolean feature: operation was not performed";
+ Events_Error::send(aFeatureError, this);
+ return;
+ }
//LoadNamingDS
LoadNamingDS(aFeature, aResultBody, anObject, aTool, aType);
tooltip="Select a face for extrusion"
activate="true"
shape_types="face"
+ object_types="construction"
use_subshapes="true"
/>
<doublevalue id="extrusion_size" label="Size" min="0" step="1.0" default="1" icon=":icons/dimension_v.png" tooltip="Set size of extrusion">
#include "GeomAlgoAPI_FaceBuilder.h"
#include "GeomAlgoAPI_EdgeBuilder.h"
#include "GeomAlgoAPI_PointBuilder.h"
+ #include "GeomAlgoAPI_SketchBuilder.h"
%}
// to avoid error on this
// standard definitions
%include "typemaps.i"
%include "std_string.i"
+%include "std_list.i"
//%include <std_shared_ptr.i>
%include <boost_shared_ptr.i>
+%template(ShapeList) std::list<boost::shared_ptr<GeomAPI_Shape> >;
+
// all supported interfaces
%include "GeomAlgoAPI_FaceBuilder.h"
%include "GeomAlgoAPI_EdgeBuilder.h"
%include "GeomAlgoAPI_PointBuilder.h"
+%include "GeomAlgoAPI_SketchBuilder.h"
ADD_DEFINITIONS(-DMODEL_EXPORTS ${CAS_DEFINITIONS} ${BOOST_DEFINITIONS})
-ADD_LIBRARY(Model SHARED ${PROJECT_SOURCES} ${PROJECT_HEADERS})
+ADD_LIBRARY(Model MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS})
TARGET_LINK_LIBRARIES(Model ${PROJECT_LIBRARIES})
INCLUDE_DIRECTORIES(
void Model_Application::deleteDocument(string theDocID)
{
- myDocs.erase(theDocID);
+ if (myDocs.find(theDocID) != myDocs.end()) {
+ myDocs[theDocID]->close(true);
+ myDocs.erase(theDocID);
+ }
+ myLoadedByDemand.clear();
+}
+
+void Model_Application::deleteAllDocuments()
+{
+ myDocs.clear();
+ myLoadedByDemand.clear();
}
//=======================================================================
MODEL_EXPORT bool hasDocument(std::string theDocID);
//! Deletes the document from the application
MODEL_EXPORT void deleteDocument(std::string theDocID);
+ //! Deletes all documents existing in the application
+ MODEL_EXPORT void deleteAllDocuments();
//! Set path for the loaded by demand documents
void setLoadPath(std::string thePath);
void Model_AttributeRefAttr::setObject(ObjectPtr theObject)
{
- if (!myIsInitialized || myID->Get().Length() != 0 || object() != theObject) {
+ if (theObject && (!myIsInitialized || myID->Get().Length() != 0 || object() != theObject)) {
boost::shared_ptr<Model_Data> aData = boost::dynamic_pointer_cast<Model_Data>(
theObject->data());
myRef->Set(aData->label().Father());
boost::dynamic_pointer_cast<GeomAPI_PlanarEdges>(
boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext)->shape());
if (aWirePtr && aWirePtr->hasPlane()) {
- boost::shared_ptr<Model_Data> aData =
- boost::dynamic_pointer_cast<Model_Data>(owner()->data());
- TDF_Label aLab = aData->label();
+ TDF_Label aLab = myRef.myRef->Label();
// getting a type of selected shape
Handle(TDataStd_Integer) aTypeAttr;
if (!aLab.FindAttribute(TDataStd_Integer::GetID(), aTypeAttr)) {
return; // saving of context is enough: result construction contains exactly the needed shape
}
boost::shared_ptr<Model_Data> aData = boost::dynamic_pointer_cast<Model_Data>(owner()->data());
- TDF_Label aLab = aData->label();
+ TDF_Label aLab = myRef.myRef->Label();
// identify the reuslts of sub-object of the composite by edges
const TopoDS_Shape& aSubShape = theSubShape->impl<TopoDS_Shape>();
// save type of the selected shape in integer attribute
}
// iterate and store the result ids of sub-elements
Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab);
+ aRefs->Clear();
const int aSubNum = aComposite->numberOfSubs();
for(int a = 0; a < aSubNum; a++) {
FeaturePtr aSub = aComposite->subFeature(a);
if (owner()) {
aNewAttr->setObject(owner());
}
- mySubs.push_back(aNewAttr);
mySize->Set(aNewTag);
aNewAttr->setValue(theContext, theSubShape);
owner()->data()->sendAttributeUpdated(this);
boost::shared_ptr<ModelAPI_AttributeSelection>
Model_AttributeSelectionList::value(const int theIndex)
{
- return mySubs[theIndex];
+ TDF_Label aLabel = mySize->Label().FindChild(theIndex + 1);
+ // create a new attribute each time, by demand
+ // supporting of old attributes is too slow (synch each time) and buggy on redo
+ // (if attribute is deleted and created, the abort updates attriute and makes the Attr invalid)
+ boost::shared_ptr<Model_AttributeSelection> aNewAttr =
+ boost::shared_ptr<Model_AttributeSelection>(new Model_AttributeSelection(aLabel));
+ if (owner()) {
+ aNewAttr->setObject(owner());
+ }
+ return aNewAttr;
}
void Model_AttributeSelectionList::clear()
{
- if (!mySubs.empty()) {
+ if (mySize->Get() != 0) {
mySize->Set(0);
- mySubs.clear();
TDF_ChildIterator aSubIter(mySize->Label());
for(; aSubIter.More(); aSubIter.Next()) {
aSubIter.Value().ForgetAllAttributes(Standard_True);
mySize = TDataStd_Integer::Set(theLabel, 0);
mySelectionType = TDataStd_Real::Set(theLabel, 0);
} else { // recollect mySubs
- int aNum = mySize->Get();
- TDF_ChildIterator aSubIter(theLabel);
- for(; aSubIter.More(), aNum != 0; aSubIter.Next(), aNum--) {
- TDF_Label aChildLab = aSubIter.Value();
- boost::shared_ptr<Model_AttributeSelection> aNewAttr =
- boost::shared_ptr<Model_AttributeSelection>(new Model_AttributeSelection(aChildLab));
- if (owner())
- aNewAttr->setObject(owner());
- mySubs.push_back(aNewAttr);
- }
- }
-}
-
-void Model_AttributeSelectionList::setObject(const boost::shared_ptr<ModelAPI_Object>& theObject)
-{
- ModelAPI_AttributeSelectionList::setObject(theObject);
- std::vector<boost::shared_ptr<Model_AttributeSelection> >::iterator aSubIter = mySubs.begin();
- for(; aSubIter != mySubs.end(); aSubIter++) {
- (*aSubIter)->setObject(theObject);
+ theLabel.FindAttribute(TDataStd_Real::GetID(), mySelectionType);
}
}
{
Handle(TDataStd_Integer) mySize; ///< Contains size of this list
Handle(TDataStd_Real) mySelectionType; ///< Contains current index, TODO: make it integer, not real
- std::vector<boost::shared_ptr<Model_AttributeSelection> > mySubs; /// the selection attributes
public:
/// Adds the new reference to the end of the list
MODEL_EXPORT virtual void append(
/// Returns all attributes
MODEL_EXPORT virtual void clear();
- /// Sets the feature object
- MODEL_EXPORT virtual void setObject(const boost::shared_ptr<ModelAPI_Object>& theObject);
-
protected:
/// Objects are created for features automatically
MODEL_EXPORT Model_AttributeSelectionList(TDF_Label& theLabel);
- /// Performs the selection for the body result (TNaming Selection)
friend class Model_Data;
};
return isDone;
}
-void Model_Document::close()
+void Model_Document::close(const bool theForever)
{
boost::shared_ptr<ModelAPI_Session> aPM = Model_Session::get();
if (this != aPM->moduleDocument().get() && this == aPM->activeDocument().get()) {
// close all subs
std::set<std::string>::iterator aSubIter = mySubs.begin();
for (; aSubIter != mySubs.end(); aSubIter++)
- subDoc(*aSubIter)->close();
+ subDoc(*aSubIter)->close(theForever);
mySubs.clear();
- // close this only if it is module document, otherwise it can be undoed
- if (this == aPM->moduleDocument().get()) {
+
+ // close for thid document needs no transaction in this document
+ boost::static_pointer_cast<Model_Session>(Model_Session::get())->setCheckTransactions(false);
+
+ // delete all features of this document
+ boost::shared_ptr<ModelAPI_Document> aThis =
+ Model_Application::getApplication()->getDocument(myID);
+ Events_Loop* aLoop = Events_Loop::loop();
+ NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator aFeaturesIter(myObjs);
+ for(; aFeaturesIter.More(); aFeaturesIter.Next()) {
+ FeaturePtr aFeature = aFeaturesIter.Value();
+ static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ ModelAPI_EventCreator::get()->sendDeleted(aThis, ModelAPI_Feature::group());
+ ModelAPI_EventCreator::get()->sendUpdated(aFeature, EVENT_DISP);
+ aFeature->eraseResults();
+ aFeature->erase();
+ }
+ myObjs.Clear();
+ aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
+ aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
+
+ // close all only if it is really asked, otherwise it can be undoed/redoed
+ if (theForever) {
if (myDoc->CanClose() == CDM_CCS_OK)
myDoc->Close();
- Model_Application::getApplication()->deleteDocument(myID);
}
+
+ boost::static_pointer_cast<Model_Session>(Model_Session::get())->setCheckTransactions(true);
}
void Model_Document::startOperation()
}
myIsEmptyTr[myTransactionsAfterSave] = allWasEmpty;
myTransactionsAfterSave++;
- myDoc->PerformDeltaCompaction();
+ if (allWasEmpty) {
+ // Issue 151: if everything is empty, it is a problem for OCCT to work with it,
+ // just commit the empty that returns nothing
+ myDoc->CommitCommand();
+ } else {
+ myDoc->PerformDeltaCompaction();
+ }
return !allWasEmpty;
}
{
if (myNestedNum > 0 && !myDoc->HasOpenCommand()) { // abort all what was done in nested
// first compact all nested
- if (compactNested()) {
- // for nested it is undo and clear redos
- myDoc->Undo();
- }
+ compactNested();
+ myDoc->Undo();
myDoc->ClearRedos();
myTransactionsAfterSave--;
myIsEmptyTr.erase(myTransactionsAfterSave);
}
boost::shared_ptr<Model_Data> aData = boost::static_pointer_cast<Model_Data>(theFeature->data());
- TDF_Label aFeatureLabel = aData->label().Father();
- if (myObjs.IsBound(aFeatureLabel))
- myObjs.UnBind(aFeatureLabel);
- else
- return; // not found feature => do not remove
- // erase fields
- theFeature->erase();
- // erase all attributes under the label of feature
- aFeatureLabel.ForgetAllAttributes();
- // remove it from the references array
- if (theFeature->isInHistory()) {
- RemoveFromRefArray(featuresLabel(), aFeatureLabel);
+ if (aData) {
+ TDF_Label aFeatureLabel = aData->label().Father();
+ if (myObjs.IsBound(aFeatureLabel))
+ myObjs.UnBind(aFeatureLabel);
+ else
+ return; // not found feature => do not remove
+ // erase fields
+ theFeature->erase();
+ // erase all attributes under the label of feature
+ aFeatureLabel.ForgetAllAttributes();
+ // remove it from the references array
+ if (theFeature->isInHistory()) {
+ RemoveFromRefArray(featuresLabel(), aFeatureLabel);
+ }
}
// event: feature is deleted
ModelAPI_EventCreator::get()->sendDeleted(theFeature->document(), ModelAPI_Feature::group());
for (; aLabIter.More(); aLabIter.Next()) {
TDF_Label aFLabel = aLabIter.Value()->Label();
FeaturePtr aFeature = feature(aFLabel);
+ if (!aFeature) // may be on close
+ continue;
const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRIter = aResults.begin();
for (; aRIter != aResults.cend(); aRIter++) {
// event: model is updated
static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent);
-
- // update results of the appeared feature
- updateResults(aFeature);
} else { // nothing is changed, both iterators are incremented
aFeature = myObjs.Find(aFeatureLabel);
aKeptFeatures.insert(aFeature);
static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent);
}
+ }
+ }
+ // update results of thefeatures (after features created because they may be connected, like sketch and sub elements)
+ TDF_ChildIDIterator aLabIter2(featuresLabel(), TDataStd_Comment::GetID());
+ for (; aLabIter2.More(); aLabIter2.Next()) {
+ TDF_Label aFeatureLabel = aLabIter2.Value()->Label();
+ if (myObjs.IsBound(aFeatureLabel)) { // a new feature is inserted
+ FeaturePtr aFeature = myObjs.Find(aFeatureLabel);
updateResults(aFeature);
}
}
+
// check all features are checked: if not => it was removed
NCollection_DataMap<TDF_Label, FeaturePtr>::Iterator aFIter(myObjs);
while (aFIter.More()) {
void Model_Document::updateResults(FeaturePtr theFeature)
{
// for not persistent is will be done by parametric updater automatically
- if (!theFeature->isPersistentResult()) return;
+ //if (!theFeature->isPersistentResult()) return;
// check the existing results and remove them if there is nothing on the label
std::list<ResultPtr>::const_iterator aResIter = theFeature->results().cbegin();
while(aResIter != theFeature->results().cend()) {
- ResultBodyPtr aBody = boost::dynamic_pointer_cast<ModelAPI_ResultBody>(*aResIter);
+ ResultPtr aBody = boost::dynamic_pointer_cast<ModelAPI_Result>(*aResIter);
if (aBody) {
if (!aBody->data()->isValid()) {
// found a disappeared result => remove it
aNewBody = createBody(theFeature->data(), aResIndex);
} else if (aGroup->Get() == ModelAPI_ResultPart::group().c_str()) {
aNewBody = createPart(theFeature->data(), aResIndex);
- } else if (aGroup->Get() != ModelAPI_ResultConstruction::group().c_str() &&
- aGroup->Get() != ModelAPI_ResultGroup::group().c_str()) {
+ } else if (aGroup->Get() == ModelAPI_ResultConstruction::group().c_str()) {
+ theFeature->execute(); // construction shapes are needed for sketch solver
+ break;
+ } else if (aGroup->Get() == ModelAPI_ResultGroup::group().c_str()) {
+ aNewBody = createGroup(theFeature->data(), aResIndex);
+ } else {
Events_Error::send(std::string("Unknown type of result is found in the document:") +
TCollection_AsciiString(aGroup->Get()).ToCString());
}
MODEL_EXPORT virtual bool save(const char* theFileName, std::list<std::string>& theResults);
//! Removes document data
- MODEL_EXPORT virtual void close();
+ //! \param theForever if it is false, document is just hiden (to keep possibility make it back on Undo/Redo)
+ MODEL_EXPORT virtual void close(const bool theForever = false);
//! Starts a new operation (opens a tansaction)
MODEL_EXPORT virtual void startOperation();
AttributeSelectionListPtr aList = myOwnerData->selectionList("group_list");
if (aList) {
std::list<boost::shared_ptr<GeomAPI_Shape> > aSubs;
- for(int a = aList->size(); a >= 0; a--) {
+ for(int a = aList->size() - 1; a >= 0; a--) {
boost::shared_ptr<GeomAPI_Shape> aSelection = aList->value(a)->value();
if (aSelection && !aSelection->isNull()) {
aSubs.push_back(aSelection);
return ROOT_DOC->save(theFileName, theResults);
}
+void Model_Session::closeAll()
+{
+ ROOT_DOC->close(true);
+ Model_Application::getApplication()->deleteAllDocuments();
+}
+
void Model_Session::startOperation()
{
ROOT_DOC->startOperation();
return myImpl->createFeature(theFeatureID);
}
+ // load all information about plugins, features and attributes
+ LoadPluginsInfo();
+
if (myPlugins.find(theFeatureID) != myPlugins.end()) {
std::pair<std::string, std::string>& aPlugin = myPlugins[theFeatureID]; // plugin and doc kind
if (!aPlugin.second.empty() && aPlugin.second != activeDocument()->kind()) {
aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED), 0, true);
aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED), 0, true);
aLoop->registerListener(this, Events_Loop::eventByName(EVENT_VALIDATOR_LOADED));
-
- // load all information about plugins, features and attributes
- LoadPluginsInfo();
}
void Model_Session::processEvent(const boost::shared_ptr<Events_Message>& theMessage)
//! \returns true if file was stored successfully
MODEL_EXPORT virtual bool save(const char* theFileName, std::list<std::string>& theResults);
+ //! Closes all documents
+ MODEL_EXPORT virtual void closeAll();
+
//! Starts a new operation (opens a tansaction)
MODEL_EXPORT virtual void startOperation();
//! Finishes the previously started operation (closes the transaction)
aLoop->registerListener(this, kCreatedEvent);
static const Events_ID kUpdatedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED);
aLoop->registerListener(this, kUpdatedEvent);
+ static const Events_ID kMovedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED);
+ aLoop->registerListener(this, kMovedEvent);
static const Events_ID kOpFinishEvent = aLoop->eventByName("FinishOperation");
aLoop->registerListener(this, kOpFinishEvent);
static const Events_ID kOpAbortEvent = aLoop->eventByName("AbortOperation");
static const Events_ID kOpStartEvent = aLoop->eventByName("StartOperation");
aLoop->registerListener(this, kOpStartEvent);
- Config_PropManager::registerProp("Model update", "automatic_rebuild", "Rebuild automatically",
+ Config_PropManager::registerProp("Model update", "automatic_rebuild", "Rebuild immediately",
Config_Prop::Bool, "false");
isAutomatic = Config_PropManager::findProp("Model update", "automatic_rebuild")->value() == "true";
}
static const Events_ID kRebuildEvent = aLoop->eventByName("Rebuild");
static const Events_ID kCreatedEvent = aLoop->eventByName(EVENT_OBJECT_CREATED);
static const Events_ID kUpdatedEvent = aLoop->eventByName(EVENT_OBJECT_UPDATED);
+ static const Events_ID kMovedEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED);
static const Events_ID kOpFinishEvent = aLoop->eventByName("FinishOperation");
static const Events_ID kOpAbortEvent = aLoop->eventByName("AbortOperation");
static const Events_ID kOpStartEvent = aLoop->eventByName("StartOperation");
isAutomaticChanged = true;
isAutomatic = true;
}
- } else if (theMessage->eventID() == kCreatedEvent || theMessage->eventID() == kUpdatedEvent) {
+ } else if (theMessage->eventID() == kCreatedEvent || theMessage->eventID() == kUpdatedEvent ||
+ theMessage->eventID() == kMovedEvent) {
boost::shared_ptr<ModelAPI_ObjectUpdatedMessage> aMsg =
boost::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
const std::set<ObjectPtr>& anObjs = aMsg->objects();
for(; anObjIter != anObjs.cend(); anObjIter++) {
myJustCreatedOrUpdated.insert(*anObjIter);
}
+ if (theMessage->eventID() == kMovedEvent)
+ return; // this event is for solver update, not here
} else if (theMessage->eventID() == kOpStartEvent) {
myJustCreatedOrUpdated.clear();
return; // we don't need the update only on operation start (caused problems in PartSet_Listener::processEvent)
isAutomaticChanged = true;
isAutomatic = true;
}
+ // the hardcode (DBC asked): hide the sketch referenced by extrusion on apply
+ if (theMessage->eventID() == kOpFinishEvent) {
+ std::set<boost::shared_ptr<ModelAPI_Object> >::iterator aFIter;
+ for(aFIter = myJustCreatedOrUpdated.begin(); aFIter != myJustCreatedOrUpdated.end(); aFIter++)
+ {
+ FeaturePtr aF = boost::dynamic_pointer_cast<ModelAPI_Feature>(*aFIter);
+ if (aF && aF->getKind() == "Extrusion") {
+ if (aF->selection("extrusion_face")) {
+ ResultPtr aSketchRes = aF->selection("extrusion_face")->context();
+ if (aSketchRes) {
+ static Events_ID HIDE_DISP = Events_Loop::loop()->eventByName(EVENT_OBJECT_TOHIDE);
+ ModelAPI_EventCreator::get()->sendUpdated(aSketchRes, HIDE_DISP);
+ }
+ }
+ }
+ }
+ }
}
if (isExecuted)
if (updateFeature(aComposite->subFeature(a)))
aMustbeUpdated = true;
}
- if (aMustbeUpdated) {
- for(int a = 0; a < aSubsNum; a++) {
- if (aComposite->subFeature(a) && aFactory->validate(aComposite->subFeature(a)))
- aComposite->subFeature(a)->execute();
- }
- }
}
// check all references: if referenced objects are updated, this object also must be updated
std::list<std::pair<std::string, std::list<ObjectPtr> > > aRefs;
}
}
+ //std::cout<<"Update feature "<<theFeature->getKind()<<" must be updated = "<<aMustbeUpdated<<std::endl;
// execute feature if it must be updated
if (aMustbeUpdated) {
if (boost::dynamic_pointer_cast<Model_Document>(theFeature->document())->executeFeatures() ||
if (isAutomatic || (myJustCreatedOrUpdated.find(theFeature) != myJustCreatedOrUpdated.end()) ||
!theFeature->isPersistentResult() /* execute quick, not persistent results */)
{
+ //std::cout<<"Execute feature "<<theFeature->getKind()<<std::endl;
// before execution update the selection attributes if any
list<AttributePtr> aRefs =
theFeature->data()->attributes(ModelAPI_AttributeSelection::type());
aSel->value(a)->update();
}
}
+ // for sketch after update of plane (by update of selection attribute)
+ // but before execute, all sub-elements also must be updated (due to the plane changes)
+ if (aComposite) {
+ int aSubsNum = aComposite->numberOfSubs();
+ for(int a = 0; a < aSubsNum; a++) {
+ FeaturePtr aSub = aComposite->subFeature(a);
+ bool aWasModified = myUpdated[aSub];
+ myUpdated.erase(myUpdated.find(aSub)); // erase to update for sure (plane may be changed)
+ myInitial.insert(aSub);
+ updateFeature(aSub);
+ myUpdated[aSub] = aWasModified; // restore value
+ }
+ // re-execute after update: solver may update the previous values, so, shapes must be
+ // updated
+ for(int a = 0; a < aSubsNum; a++) {
+ if (aComposite->subFeature(a) && aFactory->validate(aComposite->subFeature(a)))
+ aComposite->subFeature(a)->execute();
+ }
+ }
+
// execute in try-catch to avoid internal problems of the feature
try {
theFeature->execute();
#include <ModelAPI_AttributeValidator.h>
#include <Events_Error.h>
-const static std::string kDefaultId = "Model_FeatureValidator";
-
void Model_ValidatorsFactory::registerValidator(const std::string& theID,
ModelAPI_Validator* theValidator)
{
Model_ValidatorsFactory::Model_ValidatorsFactory()
: ModelAPI_ValidatorsFactory()
{
+ const static std::string kDefaultId = "Model_FeatureValidator";
registerValidator(kDefaultId, new Model_FeatureValidator);
}
void Model_ValidatorsFactory::addDefaultValidators(std::list<ModelAPI_Validator*>& theValidators) const
{
+ const static std::string kDefaultId = "Model_FeatureValidator";
std::map<std::string, ModelAPI_Validator*>::const_iterator it = myIDs.find(kDefaultId);
if(it == myIDs.end())
return;
bool Model_ValidatorsFactory::validate(const boost::shared_ptr<ModelAPI_Feature>& theFeature) const
{
+ const static std::string kDefaultId = "Model_FeatureValidator";
// check feature validators first
std::map<std::string, AttrValidators>::const_iterator aFeature =
myFeatures.find(theFeature->getKind());
void Model_ValidatorsFactory::registerNotObligatory(std::string theFeature, std::string theAttribute)
{
+ const static std::string kDefaultId = "Model_FeatureValidator";
std::map<std::string, ModelAPI_Validator*>::const_iterator it = myIDs.find(kDefaultId);
if (it != myIDs.end()) {
Model_FeatureValidator* aValidator = dynamic_cast<Model_FeatureValidator*>(it->second);
virtual const std::string& kind() const = 0;
//! Removes document data
- virtual void close() = 0;
+ //! \param theForever if it is false, document is just hiden (to keep possibility make it back on Undo/Redo)
+ virtual void close(const bool theForever = false) = 0;
//! Adds to the document the new feature of the given feature id
//! \param creates feature and puts it in the document (if it is not action)
//! \returns true if file was stored successfully
virtual bool save(const char* theFileName, std::list<std::string>& theResults) = 0;
+ //! Closes all documents
+ virtual void closeAll() = 0;
+
//! Starts a new operation (opens a tansaction)
virtual void startOperation() = 0;
//! Finishes the previously started operation (closes the transaction)
#include "ModelAPI_Tools.h"
#include <ModelAPI_ResultBody.h>
#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultGroup.h>
namespace ModelAPI_Tools {
-boost::shared_ptr<GeomAPI_Shape> shape(const ResultPtr& theResult)
-{
- ResultBodyPtr aBody = boost::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
- if (aBody)
- return aBody->shape();
- ResultConstructionPtr aConstruct = boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
+ boost::shared_ptr<GeomAPI_Shape> shape(const ResultPtr& theResult)
+ {
+
+ ResultBodyPtr aBody = boost::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
+ if (aBody)
+ return aBody->shape();
+
+ ResultConstructionPtr aConstruct = boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(
theResult);
- if (aConstruct)
- return aConstruct->shape();
- return boost::shared_ptr<GeomAPI_Shape>();
-}
+ if (aConstruct)
+ return aConstruct->shape();
+ ResultGroupPtr aGroup = boost::dynamic_pointer_cast<ModelAPI_ResultGroup>(theResult);
+ if (aGroup)
+ return aGroup->shape();
+ return boost::shared_ptr<GeomAPI_Shape>();
+ }
}
/// \param theZ the Z projection value
virtual void setViewProjection(double theX, double theY, double theZ) = 0;
+ /// Add selection filter to the viewer
+ virtual void addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) = 0;
+
+ /// Remove selection filter from the viewer
+ virtual void removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter) = 0;
+
+ /// Remove all selection filters from the viewer
+ virtual void clearSelectionFilters() = 0;
signals:
void lastViewClosed();
#include "ModuleBase_ViewerPrs.h"
#include "ModuleBase_IPropertyPanel.h"
#include "ModuleBase_ISelection.h"
+#include "ModuleBase_IViewer.h"
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_Document.h>
#include <Events_Loop.h>
-#include <TopoDS.hxx>
-#include <TopoDS_Vertex.hxx>
-
#ifdef _DEBUG
#include <QDebug>
#endif
ModuleBase_Operation::~ModuleBase_Operation()
{
delete myDescription;
+ clearPreselection();
}
QString ModuleBase_Operation::id() const
bool ModuleBase_Operation::canBeCommitted() const
{
- return true;
+ return isValid();
}
void ModuleBase_Operation::flushUpdated()
return false;
ModuleBase_ModelWidget* aWgt, *aFilledWgt = 0;
- ModuleBase_ViewerPrs aPrs;
QList<ModuleBase_ModelWidget*>::const_iterator aWIt;
- QList<ModuleBase_ViewerPrs>::const_iterator aPIt;
+ QList<ModuleBase_WidgetValueFeature*>::const_iterator aPIt;
bool isSet = false;
for (aWIt = aWidgets.constBegin(), aPIt = myPreSelection.constBegin();
(aWIt != aWidgets.constEnd()) && (aPIt != myPreSelection.constEnd());
++aWIt, ++aPIt) {
aWgt = (*aWIt);
- aPrs = (*aPIt);
- ModuleBase_WidgetValueFeature aValue;
- aValue.setObject(aPrs.object());
- // Check if the selection has a selected point
- // for today it is impossible to do because
- // the selected point demands convertation to Sketch plane 2d
- if (!aWgt->setValue(&aValue)) {
+ ModuleBase_WidgetValueFeature* aValue = (*aPIt);
+ if (!aWgt->setValue(aValue)) {
isSet = false;
break;
} else {
}
void ModuleBase_Operation::initSelection(ModuleBase_ISelection* theSelection,
- ModuleBase_IViewer* /*theViewer*/)
+ ModuleBase_IViewer* theViewer)
{
- myPreSelection.clear();
+ clearPreselection();
+ QList<ModuleBase_ViewerPrs> aPreSelected;
// Check that the selected result are not results of operation feature
- QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected();
FeaturePtr aFeature = feature();
if (aFeature) {
+ QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected();
+
std::list<ResultPtr> aResults = aFeature->results();
QList<ObjectPtr> aResList;
std::list<ResultPtr>::const_iterator aIt;
foreach (ModuleBase_ViewerPrs aPrs, aSelected) {
if ((!aResList.contains(aPrs.object())) && (aPrs.object() != aFeature))
- myPreSelection.append(aPrs);
+ aPreSelected.append(aPrs);
}
} else
- myPreSelection = aSelected;
+ aPreSelected = theSelection->getSelected();
+
+ // convert the selection values to the values, which are set to the operation widgets
+
+ Handle(V3d_View) aView = theViewer->activeView();
+ foreach (ModuleBase_ViewerPrs aPrs, aPreSelected) {
+ ModuleBase_WidgetValueFeature* aValue = new ModuleBase_WidgetValueFeature();
+ aValue->setObject(aPrs.object());
+
+ double aX, anY;
+ if (getViewerPoint(aPrs, theViewer, aX, anY))
+ aValue->setPoint(boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aX, anY)));
+ myPreSelection.append(aValue);
+ }
}
void ModuleBase_Operation::onWidgetActivated(ModuleBase_ModelWidget* theWidget)
return isApplyed;
}
+bool ModuleBase_Operation::getViewerPoint(ModuleBase_ViewerPrs thePrs,
+ ModuleBase_IViewer* theViewer,
+ double& theX, double& theY)
+{
+ return false;
+}
+
+void ModuleBase_Operation::clearPreselection()
+{
+ while (!myPreSelection.isEmpty()) {
+ delete myPreSelection.takeFirst();
+ }
+}
void ModuleBase_Operation::setPropertyPanel(ModuleBase_IPropertyPanel* theProp)
{
class ModuleBase_IPropertyPanel;
class ModuleBase_ISelection;
class ModuleBase_IViewer;
+class ModuleBase_WidgetValueFeature;
class QKeyEvent;
/// \return true if the point is set
virtual bool setWidgetValue(ObjectPtr theFeature, double theX, double theY);
+ /// Return a widget value point by the selection and the viewer position
+ /// The default realization returns false
+ /// \param thePrs the presentation
+ /// \param theViewer a viewer to have the viewer the eye position
+ /// \param theX the horizontal coordinate
+ /// \param theY the vertical coordinate
+ /// \return true if the point exits in the selection
+ virtual bool getViewerPoint(ModuleBase_ViewerPrs thePrs,
+ ModuleBase_IViewer* theViewer,
+ double& theX, double& theY);
+
+ // Removes the preselection information and clears the map of preselection
+ void clearPreselection();
+
protected:
FeaturePtr myFeature; /// the operation feature to be handled
QStringList myNestedFeatures;
/// List of pre-selected object
- QList<ModuleBase_ViewerPrs> myPreSelection;
+ QList<ModuleBase_WidgetValueFeature*> myPreSelection;
/// Access to property panel
ModuleBase_IPropertyPanel* myPropertyPanel;
#include <ModelAPI_Session.h>
#include <ModelAPI_Document.h>
+#include <ModelAPI_ResultConstruction.h>
#include <AIS_InteractiveObject.hxx>
#include <AIS_Shape.hxx>
if (aObj) {
DocumentPtr aDoc = aObj->document();
SessionPtr aMgr = ModelAPI_Session::get();
- return (aDoc == aMgr->activeDocument()) || (aDoc == aMgr->moduleDocument());
+ return (aDoc == aMgr->activeDocument() /* MPV: for the current moment selection in other document is not possible || (aDoc == aMgr->moduleDocument()*/);
}
}
}
}
return Standard_False;
}
+
+
+IMPLEMENT_STANDARD_HANDLE(ModuleBase_ObjectTypesFilter, SelectMgr_Filter);
+IMPLEMENT_STANDARD_RTTIEXT(ModuleBase_ObjectTypesFilter, SelectMgr_Filter);
+
+
+//TODO (VSV): Check bug in OCCT: Filter result is ignored (bug25340)
+Standard_Boolean ModuleBase_ObjectTypesFilter::IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const
+{
+ Standard_Boolean isOk = ModuleBase_ShapeDocumentFilter::IsOk(theOwner);
+ if (isOk && theOwner->HasSelectable()) {
+ Handle(AIS_InteractiveObject) aAisObj =
+ Handle(AIS_InteractiveObject)::DownCast(theOwner->Selectable());
+ if (!aAisObj.IsNull()) {
+ boost::shared_ptr<GeomAPI_AISObject> aAISObj = AISObjectPtr(new GeomAPI_AISObject());
+ aAISObj->setImpl(new Handle(AIS_InteractiveObject)(aAisObj));
+ ObjectPtr aObj = myWorkshop->findPresentedObject(aAISObj);
+
+ foreach (QString aType, myTypes) {
+ if (aType.toLower() == "construction") {
+ ResultConstructionPtr aConstr =
+ boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aObj);
+ return (aConstr != NULL);
+ } // ToDo: Process other types of objects
+ }
+ }
+ }
+ return Standard_False;
+}
#ifndef ModuleBase_ViewerFilters_H
#define ModuleBase_ViewerFilters_H
+#include <QStringList>
+
#include <SelectMgr_Filter.hxx>
#include <SelectMgr_EntityOwner.hxx>
#include <gp_Pln.hxx>
DEFINE_STANDARD_RTTI(ModuleBase_ShapeDocumentFilter)
-private:
+protected:
ModuleBase_IWorkshop* myWorkshop;
};
gp_Pln myPlane;
};
+
+/**
+* A filter which provides filtering of selection in 3d viewer.
+* Installing of this filter lets to select only object of requested type
+*/
+DEFINE_STANDARD_HANDLE(ModuleBase_ObjectTypesFilter, SelectMgr_Filter);
+class ModuleBase_ObjectTypesFilter: public ModuleBase_ShapeDocumentFilter
+{
+public:
+ Standard_EXPORT ModuleBase_ObjectTypesFilter(ModuleBase_IWorkshop* theWorkshop, const QStringList& theTypes):
+ ModuleBase_ShapeDocumentFilter(theWorkshop), myTypes(theTypes) {}
+
+ Standard_EXPORT virtual Standard_Boolean IsOk(const Handle(SelectMgr_EntityOwner)& theOwner) const;
+
+ DEFINE_STANDARD_RTTI(ModuleBase_ObjectTypesFilter)
+private:
+ QStringList myTypes;
+};
+
#endif
\ No newline at end of file
QList<QWidget*> ModuleBase_WidgetChoice::getControls() const
{
QList<QWidget*> aControls;
- aControls.append(myLabel);
aControls.append(myCombo);
return aControls;
}
QList<QWidget*> ModuleBase_WidgetDoubleValue::getControls() const
{
QList<QWidget*> aList;
- aList.append(myLabel);
aList.append(mySpinBox);
return aList;
}
QList<QWidget*> ModuleBase_WidgetFeature::getControls() const
{
QList<QWidget*> aList;
- aList.append(myLabel);
aList.append(myEditor);
return aList;
}
myUseSubShapes = theData->getBooleanAttribute("use_subshapes", false);
//TODO_END
connect(myTypeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onSelectionTypeChanged()));
+
activateSelection(true);
}
//********************************************************************
bool ModuleBase_WidgetMultiSelector::eventFilter(QObject* theObj, QEvent* theEvent)
{
- if (theObj == myListControl) {
- if (theEvent->type() == QEvent::FocusIn)
- activateSelection(true);
- }
+ //TODO: Remove maybe?
return ModuleBase_ModelWidget::eventFilter(theObj, theEvent);
}
+//********************************************************************
+void ModuleBase_WidgetMultiSelector::activateSelection(bool toActivate)
+{
+ myIsActive = toActivate;
+ if (myIsActive) {
+ connect(myWorkshop, SIGNAL(selectionChanged()),
+ this, SLOT(onSelectionChanged()),
+ Qt::UniqueConnection);
+ activateShapeSelection();
+ } else {
+ disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
+ myWorkshop->deactivateSubShapesSelection();
+ }
+}
+
+//********************************************************************
+void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
+{
+ activateShapeSelection();
+ QList<ObjectPtr> anEmptyList;
+ myWorkshop->setSelected(anEmptyList);
+ // Clear mySelection, myListControl and storeValue()
+ onSelectionChanged();
+}
+
//********************************************************************
void ModuleBase_WidgetMultiSelector::onSelectionChanged()
{
GeomShapePtr aShape;
for (aIt = aOwnersList.cbegin(); aIt != aOwnersList.cend(); aShpIt.Next(), aIt++) {
ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(*aIt);
+ if (myFeature) {
+ // We can not select a result of our feature
+ const std::list<ResultPtr>& aResList = myFeature->results();
+ std::list<ResultPtr>::const_iterator aIt;
+ bool isSkipSelf = false;
+ for (aIt = aResList.cbegin(); aIt != aResList.cend(); ++aIt) {
+ if ((*aIt) == aResult) {
+ isSkipSelf = true;
+ break;
+ }
+ }
+ if(isSkipSelf)
+ continue;
+ }
aShape = boost::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
aShape->setImpl(new TopoDS_Shape(aShpIt.Value()));
mySelection.append(GeomSelection(aResult, aShape));
emit valuesChanged();
}
-
-//********************************************************************
-void ModuleBase_WidgetMultiSelector::updateSelectionList()
-{
- QString aType;
- if (myTypeCombo->currentText().toLower() == "vertices")
- aType = "vertex";
- else if (myTypeCombo->currentText().toLower() == "edges")
- aType = "edge";
- else if (myTypeCombo->currentText().toLower() == "faces")
- aType = "face";
- else if (myTypeCombo->currentText().toLower() == "solids")
- aType = "solid";
-
- myListControl->clear();
- int i = 1;
- foreach (GeomSelection aSel, mySelection) {
- QString aName(aSel.first->data()->name().c_str());
- aName += ":" + aType + QString("_%1").arg(i);
- myListControl->addItem(aName);
- i++;
- }
-}
-
-
//********************************************************************
void ModuleBase_WidgetMultiSelector::filterShapes(const NCollection_List<TopoDS_Shape>& theShapesToFilter,
NCollection_List<TopoDS_Shape>& theResult)
}
}
-
//********************************************************************
void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const TopAbs_ShapeEnum theShapeType)
{
QString aShapeTypeName;
+
for (int idx = 0; idx < myTypeCombo->count(); ++idx) {
aShapeTypeName = myTypeCombo->itemText(idx);
TopAbs_ShapeEnum aRefType = ModuleBase_WidgetShapeSelector::shapeType(aShapeTypeName);
if(aRefType == theShapeType && idx != myTypeCombo->currentIndex()) {
+ activateSelection(false);
+ bool isBlocked = myTypeCombo->blockSignals(true);
myTypeCombo->setCurrentIndex(idx);
+ myTypeCombo->blockSignals(isBlocked);
+ activateSelection(true);
break;
}
}
}
-//********************************************************************
-void ModuleBase_WidgetMultiSelector::activateSelection(bool toActivate)
-{
- myIsActive = toActivate;
- if (myIsActive) {
- connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
- //onSelectionTypeChanged();
- } else {
- disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
- myWorkshop->deactivateSubShapesSelection();
- }
-}
-
void ModuleBase_WidgetMultiSelector::activateShapeSelection()
{
QString aNewType = myTypeCombo->currentText();
}
//********************************************************************
-void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
+void ModuleBase_WidgetMultiSelector::updateSelectionList()
{
- QList<ObjectPtr> anEmptyList;
- myWorkshop->setSelected(anEmptyList);
- activateShapeSelection();
- onSelectionChanged();
+ QString aType;
+ if (myTypeCombo->currentText().toLower() == "vertices")
+ aType = "vertex";
+ else if (myTypeCombo->currentText().toLower() == "edges")
+ aType = "edge";
+ else if (myTypeCombo->currentText().toLower() == "faces")
+ aType = "face";
+ else if (myTypeCombo->currentText().toLower() == "solids")
+ aType = "solid";
+
+ myListControl->clear();
+ int i = 1;
+ foreach (GeomSelection aSel, mySelection) {
+ QString aName(aSel.first->data()->name().c_str());
+ aName += ":" + aType + QString("_%1").arg(i);
+ myListControl->addItem(aName);
+ i++;
+ }
+ myListControl->repaint();
}
#include <ModuleBase_Definitions.h>
#include <ModuleBase_ISelection.h>
#include <ModuleBase_IWorkshop.h>
+#include <ModuleBase_IViewer.h>
#include <ModuleBase_Tools.h>
#include <ModuleBase_WidgetValueFeature.h>
+
#include <Config_WidgetAPI.h>
#include <Events_Loop.h>
#include <Events_Message.h>
#include <ModelAPI_Events.h>
#include <ModelAPI_Feature.h>
#include <ModelAPI_Result.h>
+#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_AttributeReference.h>
#include <ModelAPI_AttributeSelection.h>
#include <ModelAPI_Session.h>
myTextLine->setToolTip(aToolTip);
myTextLine->installEventFilter(this);
- myBasePalet = myTextLine->palette();
- myInactivePalet = myBasePalet;
- myInactivePalet.setBrush(QPalette::Base, QBrush(Qt::gray, Qt::Dense6Pattern));
- myTextLine->setPalette(myInactivePalet);
-
aLayout->addWidget(myTextLine, 1);
std::string aTypes = theData->getProperty("shape_types");
- myShapeTypes = QString(aTypes.c_str()).split(' ');
+ myShapeTypes = QString(aTypes.c_str()).split(' ', QString::SkipEmptyParts);
+
+ std::string aObjTypes = theData->getProperty("object_types");
+ myObjectTypes = QString(aObjTypes.c_str()).split(' ', QString::SkipEmptyParts);
myUseSubShapes = theData->getBooleanAttribute("use_subshapes", false);
}
QList<QWidget*> ModuleBase_WidgetShapeSelector::getControls() const
{
QList<QWidget*> aControls;
- aControls.append(myLabel);
aControls.append(myTextLine);
return aControls;
}
if (!aShape)
return;
+ /// Check that object has acceptable type
+ if (!acceptObjectType(aObject))
+ return;
+
// Get sub-shapes from local selection
if (myUseSubShapes) {
NCollection_List<TopoDS_Shape> aShapeList;
// Check that the selection corresponds to selection type
if (myUseSubShapes) {
- if (!isAccepted(aShape))
+ if (!acceptSubShape(aShape))
return;
} else {
- if (!isAccepted(aObject))
+ if (!acceptObjectShape(aObject))
return;
}
setObject(aObject, aShape);
}
//********************************************************************
-bool ModuleBase_WidgetShapeSelector::isAccepted(const ObjectPtr theResult) const
+bool ModuleBase_WidgetShapeSelector::acceptObjectShape(const ObjectPtr theResult) const
{
ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(theResult);
}
//********************************************************************
-bool ModuleBase_WidgetShapeSelector::isAccepted(boost::shared_ptr<GeomAPI_Shape> theShape) const
+bool ModuleBase_WidgetShapeSelector::acceptSubShape(boost::shared_ptr<GeomAPI_Shape> theShape) const
{
TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
foreach (QString aType, myShapeTypes) {
return false;
}
+//********************************************************************
+bool ModuleBase_WidgetShapeSelector::acceptObjectType(const ObjectPtr theObject) const
+{
+ // Definition of types is not obligatory. If types are not defined then
+ // it means that accepted any type
+ if (myObjectTypes.isEmpty())
+ return true;
+
+ foreach (QString aType, myObjectTypes) {
+ if (aType.toLower() == "construction") {
+ ResultConstructionPtr aConstr =
+ boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(theObject);
+ return (aConstr != NULL);
+ } // ToDo: Process other types of objects
+ }
+ // Object type is defined but not found
+ return false;
+}
+
+
//********************************************************************
void ModuleBase_WidgetShapeSelector::updateSelectionName()
{
myTextLine->setText(QString::fromStdString(aName));
} else {
if (myIsActive) {
- QString aMsg = tr("Select a ");
- int i = 0;
- foreach (QString aType, myShapeTypes) {
- if (i > 0)
- aMsg += " or ";
- aMsg += aType;
- i++;
- }
- myTextLine->setText(aMsg);
- } else
- myTextLine->setText(tr("No object selected"));
+ myTextLine->setText("");
+ }
}
}
void ModuleBase_WidgetShapeSelector::activateSelection(bool toActivate)
{
myIsActive = toActivate;
- if (myIsActive)
- myTextLine->setPalette(myBasePalet);
- else
- myTextLine->setPalette(myInactivePalet);
updateSelectionName();
if (myIsActive) {
connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
if (myUseSubShapes) {
+
QIntList aList;
foreach (QString aType, myShapeTypes)
aList.append(shapeType(aType));
myWorkshop->activateSubShapesSelection(aList);
+ if (!myObjectTypes.isEmpty()) {
+ myObjTypeFilter = new ModuleBase_ObjectTypesFilter(myWorkshop, myObjectTypes);
+ myWorkshop->viewer()->clearSelectionFilters();
+ myWorkshop->viewer()->addSelectionFilter(myObjTypeFilter);
+ }
}
} else {
disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
- if (myUseSubShapes)
+ if (myUseSubShapes) {
+ if (!myObjTypeFilter.IsNull()) {
+ myWorkshop->viewer()->removeSelectionFilter(myObjTypeFilter);
+ myObjTypeFilter.Nullify();
+ }
myWorkshop->deactivateSubShapesSelection();
+ }
}
}
bool ModuleBase_WidgetShapeSelector::focusTo()
{
activateSelection(true);
- return true;
+ return ModuleBase_ModelWidget::focusTo();
}
//********************************************************************
dynamic_cast<ModuleBase_WidgetValueFeature*>(theValue);
if (aFeatureValue && aFeatureValue->object()) {
ObjectPtr aObject = aFeatureValue->object();
- if (isAccepted(aObject)) {
+ if (acceptObjectShape(aObject)) {
setObject(aObject);
return true;
}
#include "ModuleBase.h"
#include "ModuleBase_ModelWidget.h"
+#include "ModuleBase_ViewerFilters.h"
#include <ModelAPI_Object.h>
#include <GeomAPI_Shape.h>
#include <TopAbs_ShapeEnum.hxx>
#include <QStringList>
-#include <QPalette>
class Config_WidgetAPI;
class QWidget;
/// \param theValue the wrapped widget value
virtual bool setValue(ModuleBase_WidgetValue* theValue);
-public slots:
+ public slots:
/// Activate or deactivate selection
void activateSelection(bool toActivate);
-private slots:
+ private slots:
void onSelectionChanged();
-protected:
+ protected:
bool eventFilter(QObject* theObj, QEvent* theEvent);
-private:
void updateSelectionName();
void raisePanel() const;
- bool isAccepted(const ObjectPtr theObject) const;
- bool isAccepted(boost::shared_ptr<GeomAPI_Shape> theShape) const;
+
+ /// Returns true if shape of given object corresponds to requested shape type
+ /// This method is called only in non sub-shapes selection mode
+ virtual bool acceptObjectShape(const ObjectPtr theObject) const;
+
+ /// Returns true if selected shape corresponds to requested shape types
+ /// This method is called only in sub-shapes selection mode
+ virtual bool acceptSubShape(boost::shared_ptr<GeomAPI_Shape> theShape) const;
+
+ /// Returns true if selected object corresponds to requested Object type
+ /// Thid method is used in any selection mode
+ virtual bool acceptObjectType(const ObjectPtr theObject) const;
+
// Set the given object as a value of the widget
void setObject(ObjectPtr theObj, boost::shared_ptr<GeomAPI_Shape> theShape = boost::shared_ptr<GeomAPI_Shape>());
+ //----------- Class members -------------
+ private:
QWidget* myContainer;
QLabel* myLabel;
QLineEdit* myTextLine;
- //QToolButton* myActivateBtn;
ModuleBase_IWorkshop* myWorkshop;
boost::shared_ptr<GeomAPI_Shape> myShape;
QStringList myShapeTypes;
+ QStringList myObjectTypes;
/// If true then local selector has to be activated in context
bool myUseSubShapes;
- QPalette myBasePalet;
- QPalette myInactivePalet;
-
bool myIsActive;
+
+ Handle(ModuleBase_ObjectTypesFilter) myObjTypeFilter;
};
#endif
//******************************************************
NewGeom_Module::NewGeom_Module()
: LightApp_Module("NewGeom"),
- mySelector(0), myIsOpened(0)
+ mySelector(0), myIsOpened(0), myPopupMgr(0)
{
myWorkshop = new XGUI_Workshop(this);
myProxyViewer = new NewGeom_SalomeViewer(this);
mySelector = createSelector(OCCViewManagers.first());
}
}
- QtxPopupMgr* aMgr = popupMgr(); // Create popup manager
- action(myEraseAll)->setEnabled(false);
+ //action(myEraseAll)->setEnabled(false);
if (myIsOpened) {
myWorkshop->objectBrowser()->rebuildDataTree();
}
}
+//******************************************************
+QtxPopupMgr* NewGeom_Module::popupMgr()
+{
+ if (!myPopupMgr)
+ myPopupMgr = new QtxPopupMgr( 0, this );
+ return myPopupMgr;
+}
+
//******************************************************
void NewGeom_Module::onDefaultPreferences()
{
}
//******************************************************
-QAction* NewGeom_Module::addEditCommand(const QString& theId, const QString& theTitle,
- const QString& theTip, const QIcon& theIcon,
- const QKeySequence& theKeys, bool isCheckable)
+QAction* NewGeom_Module::addDesktopCommand(const QString& theId, const QString& theTitle,
+ const QString& theTip, const QIcon& theIcon,
+ const QKeySequence& theKeys, bool isCheckable,
+ const char* theMenuSourceText, const int theMenuPosition)
{
- int aMenu = createMenu(tr("MEN_DESK_EDIT"), -1, -1);
+ int aMenu = createMenu(tr(theMenuSourceText), -1, -1);
int aId = myActionsList.size();
myActionsList.append(theId);
QAction* aAction = createAction(aId, theTip, theIcon, theTitle, theTip, aKeys, aDesk,
isCheckable);
aAction->setData(theId);
- createMenu(aId, aMenu, 10);
+ createMenu(aId, aMenu, theMenuPosition);
return aAction;
}
//******************************************************
-void NewGeom_Module::addEditMenuSeparator()
+void NewGeom_Module::addDesktopMenuSeparator(const char* theMenuSourceText, const int theMenuPosition)
{
- int aMenu = createMenu(tr("MEN_DESK_EDIT"), -1, -1);
- createMenu(separator(), aMenu, -1, 10);
+ int aMenu = createMenu(tr(theMenuSourceText), -1, -1);
+ createMenu(separator(), aMenu, -1, theMenuPosition);
}
//******************************************************
const QKeySequence& theKeys = QKeySequence(),
bool isCheckable = false);
- virtual QAction* addEditCommand(const QString& theId, const QString& theTitle,
- const QString& theTip, const QIcon& theIcon,
- const QKeySequence& theKeys, bool isCheckable);
+ virtual QAction* addDesktopCommand(const QString& theId, const QString& theTitle,
+ const QString& theTip, const QIcon& theIcon,
+ const QKeySequence& theKeys, bool isCheckable,
+ const char* theMenuSourceText,
+ const int theMenuPosition = 10);
- virtual void addEditMenuSeparator();
+ virtual void addDesktopMenuSeparator(const char* theMenuSourceText,
+ const int theMenuPosition = 10);
virtual QMainWindow* desktop() const;
protected:
CAM_DataModel* createDataModel();
+ virtual QtxPopupMgr* popupMgr();
private:
NewGeom_OCCSelector* createSelector(SUIT_ViewManager* theMgr);
bool myIsOpened;
bool myIsStorePositions;
+ QtxPopupMgr* myPopupMgr;
};
#endif
aView3d->SetZSize(0.);
}
}
-}
\ No newline at end of file
+}
+
+//***************************************
+void NewGeom_SalomeViewer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (!aContext.IsNull()) {
+ aContext->AddFilter(theFilter);
+ }
+}
+
+//***************************************
+void NewGeom_SalomeViewer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (!aContext.IsNull()) {
+ aContext->RemoveFilter(theFilter);
+ }
+}
+
+//***************************************
+void NewGeom_SalomeViewer::clearSelectionFilters()
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (!aContext.IsNull()) {
+ aContext->RemoveFilters();
+ }
+}
void setSelector(NewGeom_OCCSelector* theSel);
+ /// Add selection filter to the viewer
+ virtual void addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter);
+
+ /// Remove selection filter from the viewer
+ virtual void removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter);
+
+ /// Remove all selection filters from the viewer
+ virtual void clearSelectionFilters();
+
NewGeom_OCCSelector* selector() const
{
return mySelector;
#include <XGUI_Constants.h>
#include <V3d_View.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS.hxx>
#include <BRep_Tool.hxx>
#ifdef _DEBUG
PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aX, anY);
} else {
ModuleBase_ViewerPrs aPrs = aSelected.first();
+ if (getViewerPoint(aPrs, theViewer, aX, anY)) {
+ ModuleBase_ModelWidget* aActiveWgt = myPropertyPanel->activeWidget();
+ PartSet_Tools::setConstraints(sketch(), feature(), aActiveWgt->attributeID(), aX, anY);
+ }
const TopoDS_Shape& aShape = aPrs.shape();
- if (!aShape.IsNull()) {
- if (aShape.ShapeType() == TopAbs_VERTEX) { // a point is selected
- const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
- if (!aVertex.IsNull()) {
- aPoint = BRep_Tool::Pnt(aVertex);
- PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aX, anY);
- ModuleBase_ModelWidget* aActiveWgt = myPropertyPanel->activeWidget();
- PartSet_Tools::setConstraints(sketch(), feature(), aActiveWgt->attributeID(), aX, anY);
- }
- } else if (aShape.ShapeType() == TopAbs_EDGE) { // a line is selected
- PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aX, anY);
- }
+ if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_EDGE) { // a line is selected
+ PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aX, anY);
}
}
ObjectPtr aFeature;
flushUpdated();
myPropertyPanel->activateNextWidget();
}
- commit();
+ // the operation can be committed only when there is no an active widget anymore
+ // if this check is absent, the edit operation for constraint perpendicular is stopped
+ // after the first object selection in the viewer(there are two objects to be selected)
+ // the second case is the constraint distance, the edit is stopped after any mouse click
+ // in the viewer whenever it is applyed or not to the selection control
+ if (!myPropertyPanel->activeWidget())
+ commit();
+}
+
+bool PartSet_OperationFeatureBase::getViewerPoint(ModuleBase_ViewerPrs thePrs,
+ ModuleBase_IViewer* theViewer,
+ double& theX, double& theY)
+{
+ return PartSet_Tools::hasVertexShape(thePrs, sketch(), theViewer->activeView(),
+ theX, theY);
}
/*bool PartSet_OperationFeatureBase::setWidgetValue(ObjectPtr theFeature, double theX, double theY)
virtual void mouseReleased(QMouseEvent* theEvent, ModuleBase_IViewer* theViewer,
ModuleBase_ISelection* theSelection);
+ protected:
+ /// Return a widget value point by the selection and the viewer position
+ /// \param thePrs the presentation
+ /// \param theViewer a viewer to have the viewer the eye position
+ /// \param theX the horizontal coordinate
+ /// \param theY the vertical coordinate
+ /// \return true if the point exits in the selection
+ virtual bool getViewerPoint(ModuleBase_ViewerPrs thePrs,
+ ModuleBase_IViewer* theViewer,
+ double& theX, double& theY);
protected:
CompositeFeaturePtr mySketch; ///< the sketch of the feature
#include <XGUI_Constants.h>
#include <V3d_View.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS.hxx>
-#include <BRep_Tool.hxx>
-#include <TopoDS.hxx>
#ifdef _DEBUG
#include <QDebug>
|| theId == SketchPlugin_ConstraintRigid::ID();
}
-bool PartSet_OperationFeatureCreate::canBeCommitted() const
-{
- if (PartSet_OperationSketchBase::canBeCommitted()) {
- //if(myActiveWidget && !myActiveWidget->isComputedDefault()) {
- return isValid();
- }
- return false;
-}
-
void PartSet_OperationFeatureCreate::mouseMoved(QMouseEvent* theEvent, ModuleBase_IViewer* theViewer)
{
double aX, anY;
PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aX, anY);
} else {
ModuleBase_ViewerPrs aPrs = aSelected.first();
+ if (getViewerPoint(aPrs, theViewer, aX, anY)) {
+ ModuleBase_ModelWidget* aActiveWgt = myPropertyPanel->activeWidget();
+ PartSet_Tools::setConstraints(sketch(), feature(), aActiveWgt->attributeID(), aX, anY);
+ isClosedContour = true;
+ }
const TopoDS_Shape& aShape = aPrs.shape();
- if (!aShape.IsNull()) {
- if (aShape.ShapeType() == TopAbs_VERTEX) { // a point is selected
- const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
- if (!aVertex.IsNull()) {
- aPoint = BRep_Tool::Pnt(aVertex);
- PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aX, anY);
- ModuleBase_ModelWidget* aActiveWgt = myPropertyPanel->activeWidget();
- PartSet_Tools::setConstraints(sketch(), feature(), aActiveWgt->attributeID(), aX, anY);
- isClosedContour = true;
- }
- } else if (aShape.ShapeType() == TopAbs_EDGE) { // a line is selected
- ObjectPtr aObject = aPrs.object();
- if (sketch()->isSub(aObject))
- PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aX, anY);
- else {
- // we have to create the selected edge for the current sketch
- ResultPtr aRes = PartSet_Tools::createFixedObjectByEdge(aPrs, sketch());
- aSelected.first().setFeature(aRes);
- }
+ if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_EDGE) { // a line is selected
+ ObjectPtr aObject = aPrs.object();
+ if (sketch()->isSub(aObject))
+ PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aX, anY);
+ else {
+ // we have to create the selected edge for the current sketch
+ ResultPtr aRes = PartSet_Tools::createFixedObjectByEdge(aPrs, sketch());
+ aSelected.first().setFeature(aRes);
}
}
}
virtual FeaturePtr createFeature(const bool theFlushMessage = true,
CompositeFeaturePtr theCompositeFeature = CompositeFeaturePtr());
- /// Verifies whether this operator can be commited.
- /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled
- virtual bool canBeCommitted() const;
-
protected:
/// Feature of previous operation (for sequintal operations)
FeaturePtr myInitFeature;
#include <SketchPlugin_Line.h>
#include <V3d_View.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS.hxx>
-#include <BRep_Tool.hxx>
#include <AIS_DimensionOwner.hxx>
#include <AIS_DimensionSelectionMode.hxx>
}
void PartSet_OperationFeatureEdit::initSelection(ModuleBase_ISelection* theSelection,
- ModuleBase_IViewer* theViewer)
+ ModuleBase_IViewer* theViewer)
{
// the method of the parent should is useless here because it processes the given
// selection in different way
//PartSet_OperationFeatureBase::initSelection(theSelection, theViewer);
- // 1. unite selected and hightlighted objects in order to have an opportunity to drag
- // by the highlighted object
- QList<ModuleBase_ViewerPrs> aFeatures = theSelection->getSelected();
+ QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected();
QList<ModuleBase_ViewerPrs> aHighlighted = theSelection->getHighlighted();
- // add highlighted elements if they are not selected
+
+ // there is a bug in OCC, where the highlighted objects are repeated and should be
+ // filtered on the unique state here
+ QList<ModuleBase_ViewerPrs> anUniqueHighlighted;
foreach (ModuleBase_ViewerPrs aPrs, aHighlighted) {
- if (!PartSet_Tools::isContainPresentation(aFeatures, aPrs))
- aFeatures.append(aPrs);
+ if (!PartSet_Tools::isContainPresentation(anUniqueHighlighted, aPrs))
+ anUniqueHighlighted.append(aPrs);
+ }
+ fillFeature2Attribute(anUniqueHighlighted, theViewer, myHighlightedFeature2Attribute);
+
+ foreach (ModuleBase_ViewerPrs aPrs, anUniqueHighlighted) {
+ if (!PartSet_Tools::isContainPresentation(aSelected, aPrs))
+ aSelected.append(aPrs);
}
+ fillFeature2Attribute(aSelected, theViewer, myAllFeature2Attribute);
+}
+void PartSet_OperationFeatureEdit::fillFeature2Attribute(
+ const QList<ModuleBase_ViewerPrs>& thePresentations,
+ ModuleBase_IViewer* theViewer,
+ std::map<FeaturePtr, std::list<std::string> >& theFeature2Attribute)
+{
// 1. find all features with skipping features with selected vertex shapes
- myFeature2Attribute.clear();
+ theFeature2Attribute.clear();
// firstly, collect the features without local selection
- foreach (ModuleBase_ViewerPrs aPrs, aFeatures) {
- const TopoDS_Shape& aShape = aPrs.shape();
- if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) { // a point is selected
- const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
- if (!aVertex.IsNull()) {
- continue;
- }
- }
+ double aX, anY;
+ foreach (ModuleBase_ViewerPrs aPrs, thePresentations) {
+ if (getViewerPoint(aPrs, theViewer, aX, anY))
+ continue;
else {
ObjectPtr aObject = aPrs.object();
if (!aObject)
continue;
FeaturePtr aFeature = ModelAPI_Feature::feature(aObject);
- if (aFeature && myFeature2Attribute.find(aFeature) == myFeature2Attribute.end()) {
+ if (aFeature && theFeature2Attribute.find(aFeature) == theFeature2Attribute.end()) {
std::list<std::string> aList;
// using an empty list as a sign, that this feature should be moved itself
- myFeature2Attribute[aFeature] = aList;
+ theFeature2Attribute[aFeature] = aList;
}
}
}
// if the list already has this feature, the local selection is skipped
// that means that if the selection contains a feature and a feature with local selected point,
// the edit is performed for a full feature
- Handle(V3d_View) aView = theViewer->activeView();
- foreach (ModuleBase_ViewerPrs aPrs, aFeatures) {
- const TopoDS_Shape& aShape = aPrs.shape();
- if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX) { // a point is selected
- const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
- if (aVertex.IsNull())
- continue;
+ foreach (ModuleBase_ViewerPrs aPrs, thePresentations) {
+ if (getViewerPoint(aPrs, theViewer, aX, anY)) {
ObjectPtr aObject = aPrs.object();
if (!aObject)
continue;
continue;
// append the attribute of the vertex if it is found on the current feature
- gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
- double aVX, aVY;
- PartSet_Tools::convertTo2D(aPoint, sketch(), aView, aVX, aVY);
boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D = PartSet_Tools::getFeaturePoint(
- aFeature, aVX, aVY);
+ aFeature, aX, anY);
std::string anAttribute = aFeature->data()->id(aPoint2D);
std::list<std::string> aList;
- if (myFeature2Attribute.find(aFeature) != myFeature2Attribute.end())
- aList = myFeature2Attribute[aFeature];
+ if (theFeature2Attribute.find(aFeature) != theFeature2Attribute.end())
+ aList = theFeature2Attribute[aFeature];
aList.push_back(anAttribute);
- myFeature2Attribute[aFeature] = aList;
+ theFeature2Attribute[aFeature] = aList;
}
}
}
if(aActiveWgt && aActiveWgt->isViewerSelector()) {
// Almost do nothing, all stuff in on PartSet_OperationFeatureBase::mouseReleased
PartSet_OperationFeatureBase::mousePressed(theEvent, theViewer, theSelection);
- return;
+ // the current point should be cleared because it is saved from the previous move and
+ // should be reinitialized after the start moving. It is important for example for the lenght
+ // constraint where the first widget is a viewer selector.
+ myCurPoint.clear();
}
else {
// commit always until the selection restore is realized (for feature and local selection)
// SketchPlugin_Feature>(feature());
bool isMoved = false;
+ bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier);
+
// the functionality to move the feature attribute if it exists in the internal map
- std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
- while (aFeatIter != myFeature2Attribute.end()) {
+ std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter, aFeatLast;
+ if (aHasShift || myHighlightedFeature2Attribute.empty()) {
+ aFeatIter = myAllFeature2Attribute.begin();
+ aFeatLast = myAllFeature2Attribute.end();
+ }
+ else {
+ aFeatIter = myHighlightedFeature2Attribute.begin();
+ aFeatLast = myHighlightedFeature2Attribute.end();
+ }
+
+ while (aFeatIter != aFeatLast) {
FeaturePtr aFeature = aFeatIter->first;
// MPV: added condition because it could be external edge of some object, not sketch
if (aFeature && !sketch()->isSub(aFeature)) {
// }
// }
//} // multieditoperation
+ sendFeatures(aHasShift);
}
- sendFeatures();
myCurPoint.setPoint(aPoint);
}
commit();
emitFeaturesDeactivation();
}
+ else if (aSelected.size() == 1) {
+ /// TODO: OCC bug: 25034 - the highlighted list should be filled not only for AIS_Shape
+ /// but for other IO, for example constraint dimensions.
+ /// It is empty and we have to use the process mouse release to start edition operation
+ /// for these objects
+ ObjectPtr anObject = aSelected.first().object();
+ FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+ if (aFeature && PartSet_Tools::isConstraintFeature(aFeature->getKind()) &&
+ aFeature != feature()) {
+ restartOperation(PartSet_OperationFeatureEdit::Type(), aFeature);
+ }
+ }
}
}
QMouseEvent* theEvent, Handle_V3d_View theView,
ModuleBase_ISelection* theSelection)
{
- myIsBlockedByDoubleClick = true;
// TODO the functionality is important only for constraint feature. Should be moved in another place
QList<ModuleBase_ViewerPrs> aSelected = theSelection->getSelected();
+ // in case when the double click happens on another constraint feature when selection control is active
+ // we should not perform the double click functionality
+ // if there is no the viewer selector widget active, the operation is restarted with a correct feature
+ ModuleBase_ModelWidget* aActiveWgt = myPropertyPanel->activeWidget();
+ if(aActiveWgt && aActiveWgt->isViewerSelector()) {
+ if (!aSelected.empty()) {
+ if (aSelected.size() == 1) {
+ /// TODO: OCC bug: 25034 - the highlighted list should be filled not only for AIS_Shape
+ /// but for other IO, for example constraint dimensions.
+ /// It is empty and we have to use the process mouse release to start edition operation
+ /// for these objects
+ ObjectPtr anObject = aSelected.first().object();
+ FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+ if (aFeature && PartSet_Tools::isConstraintFeature(aFeature->getKind()) &&
+ aFeature != feature()) {
+ return;
+ }
+ }
+ }
+ }
+
+ myIsBlockedByDoubleClick = true;
if (!aSelected.empty()) {
ModuleBase_ViewerPrs aFeaturePrs = aSelected.first();
if (!aFeaturePrs.owner().IsNull()) {
//blockSelection(false, false);
- myFeature2Attribute.clear();
+ myHighlightedFeature2Attribute.clear();
+ myAllFeature2Attribute.clear();
}
//void PartSet_OperationFeatureEdit::blockSelection(bool isBlocked, const bool isRestoreSelection)
return FeaturePtr();
}
-void PartSet_OperationFeatureEdit::sendFeatures()
+void PartSet_OperationFeatureEdit::sendFeatures(const bool theIsAllFeatures)
{
static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);
- std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
- while (aFeatIter != myFeature2Attribute.end()) {
+ std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter, aFeatLast;
+ if (theIsAllFeatures || myHighlightedFeature2Attribute.empty()) {
+ aFeatIter = myAllFeature2Attribute.begin();
+ aFeatLast = myAllFeature2Attribute.end();
+ }
+ else {
+ aFeatIter = myHighlightedFeature2Attribute.begin();
+ aFeatLast = myHighlightedFeature2Attribute.end();
+ }
+ while (aFeatIter != aFeatLast) {
FeaturePtr aFeature = aFeatIter->first;
if (aFeature) {
ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent);
void PartSet_OperationFeatureEdit::emitFeaturesDeactivation()
{
- std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myFeature2Attribute.begin();
- while (aFeatIter != myFeature2Attribute.end()) {
+ std::map<FeaturePtr, std::list<std::string>>::iterator aFeatIter = myAllFeature2Attribute.begin();
+ while (aFeatIter != myAllFeature2Attribute.end()) {
FeaturePtr aFeature = aFeatIter->first;
if (aFeature) {
emit featureConstructed(aFeature, FM_Deactivation);
CompositeFeaturePtr theCompositeFeature = CompositeFeaturePtr());
protected:
+ void fillFeature2Attribute(const QList<ModuleBase_ViewerPrs>& thePresentations,
+ ModuleBase_IViewer* theViewer,
+ std::map<FeaturePtr, std::list<std::string> >& theFeature2Attribute);
+
/// Emits a signal about the selection blocking. Emits a signal to change the selection.
/// If the block is true, the signal clear selection, otherwise if restore selection flag allows,
/// the internal operation features are to be selected
//void blockSelection(bool isBlocked, const bool isRestoreSelection = true);
/// Sends the features
- void sendFeatures();
+ /// \param theIsAllFeatures a boolean value whether all features should be send or only the highlighted ones
+ void sendFeatures(const bool theIsAllFeatures);
/// Sends signal about the current features are to be deactivated
void emitFeaturesDeactivation();
private:
// the next map should be removed when selection is processed in the move function
- std::map<FeaturePtr, std::list<std::string> > myFeature2Attribute; /// a map of a feature to attributes
+ std::map<FeaturePtr, std::list<std::string> > myHighlightedFeature2Attribute; /// a map of a feature to attributes
+ std::map<FeaturePtr, std::list<std::string> > myAllFeature2Attribute; /// a map of a feature to attributes
Point myCurPoint; ///< the current 3D point clicked or moved
bool myIsBlockedSelection; ///< the state of the last state of selection blocked signal
// Turn viewer to the plane
emit planeSelected(aDir->x(), aDir->y(), aDir->z());
}
+ emit updatePropPanel();
emit launchSketch();
}
}
/// Signal to define sketch mode
void launchSketch();
+ /// Signal to update property panel
+ void updatePropPanel();
+
protected:
/// Virtual method called when operation started (see start() method for more description)
/// Default impl calls corresponding slot and commits immediately.
#include <BRep_Tool.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
#ifdef _DEBUG
#include <QDebug>
FeaturePtr theSketch,
const QList<ModuleBase_ViewerPrs>& theSelected,
const QList<ModuleBase_ViewerPrs>& theHighlighted)
+{
+ // firstly it finds the feature in the list of highlight
+ ObjectPtr aDeltaObject = nearestFeature(thePoint, theView, theSketch, theHighlighted);
+ if (!aDeltaObject)
+ // secondly it finds the feature in the list of selected objects
+ aDeltaObject = nearestFeature(thePoint, theView, theSketch, theSelected);
+
+ return aDeltaObject;
+}
+
+ObjectPtr PartSet_Tools::nearestFeature(QPoint thePoint, Handle_V3d_View theView,
+ FeaturePtr theSketch,
+ const QList<ModuleBase_ViewerPrs>& thePresentations)
{
ObjectPtr aDeltaObject;
- // 1. find the object in the highlighted list
- if (theHighlighted.size() > 0) {
- aDeltaObject = theHighlighted.first().object();
- }
- // 2. find it in the selected list by the selected point
+
+ CompositeFeaturePtr aSketch =
+ boost::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theSketch);
+ // 1. find it in the selected list by the selected point
if (!aDeltaObject) {
double aX, anY;
gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(thePoint, theView);
FeaturePtr aFeature;
double aMinDelta = -1;
ModuleBase_ViewerPrs aPrs;
- foreach (ModuleBase_ViewerPrs aPrs, theSelected) {
+ foreach (ModuleBase_ViewerPrs aPrs, thePresentations) {
if (!aPrs.object())
continue;
FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs.object());
boost::shared_ptr<SketchPlugin_Feature> aSketchFeature = boost::dynamic_pointer_cast<
SketchPlugin_Feature>(aFeature);
- if (!aSketchFeature)
+ if (!aSketchFeature || !aSketch->isSub(aSketchFeature))
continue;
double aDelta = aSketchFeature->distanceToPoint(
}
}
}
- // 3. if the object is not found, returns the first selected one
- if (!aDeltaObject && theSelected.size() > 0)
- aDeltaObject = theSelected.first().object();
-
+ // 2. if the object is not found, returns the first selected sketch feature
+ if (!aDeltaObject && thePresentations.size() > 0) {
+ // there can be some highlighted objects, e.g. a result of boolean operation and a sketch point
+ foreach (ModuleBase_ViewerPrs aPrs, thePresentations) {
+ if (!aPrs.object())
+ continue;
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aPrs.object());
+ if (aFeature && aSketch->isSub(aFeature))
+ aDeltaObject = aPrs.object();
+ }
+ }
return aDeltaObject;
}
}
}
return ResultPtr();
-}
\ No newline at end of file
+}
+
+bool PartSet_Tools::hasVertexShape(const ModuleBase_ViewerPrs& thePrs, FeaturePtr theSketch,
+ Handle_V3d_View theView, double& theX, double& theY)
+{
+ bool aHasVertex = false;
+
+ const TopoDS_Shape& aShape = thePrs.shape();
+ if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_VERTEX)
+ {
+ const TopoDS_Vertex& aVertex = TopoDS::Vertex(aShape);
+ if (!aVertex.IsNull())
+ {
+ gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
+ PartSet_Tools::convertTo2D(aPoint, theSketch, theView, theX, theY);
+ aHasVertex = true;
+ }
+ }
+
+ return aHasVertex;
+}
/// \param theEdge - the edge
/// \return result object with external edge if it is found
static ResultPtr findExternalEdge(CompositeFeaturePtr theSketch, boost::shared_ptr<GeomAPI_Edge> theEdge);
+
+ /// Returns whether the selected presentation has a shape with the vertex type
+ /// \param thePrs a selected presentation
+ /// \param theSketch the sketch feature
+ /// \param theView a 3D view
+ /// \param theX the output horizontal coordinate of the point
+ /// \param theY the output vertical coordinate of the point
+ static bool hasVertexShape(const ModuleBase_ViewerPrs& thePrs, FeaturePtr theSketch,
+ Handle_V3d_View theView, double& theX, double& theY);
+protected:
+ /// Returns an object that is under the mouse point. Firstly it checks the highlighting,
+ /// if it exists, the first object is returned. Secondly, there is an iteration on
+ /// the selected list to find the point. Thirdly, if the object is not found under the
+ /// the point, the first selected object is returned.
+ /// \param thePoint a screen point
+ /// \param theView a 3D view
+ /// \param theSketch the sketch feature
+ /// \param thePresentations the list of presentations
+ static ObjectPtr nearestFeature(QPoint thePoint, Handle_V3d_View theView, FeaturePtr theSketch,
+ const QList<ModuleBase_ViewerPrs>& thePresentations);
+
};
#endif
QList<QWidget*> PartSet_WidgetSketchLabel::getControls() const
{
- QList<QWidget*> aLst;
- aLst << myLabel;
- return aLst;
+ return QList<QWidget*>();
}
QWidget* PartSet_WidgetSketchLabel::getControl() const
if (aOperation->inherits("PartSet_OperationSketch")) {
PartSet_OperationSketch* aSketchOpe = static_cast<PartSet_OperationSketch*>(aOperation);
updateLabel(aSketchOpe);
- connect(aSketchOpe, SIGNAL(planeSelected(double, double, double)), this,
+ connect(aSketchOpe, SIGNAL(updatePropPanel()), this,
SLOT(onPlaneSelected()));
}
}
virtual ~PartSet_WidgetSketchLabel()
{
}
- ;
/// Saves the internal parameters to the given feature
/// \param theFeature a model feature to be changed
boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(data()->attribute(RADIUS_ID()));
if (aCenterAttr->isInitialized() && aRadiusAttr->isInitialized()) {
boost::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
+ //std::cout<<"Execute circle "<<aCenter->x()<<" "<<aCenter->y()<<" "<<aCenter->z()<<std::endl;
// make a visible point
boost::shared_ptr<GeomAPI_Shape> aCenterPointShape = GeomAlgoAPI_PointBuilder::point(aCenter);
boost::shared_ptr<ModelAPI_ResultConstruction> aConstr1 = document()->createConstruction(
void SketchPlugin_Circle::attributeChanged() {
static bool myIsUpdated = false; // to avoid infinitive cycle on attrubtes change
boost::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
- if (aSelection && !myIsUpdated) { // update arguments due to the selection value
+ // update arguments due to the selection value
+ if (aSelection && !aSelection->isNull() && aSelection->isEdge() && !myIsUpdated) {
myIsUpdated = true;
boost::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
boost::shared_ptr<GeomAPI_Circ> aCirc = anEdge->circle();
if(anAttrValue->isInitialized())
return;
- boost::shared_ptr<GeomDataAPI_Point2D> aPointA =
- getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_A());
- boost::shared_ptr<GeomDataAPI_Point2D> aPointB =
- getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_B());
- double aDistance = -1.;
- if (aPointA && aPointB) { // both points
- aDistance = aPointA->pnt()->distance(aPointB->pnt());
- } else {
- if (!aPointA && aPointB) { //Line and point
- boost::shared_ptr<SketchPlugin_Line> aLine =
- getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A());
- if (aLine) {
- aDistance = aLine->distanceToPoint(aPointB->pnt());
- }
- } else if (aPointA && !aPointB) { // Point and line
- boost::shared_ptr<SketchPlugin_Line> aLine =
- getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B());
- if (aLine) {
- aDistance = aLine->distanceToPoint(aPointA->pnt());
- }
- }
- }
+ double aDistance = calculateCurrentDistance();
if(aDistance >= 0) {
anAttrValue->setValue(aDistance);
}
boost::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = boost::dynamic_pointer_cast<
ModelAPI_AttributeDouble>(aData->attribute(SketchPlugin_Constraint::VALUE()));
double aValue = aValueAttr->value();
+ // Issue #196: checking the positivity of the distance constraint
+ // there is a validator for a distance constraint, that the value should be positive
+ // in case if an invalid value is set, the current distance value is shown
+ if (aValue <= 0)
+ aValue = calculateCurrentDistance();
AISObjectPtr anAIS = thePrevious;
if (!anAIS)
aPoint->move(theDeltaX, theDeltaY);
}
+double SketchPlugin_ConstraintDistance::calculateCurrentDistance() const
+{
+ double aDistance = -1.;
+
+ boost::shared_ptr<ModelAPI_Data> aData = data();
+ boost::shared_ptr<GeomDataAPI_Point2D> aPointA =
+ getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_A());
+ boost::shared_ptr<GeomDataAPI_Point2D> aPointB =
+ getFeaturePoint(aData, SketchPlugin_Constraint::ENTITY_B());
+
+ if (aPointA && aPointB) { // both points
+ aDistance = aPointA->pnt()->distance(aPointB->pnt());
+ } else {
+ if (!aPointA && aPointB) { //Line and point
+ boost::shared_ptr<SketchPlugin_Line> aLine =
+ getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_A());
+ if (aLine) {
+ aDistance = aLine->distanceToPoint(aPointB->pnt());
+ }
+ } else if (aPointA && !aPointB) { // Point and line
+ boost::shared_ptr<SketchPlugin_Line> aLine =
+ getFeatureLine(aData, SketchPlugin_Constraint::ENTITY_B());
+ if (aLine) {
+ aDistance = aLine->distanceToPoint(aPointA->pnt());
+ }
+ }
+ }
+ return aDistance;
+}
+
+
//*************************************************************************************
boost::shared_ptr<GeomDataAPI_Point2D> getFeaturePoint(DataPtr theData,
const std::string& theAttribute)
/// \param theDeltaY the delta for Y coordinate is moved
SKETCHPLUGIN_EXPORT virtual void move(const double theDeltaX, const double theDeltaY);
+ /// Returns the current distance between the feature attributes
+ double calculateCurrentDistance() const;
+
/// \brief Use plugin manager for features creation
SketchPlugin_ConstraintDistance();
};
if (aStartAttr->isInitialized() && anEndAttr->isInitialized()) {
boost::shared_ptr<GeomAPI_Pnt> aStart(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
boost::shared_ptr<GeomAPI_Pnt> anEnd(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
+ //std::cout<<"Execute line "<<aStart->x()<<" "<<aStart->y()<<" "<<aStart->z()<<" - "
+ // <<anEnd->x()<<" "<<anEnd->y()<<" "<<anEnd->z()<<std::endl;
// make linear edge
boost::shared_ptr<GeomAPI_Edge> anEdge = GeomAlgoAPI_EdgeBuilder::line(aStart, anEnd);
// store the result
static bool myIsUpdated = false; // to avoid infinitive cycle on attrubtes change
boost::shared_ptr<GeomAPI_Shape> aSelection = data()->selection(EXTERNAL_ID())->value();
// update arguments due to the selection value
- if (aSelection && !aSelection->isNull() && !myIsUpdated) {
+ if (aSelection && !aSelection->isNull() && aSelection->isEdge() && !myIsUpdated) {
myIsUpdated = true;
boost::shared_ptr<GeomAPI_Edge> anEdge( new GeomAPI_Edge(aSelection));
boost::shared_ptr<GeomDataAPI_Point2D> aStartAttr =
for (; anIt != aLast; anIt++) {
aFeature = boost::dynamic_pointer_cast<SketchPlugin_Feature>(*anIt);
if (aFeature) {
+ if (!aFeature->sketch()) // on load document the back references are missed
+ aFeature->setSketch(this);
// do not include the external edges into the result
if (aFeature->data()->attribute(SketchPlugin_Feature::EXTERNAL_ID())) {
if (aFeature->data()->selection(SketchPlugin_Feature::EXTERNAL_ID())->value())
boost::shared_ptr<GeomAPI_Dir> aDir = aPlane->direction();
if (kIsAttrChanged) {
+ /* now it is in updater
// the plane was changed, so reexecute sub-elements to update shapes (located in new plane)
ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
list<ObjectPtr> aSubs = data()->reflist(SketchPlugin_Sketch::FEATURES_ID())->list();
aFeature->execute();
}
}
+ */
kIsAttrChanged = false;
}
}
deltaX = deltaY = 40.
# move line
aSession.startOperation()
-aLineStartPoint.setValue(aLineStartPoint.x() + deltaX,
+anArcStartPoint.setValue(aLineStartPoint.x() + deltaX,
aLineStartPoint.y() + deltaY)
-aLineEndPoint.setValue(aLineEndPoint.x() + deltaX,
+anArcEndPoint.setValue(aLineEndPoint.x() + deltaX,
aLineEndPoint.y() + deltaY)
aSession.finishOperation()
# check that arc's points are moved also
if (isEmpty())
return true;
+ // Check if the feature is already in the group
+ if (myEntityFeatMap.find(theFeature) != myEntityFeatMap.end())
+ return true;
+ boost::shared_ptr<SketchPlugin_Constraint> aConstr =
+ boost::dynamic_pointer_cast<SketchPlugin_Constraint>(theFeature);
+ if (aConstr && myConstraintMap.find(aConstr) != myConstraintMap.end())
+ return true;
+
// Go through the attributes and verify if some of them already in the group
std::list<boost::shared_ptr<ModelAPI_Attribute>>
anAttrList = theFeature->data()->attributes(std::string());
theConstraint->data()->attribute(SketchPlugin_Constraint::VALUE()));
if (aDistAttr) {
aDistance = aDistAttr->value();
+ // Issue #196: checking the positivity of the distance constraint
+ if (aDistance < tolerance &&
+ (aConstrType == SLVS_C_PT_PT_DISTANCE || aConstrType == SLVS_C_PT_LINE_DISTANCE))
+ return false;
// SketchPlugin circle defined by its radius, but SolveSpace uses constraint for diameter
if (aConstrType == SLVS_C_DIAMETER)
aDistance *= 2.0;
isFound = (aGrEntIter->find(aConstrEnt[i]) != aGrEntIter->end());
// Also we need to check sub-entities
int aEntPos = Search(aConstrEnt[i], myEntities);
- Slvs_hEntity* aSub = myEntities[aEntPos].point;
- for (int j = 0; *aSub != 0 && j < 4 && !isFound; aSub++, j++)
- isFound = (aGrEntIter->find(*aSub) != aGrEntIter->end());
+ if (aEntPos != myEntities.size()) { // MPV: to fix the crash on close
+ Slvs_hEntity* aSub = myEntities[aEntPos].point;
+ for (int j = 0; *aSub != 0 && j < 4 && !isFound; aSub++, j++)
+ isFound = (aGrEntIter->find(*aSub) != aGrEntIter->end());
+ }
}
if (isFound)
anIndexes.push_back(aGrEntIter - aGroupsEntities.begin());
if (aConstrEnt[i] != 0) {
aNewGrEnt.insert(aConstrEnt[i]);
int aEntPos = Search(aConstrEnt[i], myEntities);
- Slvs_hEntity* aSub = myEntities[aEntPos].point;
- for (int j = 0; *aSub != 0 && j < 4; aSub++, j++)
- aNewGrEnt.insert(*aSub);
+ if (aEntPos != myEntities.size()) { // MPV: to fix the crash on close
+ Slvs_hEntity* aSub = myEntities[aEntPos].point;
+ for (int j = 0; *aSub != 0 && j < 4; aSub++, j++)
+ aNewGrEnt.insert(*aSub);
+ }
}
std::set<Slvs_hConstraint> aNewGrConstr;
aNewGrConstr.insert(aConstrIter->h);
if (aConstrEnt[i] != 0) {
aGrEntIter->insert(aConstrEnt[i]);
int aEntPos = Search(aConstrEnt[i], myEntities);
- Slvs_hEntity* aSub = myEntities[aEntPos].point;
- for (int j = 0; *aSub != 0 && j < 4; aSub++, j++)
- aGrEntIter->insert(*aSub);
+ if (aEntPos != myEntities.size()) { // MPV: to fix the crash on close
+ Slvs_hEntity* aSub = myEntities[aEntPos].point;
+ for (int j = 0; *aSub != 0 && j < 4; aSub++, j++)
+ aGrEntIter->insert(*aSub);
+ }
}
aGroupsConstr[anIndexes.front()].insert(aConstrIter->h);
if (aGrEntIter->size() > aGroupsEntities[aMaxNbEntities].size())
}
} else {
std::set<ObjectPtr>::iterator aFeatIter;
+ // iterate sketchers fisrt to create all sketches before (on load may exist several sketches)
for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) {
FeaturePtr aFeature = boost::dynamic_pointer_cast<ModelAPI_Feature>(*aFeatIter);
if (!aFeature)
continue;
- // Only sketches and constraints can be added by Create event
const std::string& aFeatureKind = aFeature->getKind();
if (aFeatureKind.compare(SketchPlugin_Sketch::ID()) == 0) {
boost::shared_ptr<ModelAPI_CompositeFeature> aSketch = boost::dynamic_pointer_cast<
ModelAPI_CompositeFeature>(aFeature);
- if (aSketch)
- changeWorkplane(aSketch);
- continue;
+ changeWorkplane(aSketch);
}
- // Sketch plugin features can be only updated
- boost::shared_ptr<SketchPlugin_Feature> aSFeature = boost::dynamic_pointer_cast<
- SketchPlugin_Feature>(aFeature);
- if (aSFeature)
- changeConstraintOrEntity(aSFeature);
+ }
+ // then get anything but not the sketch
+ for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) {
+ boost::shared_ptr<SketchPlugin_Feature> aFeature =
+ boost::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
+ if (!aFeature)
+ continue;
+ changeConstraintOrEntity(aFeature);
}
}
XGUI_Displayer* aDisplayer = myWorkshop->displayer();
bool hasResult = false;
bool hasFeature = false;
- bool hasGroup = false;
foreach(ObjectPtr aObj, aObjects)
{
FeaturePtr aFeature = boost::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(aObj);
- ResultGroupPtr aGroupRes = boost::dynamic_pointer_cast<ModelAPI_ResultGroup>(aObj);
if (aResult)
hasResult = true;
if (aFeature)
hasFeature = true;
- if (aGroupRes)
- hasGroup = true;
- if (hasFeature && hasResult && hasGroup)
+ if (hasFeature && hasResult) // && hasGroup)
break;
}
//Process Feature
- if (!hasGroup) {
- if (aSelected == 1) {
- ObjectPtr aObject = aObjects.first();
- if (aObject) {
- ResultPartPtr aPart = boost::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
- if (aPart) {
- if (aMgr->activeDocument() == aPart->partDoc())
- aMenu->addAction(action("DEACTIVATE_PART_CMD"));
+ if (aSelected == 1) {
+ ObjectPtr aObject = aObjects.first();
+ if (aObject) {
+ ResultPartPtr aPart = boost::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
+ if (aPart) {
+ if (aMgr->activeDocument() == aPart->partDoc())
+ aMenu->addAction(action("DEACTIVATE_PART_CMD"));
+ else
+ aMenu->addAction(action("ACTIVATE_PART_CMD"));
+ } else if (hasFeature) {
+ aMenu->addAction(action("EDIT_CMD"));
+ } else {
+ if (aDisplayer->isVisible(aObject)) {
+ if (aDisplayer->displayMode(aObject) == XGUI_Displayer::Shading)
+ aMenu->addAction(action("WIREFRAME_CMD"));
else
- aMenu->addAction(action("ACTIVATE_PART_CMD"));
- } else if (hasFeature) {
- aMenu->addAction(action("EDIT_CMD"));
+ aMenu->addAction(action("SHADING_CMD"));
+ aMenu->addSeparator();
+ aMenu->addAction(action("HIDE_CMD"));
} else {
- if (aDisplayer->isVisible(aObject)) {
- if (aDisplayer->displayMode(aObject) == XGUI_Displayer::Shading)
- aMenu->addAction(action("WIREFRAME_CMD"));
- else
- aMenu->addAction(action("SHADING_CMD"));
- aMenu->addSeparator();
- aMenu->addAction(action("HIDE_CMD"));
- } else {
- aMenu->addAction(action("SHOW_CMD"));
- }
- aMenu->addAction(action("SHOW_ONLY_CMD"));
+ aMenu->addAction(action("SHOW_CMD"));
}
- } else { // If feature is 0 the it means that selected root object (document)
- if (aMgr->activeDocument() != aMgr->moduleDocument())
- aMenu->addAction(action("ACTIVATE_PART_CMD"));
- }
- } else {
- if (hasResult) {
- aMenu->addAction(action("SHOW_CMD"));
- aMenu->addAction(action("HIDE_CMD"));
aMenu->addAction(action("SHOW_ONLY_CMD"));
- aMenu->addSeparator();
- aMenu->addAction(action("SHADING_CMD"));
- aMenu->addAction(action("WIREFRAME_CMD"));
}
+ } else { // If feature is 0 the it means that selected root object (document)
+ if (aMgr->activeDocument() != aMgr->moduleDocument())
+ aMenu->addAction(action("ACTIVATE_PART_CMD"));
+ }
+ } else {
+ if (hasResult) {
+ aMenu->addAction(action("SHOW_CMD"));
+ aMenu->addAction(action("HIDE_CMD"));
+ aMenu->addAction(action("SHOW_ONLY_CMD"));
+ aMenu->addSeparator();
+ aMenu->addAction(action("SHADING_CMD"));
+ aMenu->addAction(action("WIREFRAME_CMD"));
}
- if (hasFeature)
- aMenu->addAction(action("DELETE_CMD"));
}
+ if (hasFeature)
+ aMenu->addAction(action("DELETE_CMD"));
}
aMenu->addSeparator();
aMenu->addActions(myWorkshop->objectBrowser()->actions());
if (aDoc == aRootDoc) { // If root objects
if (aGroup == ModelAPI_ResultPart::group()) { // Update only Parts group
int aStart = myPartModels.size() - 1;
- removeSubModel(aStart);
- removeRow(aStart, partFolderNode());
- if (myActivePart && (!isPartSubModel(myActivePart))) {
- myActivePart = 0;
- myActivePartIndex = QModelIndex();
- myModel->setItemsColor(ACTIVE_COLOR);
+ if (aStart >= 0) {// MPV: this could be reproduced on close
+ 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);
DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), myId);
ResultPartPtr aPart = boost::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
- return aPart->partDoc();
+ if (aPart)
+ return aPart->partDoc();
+ return DocumentPtr(); // null if not found
}
ObjectPtr XGUI_PartDataModel::object(const QModelIndex& theIndex) const
//! \param theIcon - icon
//! \param isCheckable - is checkable or not
//! \param theKeys - hot keys
+ //! \param theMenuSourceText - a source text of the desktop menu
+ //! \param theMenuPosition - a position of the command in the desktop menu
//! returns created action
- virtual QAction* addEditCommand(const QString& theId, const QString& theTitle,
- const QString& theTip, const QIcon& theIcon,
- const QKeySequence& theKeys, bool isCheckable) = 0;
+ virtual QAction* addDesktopCommand(const QString& theId, const QString& theTitle,
+ const QString& theTip, const QIcon& theIcon,
+ const QKeySequence& theKeys, bool isCheckable,
+ const char* theMenuSourceText,
+ const int theMenuPosition = 10) = 0;
//! Insert separator into Edit menu of SALOME desktop
- virtual void addEditMenuSeparator() = 0;
+ virtual void addDesktopMenuSeparator(const char* theMenuSourceText,
+ const int theMenuPosition = 10) = 0;
//! Returns desktop window of SALOME
virtual QMainWindow* desktop() const = 0;
if (!aShape.IsNull()) {
theList.Append(aShape);
Handle(SelectMgr_EntityOwner) aEO = aContext->SelectedOwner();
- Handle(AIS_InteractiveObject) anObj =
- Handle(AIS_InteractiveObject)::DownCast(aEO->Selectable());
- ObjectPtr anObject = myWorkshop->displayer()->getObject(anObj);
- theOwners.push_back(anObject);
+ if (!aEO.IsNull()) {
+ Handle(AIS_InteractiveObject) anObj =
+ Handle(AIS_InteractiveObject)::DownCast(aEO->Selectable());
+ ObjectPtr anObject = myWorkshop->displayer()->getObject(anObj);
+ theOwners.push_back(anObject);
+ }
}
}
}
SIGNAL(keyPress(XGUI_ViewWindow*, QKeyEvent*)));
connect(aWindow, SIGNAL(keyReleased(XGUI_ViewWindow*, QKeyEvent*)), this,
- SIGNAL(keyRelease(XGUI_ViewWindow*, QKeyEvent*)));
+ SLOT(onKeyRelease(XGUI_ViewWindow*, QKeyEvent*)));
//connect(aWindow, SIGNAL(contextMenuRequested( QContextMenuEvent* )),
// this, SLOT (onContextMenuRequested( QContextMenuEvent* )));
Handle(V3d_View) aView3d = theWindow->viewPort()->getView();
if (!aView3d.IsNull()) {
myAISContext->MoveTo(theEvent->x(), theEvent->y(), aView3d);
+ if (myAISContext->HasDetected())
+ theWindow->viewPort()->setFocus(Qt::MouseFocusReason);
}
}
}
}
+//******************************************************
+void XGUI_Viewer::onKeyRelease(XGUI_ViewWindow* theView, QKeyEvent* theKey)
+{
+ Handle(V3d_View) aView = theView->viewPort()->getView();
+ bool noModifiers = (theKey->modifiers() == Qt::NoModifier);
+ if ((theKey->key() == Qt::Key_N) && noModifiers) {
+ myAISContext->HilightNextDetected(aView);
+ } else if ((theKey->key() == Qt::Key_P) && noModifiers) {
+ myAISContext->HilightPreviousDetected(aView);
+ } else {
+ emit keyRelease(theView, theKey);
+ }
+}
+
//******************************************************
//void XGUI_Viewer::onContextMenuRequested(QContextMenuEvent* theEvent)
//{
void onMousePressed(XGUI_ViewWindow* theWindow, QMouseEvent* theEvent);
//void onContextMenuRequested(QContextMenuEvent* theEvent);
+ void onKeyRelease(XGUI_ViewWindow* theView, QKeyEvent* theKey);
+
private:
void addView(QMdiSubWindow* theView);
private:
XGUI_MainWindow* myMainWindow;
- Handle(V3d_Viewer) myV3dViewer;Handle(AIS_Trihedron) myTrihedron;Handle(AIS_InteractiveContext) myAISContext;
+ Handle(V3d_Viewer) myV3dViewer;
+ Handle(AIS_Trihedron) myTrihedron;
+ Handle(AIS_InteractiveContext) myAISContext;
XGUI::InteractionStyle myInteractionStyle;
return myWorkshop->mainWindow()->viewer()->isMultiSelectionEnabled();
}
}
+
+//***************************************
+void XGUI_ViewerProxy::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (!aContext.IsNull()) {
+ aContext->AddFilter(theFilter);
+ }
+}
+
+//***************************************
+void XGUI_ViewerProxy::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (!aContext.IsNull()) {
+ aContext->RemoveFilter(theFilter);
+ }
+}
+
+//***************************************
+void XGUI_ViewerProxy::clearSelectionFilters()
+{
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ if (!aContext.IsNull()) {
+ aContext->RemoveFilters();
+ }
+}
/// Connects to a viewer according to current environment
void connectToViewer();
+ /// Add selection filter to the viewer
+ virtual void addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter);
+
+ /// Remove selection filter from the viewer
+ virtual void removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter);
+
+ /// Remove all selection filters from the viewer
+ virtual void clearSelectionFilters();
+
private slots:
void onMousePress(XGUI_ViewWindow*, QMouseEvent*);
void onMouseRelease(XGUI_ViewWindow*, QMouseEvent*);
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(ModuleBase_Operation*)), myActionsMgr,
- SLOT(update()));
+ // TODO(sbh): It seems that application works properly without update on operationStarted
+ connect(myOperationMgr, SIGNAL(operationStarted(ModuleBase_Operation*)),
+ myActionsMgr, SLOT(update()));
+ connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)),
+ myActionsMgr, SLOT(update()));
connect(this, SIGNAL(errorOccurred(const QString&)), myErrorDlg, SLOT(addError(const QString&)));
}
if (isSalomeMode()) {
// Create only Undo, Redo commands
- QAction* aAction = salomeConnector()->addEditCommand("UNDO_CMD", tr("Undo"),
+ QAction* aAction = salomeConnector()->addDesktopCommand("UNDO_CMD", tr("Undo"),
tr("Undo last command"),
QIcon(":pictures/undo.png"),
- QKeySequence::Undo, false);
+ QKeySequence::Undo, false, "MEN_DESK_EDIT");
connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onUndo()));
- aAction = salomeConnector()->addEditCommand("REDO_CMD", tr("Redo"), tr("Redo last command"),
+ aAction = salomeConnector()->addDesktopCommand("REDO_CMD", tr("Redo"), tr("Redo last command"),
QIcon(":pictures/redo.png"), QKeySequence::Redo,
- false);
+ false, "MEN_DESK_EDIT");
connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRedo()));
- salomeConnector()->addEditMenuSeparator();
- aAction = salomeConnector()->addEditCommand("REBUILD_CMD", tr("Rebuild"), tr("Rebuild data objects"),
+ salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT");
+ aAction = salomeConnector()->addDesktopCommand("REBUILD_CMD", tr("Rebuild"), tr("Rebuild data objects"),
QIcon(":pictures/rebuild.png"), QKeySequence(),
- false);
+ false, "MEN_DESK_EDIT");
connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onRebuild()));
- salomeConnector()->addEditMenuSeparator();
+ salomeConnector()->addDesktopMenuSeparator("MEN_DESK_EDIT");
+
+ aAction = salomeConnector()->addDesktopCommand("SAVEAS_CMD", tr("Export NewGeom..."), tr("Export the current document into a NewGeom file"),
+ QIcon(), QKeySequence(),
+ false, "MEN_DESK_FILE");
+ connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onSaveAs()));
+
+ aAction = salomeConnector()->addDesktopCommand("OPEN_CMD", tr("Import NewGeom..."), tr("Import a NewGeom file"),
+ QIcon(), QKeySequence(),
+ false, "MEN_DESK_FILE");
+ connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onOpen()));
+ salomeConnector()->addDesktopMenuSeparator("MEN_DESK_FILE");
+
return;
}
// File commands group
} else if (anAnswer == QMessageBox::Cancel) {
return;
}
- aSession->moduleDocument()->close();
+ aSession->closeAll();
myCurrentDir = "";
}
std::list<std::string> aFiles;
saveDocument(myCurrentDir, aFiles);
updateCommandStatus();
- myMainWindow->setModifiedState(false);
+ if (!isSalomeMode())
+ myMainWindow->setModifiedState(false);
return true;
}
}
SessionPtr aMgr = ModelAPI_Session::get();
if (aMgr->hasModuleDocument()) {
- QAction* aUndoCmd;
- QAction* aRedoCmd;
+ QAction *aUndoCmd, *aRedoCmd;
foreach(QAction* aCmd, aCommands) {
QString aId = aCmd->data().toString();
if (aId == "UNDO_CMD")
// Enable all commands
aCmd->setEnabled(true);
}
- aUndoCmd->setEnabled(aMgr->canUndo());
- aRedoCmd->setEnabled(aMgr->canRedo());
+ aUndoCmd->setEnabled(aMgr->canUndo() && !aMgr->isOperation());
+ aRedoCmd->setEnabled(aMgr->canRedo() && !aMgr->isOperation());
} else {
foreach(QAction* aCmd, aCommands) {
QString aId = aCmd->data().toString();
objectBrowser()->clearContent();
SessionPtr aMgr = ModelAPI_Session::get();
- aMgr->moduleDocument()->close();
+ aMgr->closeAll();
objectBrowser()->clearContent();
}