-// Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+// Copyright (C) 2014-2022 CEA/DEN, EDF R&D
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.salome-platform.org/ or
-// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
#include <Model_ResultBody.h>
#include <ModelAPI_Object.h>
#include <ModelAPI_Events.h>
#include <ModelAPI_Tools.h>
+#include <ModelAPI_AttributeImage.h>
#include <Model_Data.h>
#include <Events_Loop.h>
#include <GeomAPI_ShapeIterator.h>
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_Face.h>
+#include <GeomAPI_Pnt.h>
#include <TopoDS_Shape.hxx>
#include <TopExp_Explorer.hxx>
delete myBuilder;
}
+void Model_ResultBody::initAttributes()
+{
+ ModelAPI_Result::initAttributes();
+ // append the image attribute. It is empty, the attribute will be filled by a request
+ data()->addAttribute(IMAGE_ID(), ModelAPI_AttributeImage::typeId())->setIsArgument(false);
+}
+
bool Model_ResultBody::generated(const GeomShapePtr& theNewShape,
const std::string& theName, const bool theCheckIsInResult)
{
void Model_ResultBody::loadGeneratedShapes(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgo,
const GeomShapePtr& theOldShape,
const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
- const std::string& theName)
+ const std::string& theName,
+ const bool theSaveOldIfNotInTree)
{
if (mySubs.size()) { // consists of subs
for (std::vector<ResultBodyPtr>::const_iterator aSubIter = mySubs.cbegin();
++aSubIter)
{
const ResultBodyPtr& aSub = *aSubIter;
- aSub->loadGeneratedShapes(theAlgo, theOldShape, theShapeTypeToExplore, theName);
+ aSub->loadGeneratedShapes(
+ theAlgo, theOldShape, theShapeTypeToExplore, theName, theSaveOldIfNotInTree);
}
} else { // do for this directly
- myBuilder->loadGeneratedShapes(theAlgo, theOldShape, theShapeTypeToExplore, theName);
+ myBuilder->loadGeneratedShapes(
+ theAlgo, theOldShape, theShapeTypeToExplore, theName, theSaveOldIfNotInTree);
}
}
}
}
-int Model_ResultBody::numberOfSubs(bool forTree) const
+void Model_ResultBody::loadFirstLevel(GeomShapePtr theShape, const std::string& theName)
+{
+ if (mySubs.size()) { // consists of subs
+ for (std::vector<ResultBodyPtr>::const_iterator aSubIter = mySubs.cbegin();
+ aSubIter != mySubs.cend();
+ ++aSubIter)
+ {
+ const ResultBodyPtr& aSub = *aSubIter;
+ aSub->loadFirstLevel(theShape, theName);
+ }
+ } else { // do for this directly
+ myBuilder->loadFirstLevel(theShape, theName);
+ }
+}
+
+int Model_ResultBody::numberOfSubs(bool /*forTree*/) const
{
return int(mySubs.size());
}
-ResultBodyPtr Model_ResultBody::subResult(const int theIndex, bool forTree) const
+ResultBodyPtr Model_ResultBody::subResult(const int theIndex, bool /*forTree*/) const
{
if (theIndex >= int(mySubs.size()))
return ResultBodyPtr();
return mySubs.at(theIndex);
}
-bool Model_ResultBody::isSub(ObjectPtr theObject, int& theIndex) const
+bool Model_ResultBody::isSub(ObjectPtr theResult, int& theIndex) const
{
- std::map<ObjectPtr, int>::const_iterator aFound = mySubsMap.find(theObject);
+ std::map<ObjectPtr, int>::const_iterator aFound = mySubsMap.find(theResult);
if (aFound != mySubsMap.end()) {
theIndex = aFound->second;
return true;
return myLastConcealed;
}
-void Model_ResultBody::setIsConcealed(const bool theValue)
+void Model_ResultBody::setIsConcealed(const bool theValue, const bool theForced)
{
if (ModelAPI_ResultBody::isConcealed() != theValue) {
- ModelAPI_ResultBody::setIsConcealed(theValue);
+ ModelAPI_ResultBody::setIsConcealed(theValue, theForced);
updateConcealment();
}
}
}
}
+void Model_ResultBody::addShapeColor( const std::wstring& theName,std::vector<int>& color) {
+
+ if (myColorsShape.find(theName) == myColorsShape.end())
+ myColorsShape[ theName ] = color;
+}
+
+std::wstring Model_ResultBody::addShapeName(std::shared_ptr<GeomAPI_Shape> theshape,
+ const std::wstring& theName ){
+
+ int indice = 1;
+ std::wstringstream aName;
+ aName << theName;
+ while(myNamesShape.find(aName.str()) != myNamesShape.end() ){
+ aName.str(L"");
+ aName << theName << L"__" << indice;
+ indice++;
+ }
+ myNamesShape[ aName.str() ] = theshape;
+
+ return aName.str();
+}
+
+std::wstring Model_ResultBody::findShapeName(std::shared_ptr<GeomAPI_Shape> theShape){
+
+ TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
+ for (std::map< std::wstring, std::shared_ptr<GeomAPI_Shape> >::iterator it =
+ myNamesShape.begin();
+ it != myNamesShape.end();
+ ++it)
+ {
+ TopoDS_Shape curSelectedShape = (*it).second->impl<TopoDS_Shape>();
+ if ((aShape.IsSame(curSelectedShape))) {
+ return (*it).first;
+ }
+ }
+ return L"material not found" ;
+}
+
+void Model_ResultBody::setShapeName(
+ std::map< std::wstring, std::shared_ptr<GeomAPI_Shape>>& theShapeName,
+ std::map< std::wstring, std::vector<int>>& theColorsShape)
+{
+ myNamesShape = theShapeName;
+ myColorsShape = theColorsShape;
+}
+
+void Model_ResultBody::clearShapeNameAndColor(){
+ myNamesShape.clear();
+ myColorsShape.clear();
+}
+
void Model_ResultBody::updateSubs(const std::shared_ptr<GeomAPI_Shape>& theThisShape,
const bool theShapeChanged)
{
aShape->setImpl(new TopoDS_Shape(aShapesIter.Value()));
ResultBodyPtr aSub;
if (mySubs.size() <= aSubIndex) { // it is needed to create a new sub-result
- aSub = anObjects->createBody(this->data(), aSubIndex);
+ std::wstring thenameshape = L"";
+ // find shape name read
+ for (std::map< std::wstring, std::shared_ptr<GeomAPI_Shape> >::iterator it =
+ myNamesShape.begin();
+ it != myNamesShape.end();
+ ++it)
+ {
+ TopoDS_Shape curSelectedShape = (*it).second->impl<TopoDS_Shape>();
+ if (!(aShapesIter.Value().IsSame(curSelectedShape))) continue;
+ thenameshape = (*it).first;
+ break;
+ }
+ aSub = anObjects->createBody(this->data(), aSubIndex,thenameshape);
+ //finf color read
+ std::map< std::wstring, std::vector<int>>::iterator itColor =
+ myColorsShape.find(thenameshape);
+ if (itColor != myColorsShape.end()){
+ ModelAPI_Tools::setColor(aSub,(*itColor).second);
+ }
+ aSub->setShapeName(myNamesShape,myColorsShape);
mySubs.push_back(aSub);
mySubsMap[aSub] = int(mySubs.size() - 1);
if (isConcealed()) { // for issue #2579 note7
aSub->ModelAPI_ResultBody::setIsConcealed(true);
std::dynamic_pointer_cast<Model_ResultBody>(aSub)->updateConcealment();
}
+
} else { // just update shape of this result
aSub = mySubs[aSubIndex];
}
myAlgo = theMakeShape;
myOlds = theOlds;
myIsGenerated = isGenerated;
+ // to avoid changing of "isDisabled" flag in the "updateSubs" cycle
+ isDisabled();
+
updateSubs(theThisShape, true);
myAlgo.reset();
myOlds.clear();
+ myHistoryCash.Clear();
}
-
bool Model_ResultBody::isConnectedTopology()
{
TDF_Label aDataLab = std::dynamic_pointer_cast<Model_Data>(data())->label();
}
}
+bool Model_ResultBody::hasTexture()
+{
+ AttributeImagePtr anImageAttr =
+ data()->image(ModelAPI_ResultBody::IMAGE_ID());
+ if (anImageAttr.get()) {
+ return anImageAttr->hasTexture();
+ }
+ return false;
+}
+
// adds to the theSubSubs map all sub-shapes of theSub if it is compound of compsolid
static void collectSubs(
const GeomShapePtr theSub, TopTools_MapOfShape& theSubSubs, const bool theOneLevelMore)
return;
if (theSubSubs.Add(theSub->impl<TopoDS_Shape>())) {
bool aIsComp = theSub->isCompound() || theSub->isCompSolid();
- if (aIsComp || theOneLevelMore) {
- for(GeomAPI_ShapeIterator anIter(theSub); anIter.more(); anIter.next()) {
- collectSubs(anIter.current(), theSubSubs, aIsComp && theOneLevelMore);
+ if (aIsComp) {
+ for(GeomAPI_ShapeIterator anIter(theSub); anIter.more(); anIter.next())
+ collectSubs(anIter.current(), theSubSubs, theOneLevelMore);
+ } else if (theOneLevelMore) {
+ GeomAPI_Shape::ShapeType aSubType = GeomAPI_Shape::ShapeType(int(theSub->shapeType()) + 1);
+ if (aSubType == GeomAPI_Shape::SHAPE)
+ return;
+ if (aSubType == GeomAPI_Shape::SHELL)
+ aSubType = GeomAPI_Shape::FACE;
+ if (aSubType == GeomAPI_Shape::WIRE)
+ aSubType = GeomAPI_Shape::EDGE;
+
+ for(GeomAPI_ShapeExplorer anExp(theSub, aSubType); anExp.more(); anExp.next()) {
+ collectSubs(anExp.current(), theSubSubs, false);
}
}
}
// iterate one level more (for intersection of solids this is face)
collectSubs(*aRootOlds, anOldSubs, true);
for (TopTools_MapOfShape::Iterator anOldIter(anOldSubs); anOldIter.More(); anOldIter.Next()) {
+ TopoDS_Shape anOldShape = anOldIter.Value();
+ if (anOldShape.ShapeType() == TopAbs_COMPOUND || anOldShape.ShapeType() == TopAbs_SHELL ||
+ anOldShape.ShapeType() == TopAbs_WIRE || anOldShape.ShapeType() == TopAbs_COMPSOLID)
+ continue; // container old-shapes are not supported by the history, may cause crash
GeomShapePtr anOldSub(new GeomAPI_Shape);
- anOldSub->setImpl<TopoDS_Shape>(new TopoDS_Shape(anOldIter.Value()));
+ anOldSub->setImpl<TopoDS_Shape>(new TopoDS_Shape(anOldShape));
+
ListOfShape aNews;
- myIsGenerated ? myAlgo->generated(anOldSub, aNews) : myAlgo->modified(anOldSub, aNews);
- // MakeShape may return alone old shape if there is no history information for this input
- if (aNews.size() == 1 && aNews.front()->isEqual(anOldSub))
- aNews.clear();
+ if (myHistoryCash.IsBound(anOldShape)) {
+ const TopTools_ListOfShape& aList = myHistoryCash.Find(anOldShape);
+ for(TopTools_ListIteratorOfListOfShape anIter(aList); anIter.More(); anIter.Next()) {
+ GeomShapePtr aShape(new GeomAPI_Shape);
+ aShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(anIter.Value()));
+ aNews.push_back(aShape);
+ }
+ } else {
+ myIsGenerated ? myAlgo->generated(anOldSub, aNews) : myAlgo->modified(anOldSub, aNews);
+ // MakeShape may return alone old shape if there is no history information for this input
+ if (aNews.size() == 1 && aNews.front()->isEqual(anOldSub))
+ aNews.clear();
+ // store result in the history
+ TopTools_ListOfShape aList;
+ for (ListOfShape::iterator aNewIter = aNews.begin(); aNewIter != aNews.end(); aNewIter++) {
+ aList.Append((*aNewIter)->impl<TopoDS_Shape>());
+ }
+ myHistoryCash.Bind(anOldShape, aList);
+ }
for (ListOfShape::iterator aNewIter = aNews.begin(); aNewIter != aNews.end(); aNewIter++) {
if (aSubSubs.Contains((*aNewIter)->impl<TopoDS_Shape>())) {