From e57e1a64cea597f670644f86baf9efb2780450b9 Mon Sep 17 00:00:00 2001 From: mpv Date: Thu, 31 Oct 2019 18:23:09 +0300 Subject: [PATCH] Fix for the issue #17917 Error during export to GEOM of a PartSet with groups The problem was related to the Placement of parts feature - it adds additional transformation to all results and groups. --- .../ExchangePlugin_ExportFeature.cpp | 8 +++++- src/GeomAPI/GeomAPI_Shape.cpp | 7 +++++ src/GeomAPI/GeomAPI_Shape.h | 5 ++++ src/GeomAPI/GeomAPI_Trsf.h | 3 +++ .../GeomAlgoAPI_CompoundBuilder.cpp | 27 +++++++++++++++++++ src/Model/Model_ResultPart.cpp | 7 +++++ src/Model/Model_ResultPart.h | 2 ++ src/ModelAPI/ModelAPI_ResultPart.h | 3 +++ 8 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp index bf677c743..4eedccc26 100644 --- a/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp +++ b/src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include @@ -313,6 +314,7 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName) std::list aShapes; std::list aResults; std::list aDocuments; /// documents of Parts selected and used in export + std::map aDocTrsf; /// translation of the part AttributeSelectionListPtr aSelection = selectionList(SELECTION_LIST_ID()); bool aIsSelection = aSelection->isInitialized() && aSelection->size() > 0; @@ -336,6 +338,7 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName) return; } else { aDocuments.push_back(aPartDoc); + aDocTrsf[aPartDoc] = aResPart->summaryTrsf(); } } } @@ -414,7 +417,10 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName) try { GeomAPI_ShapeExplorer aGroupResExplorer(aResultGroup->shape(), aSelType); for(; aGroupResExplorer.more(); aGroupResExplorer.next()) { - int aReferenceID = GeomAlgoAPI_CompoundBuilder::id(aShape, aGroupResExplorer.current()); + GeomShapePtr aGroupShape = aGroupResExplorer.current(); + if (aDocTrsf.find(*aDoc) != aDocTrsf.end()) + aGroupShape->move(aDocTrsf[*aDoc]); + int aReferenceID = GeomAlgoAPI_CompoundBuilder::id(aShape, aGroupShape); if (aReferenceID == 0) // selected value does not found in the exported shape continue; std::string aReferenceString = XAO::XaoUtils::intToString(aReferenceID); diff --git a/src/GeomAPI/GeomAPI_Shape.cpp b/src/GeomAPI/GeomAPI_Shape.cpp index 99b27729f..a0c9061d7 100644 --- a/src/GeomAPI/GeomAPI_Shape.cpp +++ b/src/GeomAPI/GeomAPI_Shape.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -699,6 +700,12 @@ void GeomAPI_Shape::translate(const std::shared_ptr theDir, const d setImpl(new TopoDS_Shape(aResult)); } +void GeomAPI_Shape::move(const std::shared_ptr theTransformation) +{ + TopoDS_Shape aResult = MY_SHAPE->Moved(theTransformation->impl()); + setImpl(new TopoDS_Shape(aResult)); +} + bool GeomAPI_Shape::isSelfIntersected(const int theLevelOfCheck) const { BOPAlgo_CheckerSI aCSI; // checker of self-interferences diff --git a/src/GeomAPI/GeomAPI_Shape.h b/src/GeomAPI/GeomAPI_Shape.h index 2202d0226..7c3a2a6cc 100644 --- a/src/GeomAPI/GeomAPI_Shape.h +++ b/src/GeomAPI/GeomAPI_Shape.h @@ -33,6 +33,7 @@ class GeomAPI_Wire; class GeomAPI_Face; class GeomAPI_Shell; class GeomAPI_Solid; +class GeomAPI_Trsf; /**\class GeomAPI_Shape * \ingroup DataModel @@ -205,6 +206,10 @@ public: GEOMAPI_EXPORT void translate(const std::shared_ptr theDir, const double theOffset); + /// Moves the shape with the given transformation matrix. + GEOMAPI_EXPORT + void move(const std::shared_ptr theTransformation); + /// Returns type of shapes in the compound. // If shapes are of different type then it will return SHAPE type GEOMAPI_EXPORT ShapeType typeOfCompoundShapes() const; diff --git a/src/GeomAPI/GeomAPI_Trsf.h b/src/GeomAPI/GeomAPI_Trsf.h index 80b492f09..84539eca6 100644 --- a/src/GeomAPI/GeomAPI_Trsf.h +++ b/src/GeomAPI/GeomAPI_Trsf.h @@ -95,5 +95,8 @@ class GeomAPI_Trsf : public GeomAPI_Interface GEOMAPI_EXPORT void setSymmetry(const std::shared_ptr thePlane); }; +//! Pointer on the object +typedef std::shared_ptr GeomTrsfPtr; + #endif diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.cpp index 6df743c50..bb241e6af 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_CompoundBuilder.cpp @@ -22,6 +22,7 @@ #include #include #include +#include std::shared_ptr GeomAlgoAPI_CompoundBuilder::compound( std::list > theShapes) @@ -41,6 +42,20 @@ std::shared_ptr GeomAlgoAPI_CompoundBuilder::compound( return aRes; } +// Returns true if transformations are equal with the given precision +static bool isEqual(const gp_Trsf& theT1, const gp_Trsf& theT2, const double thePrecision) +{ + 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 (aDiff < 0) aDiff = -aDiff; + if (aDiff > thePrecision) + return false; + } + } + return true; +} + int GeomAlgoAPI_CompoundBuilder::id( std::shared_ptr theContext, std::shared_ptr theSub) { @@ -51,6 +66,18 @@ int GeomAlgoAPI_CompoundBuilder::id( TopTools_IndexedMapOfShape aSubShapesMap; TopExp::MapShapes(aMainShape, aSubShapesMap); anID = aSubShapesMap.FindIndex(aSubShape); + if (anID == 0) { // try to search shape with the same location if TopLoc_Location is different + TopExp_Explorer anExp(aMainShape, aSubShape.ShapeType()); + for(; anExp.More(); anExp.Next()) { + if (anExp.Current().TShape() == aSubShape.TShape()) { + const TopLoc_Location aLoc1 = anExp.Current().Location(); + if (isEqual(aLoc1.Transformation(), aSubShape.Location().Transformation(), 1.e-7)) { + anID = aSubShapesMap.FindIndex(anExp.Current()); + break; + } + } + } + } } return anID; diff --git a/src/Model/Model_ResultPart.cpp b/src/Model/Model_ResultPart.cpp index b8fb440d7..7bbadba0d 100644 --- a/src/Model/Model_ResultPart.cpp +++ b/src/Model/Model_ResultPart.cpp @@ -415,3 +415,10 @@ void Model_ResultPart::setTrsf(std::shared_ptr theThis, static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); ModelAPI_EventCreator::get()->sendUpdated(theThis, EVENT_DISP); // flush is in preview-update } + +std::shared_ptr Model_ResultPart::summaryTrsf() +{ + GeomTrsfPtr aResult(new GeomAPI_Trsf); + aResult->setImpl(new gp_Trsf(sumTrsf())); + return aResult; +} diff --git a/src/Model/Model_ResultPart.h b/src/Model/Model_ResultPart.h index 4be75fc07..fff44ed1c 100644 --- a/src/Model/Model_ResultPart.h +++ b/src/Model/Model_ResultPart.h @@ -85,6 +85,8 @@ class Model_ResultPart : public ModelAPI_ResultPart /// Applies the additional transformation of the part MODEL_EXPORT virtual void setTrsf(std::shared_ptr theThis, const std::shared_ptr& theTransformation); + /// Returns the summary transformations of all references to the origin + MODEL_EXPORT virtual std::shared_ptr summaryTrsf(); /// Returns the parameters of color definition in the resources config manager MODEL_EXPORT virtual void colorConfigInfo(std::string& theSection, std::string& theName, diff --git a/src/ModelAPI/ModelAPI_ResultPart.h b/src/ModelAPI/ModelAPI_ResultPart.h index bb49d5188..4a4756be5 100644 --- a/src/ModelAPI/ModelAPI_ResultPart.h +++ b/src/ModelAPI/ModelAPI_ResultPart.h @@ -82,6 +82,9 @@ class ModelAPI_ResultPart : public ModelAPI_Result virtual void setTrsf(std::shared_ptr theThis, const std::shared_ptr& theTransformation) = 0; + /// Returns the summary transformations of all references to the origin + virtual std::shared_ptr summaryTrsf() = 0; + /// Returns the shape by the name in the part virtual std::shared_ptr shapeInPart( const std::string& theName, const std::string& theType, int& theIndex) = 0; -- 2.30.2