X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModel%2FModel_ResultPart.cpp;h=431576afbacd1cd57096b850b45cfa445ec24f25;hb=f74f5e57b4c647e061575929334db69c0f4fc8e2;hp=a54ca670999c64d005f81c59f45d2a4712baf07e;hpb=a731f82dccbfdb67cbf8e8d617222a4d3e32018a;p=modules%2Fshaper.git diff --git a/src/Model/Model_ResultPart.cpp b/src/Model/Model_ResultPart.cpp index a54ca6709..431576afb 100644 --- a/src/Model/Model_ResultPart.cpp +++ b/src/Model/Model_ResultPart.cpp @@ -6,49 +6,328 @@ #include #include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include -std::shared_ptr Model_ResultPart::partDoc() +#include +#include +#include +#include +#include +#include +#include + +#define baseRef() std::dynamic_pointer_cast(data()->reference(BASE_REF_ID())->value()) + +void Model_ResultPart::initAttributes() { - return data()->document("PartDocument")->value(); + // append the color attribute. It is empty, the attribute will be filled by a request + data()->addAttribute(DOC_REF(), ModelAPI_AttributeDocRef::typeId()); + data()->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId()); + data()->addAttribute(BASE_REF_ID(), ModelAPI_AttributeReference::typeId()); } -std::shared_ptr Model_ResultPart::owner() +std::shared_ptr Model_ResultPart::partDoc() { - return std::shared_ptr(); // return empty pointer + if (myTrsf.get()) { + return baseRef()->partDoc(); + } + DocumentPtr aRes = data()->document(DOC_REF())->value(); + if (!aRes.get() && myIsInLoad) { // trying to get this document from the session + aRes = document()->subDocument(data()->name()); + } + return aRes; } Model_ResultPart::Model_ResultPart() { - setIsConcealed(false); + myIsInLoad = false; } -void Model_ResultPart::setData(std::shared_ptr theData) +void Model_ResultPart::activate() { - ModelAPI_Result::setData(theData); - if (theData) { - data()->addAttribute(DOC_REF(), ModelAPI_AttributeDocRef::typeId()); + if (myTrsf.get()) { + baseRef()->activate(); + return; } -} -void Model_ResultPart::activate() -{ std::shared_ptr aDocRef = data()->document(DOC_REF()); + // activation may cause changes in current features in document, so it must be in transaction + bool isNewTransaction = false; + SessionPtr aMgr = ModelAPI_Session::get(); if (!aDocRef->value().get()) { // create (or open) a document if it is not yet created + myIsInLoad = true; + if (!aMgr->isOperation()) { + aMgr->startOperation("Activation"); + isNewTransaction = true; + } std::shared_ptr aDoc = document()->subDocument(data()->name()); + myIsInLoad = false; if (aDoc) { + aDoc->synchronizeTransactions(); aDocRef->setValue(aDoc); } } if (aDocRef->value().get()) { ModelAPI_Session::get()->setActiveDocument(aDocRef->value()); } + if (isNewTransaction) { + aMgr->finishOperation(); + } +} + +std::shared_ptr Model_ResultPart::original() +{ + if (myTrsf.get()) { + return baseRef()->original(); + } + return std::dynamic_pointer_cast(data()->owner()); } bool Model_ResultPart::isActivated() { + if (myTrsf.get()) { + return baseRef()->isActivated(); + } + std::shared_ptr aDocRef = data()->document(DOC_REF()); - return aDocRef->value().get(); + return aDocRef->value().get() != NULL; +} + +bool Model_ResultPart::setDisabled(std::shared_ptr theThis, + const bool theFlag) +{ + if (ModelAPI_ResultPart::setDisabled(theThis, theFlag)) { + if (!myTrsf.get()) { // disable of base result part + DocumentPtr aDoc = Model_ResultPart::partDoc(); + if (aDoc.get() && aDoc->isOpened()) { + std::shared_ptr anIntDoc = std::dynamic_pointer_cast(aDoc); + // make the current feature the last in any case: to update shapes defore deactivation too + FeaturePtr aLastFeature = anIntDoc->lastFeature(); + aDoc->setCurrentFeature(aLastFeature, false); + if (theFlag) { // disable, so make all features disabled too + // update the shape just before the deactivation: it will be used outside of part + updateShape(); + shape(); + aDoc->setCurrentFeature(FeaturePtr(), false); + // in order to update OB sub-elements of document before the document closing + Events_Loop* aLoop = Events_Loop::loop(); + aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); + aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); + aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); + } + } + } + return true; + } + return false; +} + +std::shared_ptr Model_ResultPart::shape() +{ + std::shared_ptr aResult(new GeomAPI_Shape); + if (myTrsf.get()) { // get shape of the base result and apply the transformation + ResultPtr anOrigResult = baseRef(); + std::shared_ptr anOrigShape = anOrigResult->shape(); + if (anOrigShape.get()) { + TopoDS_Shape aShape = anOrigShape->impl(); + if (!aShape.IsNull()) { + aShape.Move(*(myTrsf.get())); + aResult->setImpl(new TopoDS_Shape(aShape)); + } + } + return aResult; + } + if (myShape.IsNull()) { // shape is not produced yet, create it + DocumentPtr aDoc = Model_ResultPart::partDoc(); + if (aDoc.get() && aDoc->isOpened()) { + const std::string& aBodyGroup = ModelAPI_ResultBody::group(); + TopoDS_Compound aResultComp; + BRep_Builder aBuilder; + aBuilder.MakeCompound(aResultComp); + int aNumSubs = 0; + for(int a = aDoc->size(aBodyGroup) - 1; a >= 0; a--) { + ResultPtr aBody = std::dynamic_pointer_cast(aDoc->object(aBodyGroup, a)); + // "object" method filters out disabled and concealed anyway, so don't check + if (aBody.get() && aBody->shape().get()) { + TopoDS_Shape aShape = *(aBody->shape()->implPtr()); + if (!aShape.IsNull()) { + aBuilder.Add(aResultComp, aShape); + aNumSubs++; + } + } + } + if (aNumSubs) { + myShape = aResultComp; + } + } + } + if (!myShape.IsNull()) + aResult->setImpl(new TopoDS_Shape(myShape)); + return aResult; +} + +// Returns true is transformation matrices are equal +static bool IsEqualTrsf(gp_Trsf& theT1, gp_Trsf theT2) { + for(int aRow = 1; aRow < 4; aRow++) { + for(int aCol = 1; aCol < 5; aCol++) { + double aDiff = theT1.Value(aRow, aCol) - theT2.Value(aRow, aCol); + if (Abs(aDiff) > 1.e-9) + return false; + } + } + return true; +} + +std::string Model_ResultPart::nameInPart(const std::shared_ptr& theShape, + int& theIndex) +{ + theIndex = 0; // not initialized + + if (myTrsf.get()) { // if this is moved copy of part => return the name of original shape + ResultPartPtr anOrigResult = baseRef(); + // searching in the origin the shape equal to the given but with myTrsf + TopoDS_Shape aSelection = theShape->impl(); + gp_Trsf aSelTrsf = aSelection.Location().Transformation(); + TopoDS_Shape anOrigMain = anOrigResult->shape()->impl(); + if (!aSelection.IsNull() && !anOrigMain.IsNull()) { + TopExp_Explorer anExp(anOrigMain, aSelection.ShapeType()); + for(; anExp.More(); anExp.Next()) { + if (anExp.Current().IsPartner(aSelection)) { + TopoDS_Shape anOrigMoved = anExp.Current().Moved(*(myTrsf.get())); + //if (anOrigMoved.IsSame(aSelection)) { + if (IsEqualTrsf(aSelTrsf, anOrigMoved.Location().Transformation())) { + std::shared_ptr anOrigSel(new GeomAPI_Shape); + anOrigSel->setImpl(new TopoDS_Shape(anExp.Current())); + return anOrigResult->nameInPart(anOrigSel, theIndex); + } + } + } + } + // something is not right + return ""; + } + + TopoDS_Shape aShape = theShape->impl(); + if (aShape.IsNull()) + return ""; + + // getting an access to the document of part + std::shared_ptr aDoc = std::dynamic_pointer_cast(partDoc()); + if (!aDoc.get()) // the part document is not presented for the moment + return ""; + TDF_Label anAccessLabel = aDoc->generalLabel(); + // make the selection attribute anyway: otherwise just by name it is not stable to search the result + std::string aName; + // for this the context result is needed + ResultPtr aContext; + const std::string& aBodyGroup = ModelAPI_ResultBody::group(); + for(int a = aDoc->size(aBodyGroup) - 1; a >= 0; a--) { + ResultPtr aBody = std::dynamic_pointer_cast(aDoc->object(aBodyGroup, a)); + if (aBody.get() && aBody->shape().get() && !aBody->isDisabled()) { + TopoDS_Shape aBodyShape = *(aBody->shape()->implPtr()); + // check is body contain the selected sub-shape + for(TopExp_Explorer anExp(aBodyShape, aShape.ShapeType()); anExp.More(); anExp.Next()) { + if (aShape.IsEqual(anExp.Current())) { + aContext = aBody; + break; + } + } + } + } + if (aContext.get()) { + AttributeSelectionListPtr aSelAttr = aDoc->selectionInPartFeature(); + aSelAttr->append(aContext, theShape); + theIndex = aSelAttr->size(); + AttributeSelectionPtr aNewAttr = aSelAttr->value(theIndex - 1); + return aNewAttr->namingName(); + } + return aName; +} + +bool Model_ResultPart::updateInPart(const int theIndex) +{ + std::shared_ptr aDoc = std::dynamic_pointer_cast(partDoc()); + if (aDoc.get()) { + AttributeSelectionListPtr aSelAttr = aDoc->selectionInPartFeature(); + AttributeSelectionPtr aThisAttr = aSelAttr->value(theIndex - 1); + if (aThisAttr.get()) { + return aThisAttr->update(); + } + } + return false; // something is wrong +} + +std::shared_ptr Model_ResultPart::shapeInPart( + const std::string& theName, const std::string& theType, int& theIndex) +{ + theIndex = 0; // not found yet + std::shared_ptr aResult; + std::shared_ptr aDoc = std::dynamic_pointer_cast(partDoc()); + if (!aDoc.get()) // the part document is not presented for the moment + return aResult; + + AttributeSelectionListPtr aSelAttr = aDoc->selectionInPartFeature(); + // check this selection is already there: reuse it + int aSize = aSelAttr->size(); + for(int a = 0; a < aSize; a++) { + if (aSelAttr->value(a)->namingName() == theName) { + theIndex = a; + return aSelAttr->value(a)->value(); + } + } + + aSelAttr->append(theName, theType); + theIndex = aSelAttr->size(); + aResult = aSelAttr->value(theIndex - 1)->value(); + return aResult; +} + +std::shared_ptr Model_ResultPart::selectionValue(const int theIndex) +{ + std::shared_ptr aResult; + std::shared_ptr aDoc = std::dynamic_pointer_cast(partDoc()); + if (!aDoc.get()) // the part document is not presented for the moment + return aResult; + + AttributeSelectionListPtr aSelAttr = aDoc->selectionInPartFeature(); + aResult = aSelAttr->value(theIndex - 1)->value(); + return aResult; +} + +void Model_ResultPart::colorConfigInfo(std::string& theSection, std::string& theName, + std::string& theDefault) +{ + theSection = "Visualization"; + theName = "result_part_color"; + theDefault = DEFAULT_COLOR(); +} + +void Model_ResultPart::updateShape() +{ + myShape.Nullify(); + myTrsf.reset(); +} + +void Model_ResultPart::setTrsf(std::shared_ptr theThis, + const std::shared_ptr& theTransformation) +{ + updateShape(); + if (theTransformation.get()) { + myTrsf = std::shared_ptr(new gp_Trsf(theTransformation->impl())); + } + // the result must be explicitly updated + static Events_Loop* aLoop = Events_Loop::loop(); + static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); + ModelAPI_EventCreator::get()->sendUpdated(theThis, EVENT_DISP); // flush is in preview-update }