-// Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+// Copyright (C) 2014-2021 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
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-#include "ModelAPI_Tools.h"
-#include <ModelAPI_Session.h>
+#include <ModelAPI_AttributeBoolean.h>
+#include <ModelAPI_AttributeDocRef.h>
+#include <ModelAPI_AttributeDouble.h>
+#include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_CompositeFeature.h>
#include <ModelAPI_Document.h>
+#include <ModelAPI_Events.h>
#include <ModelAPI_Object.h>
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultConstruction.h>
+#include <ModelAPI_ResultGroup.h>
#include <ModelAPI_ResultParameter.h>
#include <ModelAPI_ResultPart.h>
-#include <ModelAPI_ResultGroup.h>
-#include <ModelAPI_AttributeDocRef.h>
+#include <ModelAPI_Session.h>
+#include "ModelAPI_Tools.h"
#include <ModelAPI_Validator.h>
-#include <ModelAPI_AttributeIntArray.h>
-#include <ModelAPI_ResultConstruction.h>
-#include <ModelAPI_AttributeBoolean.h>
-#include <list>
-#include <map>
-#include <iostream>
-#include <sstream>
-
-// To support old types of GCC (less than 5.0), check the wide-string conversion is working
-#if (__cplusplus >= 201103L || _MSVC_LANG >= 201103L) && \
- (__cplusplus >= 201402L || !defined(__GLIBCXX__) || \
- (defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE > 4))
-#define HAVE_WORKING_WIDESTRING 1
-#else
-#define HAVE_WORKING_WIDESTRING 0
-#endif
-
-#if HAVE_WORKING_WIDESTRING
-#include <codecvt>
-#endif
+#include <Config_Translator.h>
#include <Events_Loop.h>
-#include <ModelAPI_Events.h>
+#include <Locale_Convert.h>
#include <GeomAPI_ShapeHierarchy.h>
#include <GeomAPI_ShapeIterator.h>
+#include <algorithm>
+#include <iostream>
+#include <list>
+#include <map>
+#include <sstream>
+
#define RECURSE_TOP_LEVEL 50
//#define DEBUG_REMOVE_FEATURES
CompositeFeaturePtr aComposite =
std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
if (aComposite) {
+ bool aHasSubError = false;
for (int i = 0, aSize = aComposite->numberOfSubs(); i < aSize; i++) {
FeaturePtr aSubFeature = aComposite->subFeature(i);
std::string aSubFeatureError = getFeatureError(aSubFeature);
if (!aSubFeatureError.empty()) {
anError = anError + " in " + aSubFeature->getKind() + ".\n" + aSubFeatureError;
+ aHasSubError = true;
break;
}
}
+ if (!aHasSubError) { // #24260: error not in the sub-features, but in the argument
+ if (aComposite->getKind() == "Sketch" &&
+ aComposite->selection("External")->isInvalid()) {
+ std::string aMsg = "The sketch base plane is invalid, ";
+ aMsg += "please push 'Change sketch plane' button to reselect it.";
+ anError = Config_Translator::translate(aComposite->getKind(), aMsg);
+ }
+ }
}
}
}
// LCOV_EXCL_STOP
ObjectPtr objectByName(const DocumentPtr& theDocument, const std::string& theGroup,
- const std::string& theName)
+ const std::wstring& theName)
{
- std::wstring aName = toWString(theName);
for (int anIndex = 0; anIndex < theDocument->size(theGroup); ++anIndex) {
ObjectPtr anObject = theDocument->object(theGroup, anIndex);
- if (anObject->data()->name() == aName)
+ if (anObject->data()->name() == theName)
return anObject;
}
// not found
}
bool findVariable(const DocumentPtr& theDocument, FeaturePtr theSearcher,
- const std::string& theName, double& outValue, ResultParameterPtr& theParam)
+ const std::wstring& theName, double& outValue, ResultParameterPtr& theParam)
{
ObjectPtr aParamObj = objectByName(theDocument, ModelAPI_ResultParameter::group(), theName);
theParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParamObj);
return true;
}
-bool findVariable(FeaturePtr theSearcher, const std::string& theName, double& outValue,
+bool findVariable(FeaturePtr theSearcher, const std::wstring& theName, double& outValue,
ResultParameterPtr& theParam, const DocumentPtr& theDocument)
{
SessionPtr aSession = ModelAPI_Session::get();
}
bool removeFeaturesAndReferences(const std::set<FeaturePtr>& theFeatures,
- const bool theFlushRedisplay,
+ const bool /*theFlushRedisplay*/,
const bool theUseComposite,
const bool theUseRecursion)
{
}
else { // filter references to skip composition features of the current feature
std::set<FeaturePtr> aFilteredFeatures;
- std::set<FeaturePtr>::const_iterator anIt = aSelRefFeatures.begin(),
- aLast = aSelRefFeatures.end();
- for (; anIt != aLast; anIt++) {
- FeaturePtr aCFeature = *anIt;
+ std::set<FeaturePtr>::const_iterator aRefIt = aSelRefFeatures.begin(),
+ aRefLast = aSelRefFeatures.end();
+ for (; aRefIt != aRefLast; aRefIt++) {
+ FeaturePtr aCFeature = *aRefIt;
CompositeFeaturePtr aComposite =
std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCFeature);
if (aComposite.get() && aComposite->isSub(aFeature))
aResultRefList.insert(aMainRefList.begin(), aMainRefList.end());
for (; anIt != aLast; anIt++) {
FeaturePtr aFeature = *anIt;
- int aRecLevel = 0;
+ aRecLevel = 0;
#ifdef DEBUG_REMOVE_FEATURES_RECURSE
std::cout << " Ref: " << getFeatureInfo(aFeature) << std::endl;
#endif
}
std::pair<std::wstring, bool> getDefaultName(const std::shared_ptr<ModelAPI_Result>& theResult,
- const bool theInherited)
+ const bool theInherited,
+ const bool theRecursive)
{
typedef std::list< std::pair < std::string, std::list<ObjectPtr> > > ListOfReferences;
}
}
// check the result is a Body
- if ((*anObjIt)->groupName() == ModelAPI_ResultBody::group()) {
+ if (anObjIt->get() && (*anObjIt)->groupName() == ModelAPI_ResultBody::group()) {
// check the result is part of CompSolid
ResultPtr anObjRes = std::dynamic_pointer_cast<ModelAPI_Result>(*anObjIt);
ResultBodyPtr aParentBody = ModelAPI_Tools::bodyOwner(anObjRes);
// return name of reference result only if it has been renamed by the user,
// in other case compose a default name
- if (anObjRes->data()->hasUserDefinedName()) {
+ if (anObjRes->data()->hasUserDefinedName() ||
+ (theRecursive && anObjRes->data()->name() != getDefaultName(anObjRes).first)) {
std::wstringstream aName;
aName << anObjRes->data()->name();
std::map<ResultPtr, int>::iterator aFound = aNbRefToObject.find(anObjRes);
for(; aResIter != aResSet.end(); aResIter++) {
std::list<ResultPtr>::const_iterator aGroupRes = (*aResIter)->results().cbegin();
for(; aGroupRes != (*aResIter)->results().cend(); aGroupRes++) {
- const std::set<AttributePtr>& aRefs = (*aGroupRes)->data()->refsToMe();
- std::set<AttributePtr>::const_iterator aRef = aRefs.cbegin();
- for(; aRef != aRefs.cend(); aRef++) {
- FeaturePtr aFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
+ const std::set<AttributePtr>& aGroupRefs = (*aGroupRes)->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aRefIt = aGroupRefs.cbegin();
+ for(; aRefIt != aGroupRefs.cend(); aRefIt++) {
+ FeaturePtr aFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRefIt)->owner());
if (aFeat.get() && !aGroupOperations.count(aFeat) && !aFeat->results().empty() &&
aFeat->firstResult()->groupName() == ModelAPI_ResultGroup::group()) {
// iterate results of this group operation because it may be without theTarget shape
return aResList;
}
-// LCOV_EXCL_STOP
-std::string toString(const std::wstring& theWStr)
+void setValues(std::vector<int>& theRGB, const int theRed, const int theGreen, const int theBlue)
{
-#if HAVE_WORKING_WIDESTRING
- static std::wstring_convert<std::codecvt_utf8<wchar_t> > aConvertor;
- return aConvertor.to_bytes(theWStr);
-#else
- char* aBuf = new char[2 * (theWStr.size() + 1)];
- size_t aNbChars = std::wcstombs(aBuf, theWStr.c_str(), theWStr.size());
- if (aNbChars != (size_t)-1)
- aBuf[aNbChars] = '\0';
- std::string aStr(aBuf);
- delete[] aBuf;
- return aStr;
-#endif
+ theRGB.push_back(theRed);
+ theRGB.push_back(theGreen);
+ theRGB.push_back(theBlue);
}
-/*! Converts a byte string to an extended string
-* \param theStr a byte string
-*/
-std::wstring toWString(const std::string& theStr)
+std::vector<int> HSVtoRGB(int theH, int theS, int theV)
{
-#if HAVE_WORKING_WIDESTRING
- static std::wstring_convert<std::codecvt_utf8<wchar_t> > aConvertor;
- return aConvertor.from_bytes(theStr);
-#else
- wchar_t* aBuf = new wchar_t[theStr.size()];
- size_t aNbWChars = std::mbstowcs(aBuf, theStr.c_str(), theStr.size());
- if (aNbWChars != (size_t)-1)
- aBuf[aNbWChars] = '\0';
- std::wstring aWStr(aBuf);
- delete[] aBuf;
- return aWStr;
-#endif
+ std::vector<int> aRGB;
+ if (theH < 0 || theH > 360 ||
+ theS < 0 || theS > 100 ||
+ theV < 0 || theV > 100)
+ return aRGB;
+
+ int aHi = (int)theH/60;
+ double aV = theV;
+ double aVmin = (100 - theS)*theV/100;
+ double anA = (theV - aVmin)* (theH % 60) / 60;
+ double aVinc = aVmin + anA;
+ double aVdec = theV - anA;
+ double aPercentToValue = 255./100;
+ int aV_int = (int)(aV*aPercentToValue);
+ int aVinc_int = (int)(aVinc*aPercentToValue);
+ int aVmin_int = (int)(aVmin*aPercentToValue);
+ int aVdec_int = (int)(aVdec*aPercentToValue);
+
+ switch(aHi) {
+ case 0: setValues(aRGB, aV_int, aVinc_int, aVmin_int); break;
+ case 1: setValues(aRGB, aVdec_int, aV_int, aVmin_int); break;
+ case 2: setValues(aRGB, aVmin_int, aV_int, aVinc_int); break;
+ case 3: setValues(aRGB, aVmin_int, aVdec_int, aV_int); break;
+ case 4: setValues(aRGB, aVinc_int, aVmin_int, aV_int); break;
+ case 5: setValues(aRGB, aV_int, aVmin_int, aVdec_int); break;
+ default: break;
+ }
+ return aRGB;
}
+std::array<std::vector<int>, 10> myColorTab = {
+ std::vector<int> {255, 0, 0},
+ std::vector<int> {0, 255, 0},
+ std::vector<int> {0, 0, 255},
+ std::vector<int> {255, 255, 0},
+ std::vector<int> {0, 255, 255},
+ std::vector<int> {255, 0, 255},
+ std::vector<int> {255, 94, 0},
+ std::vector<int> {132, 255, 0},
+ std::vector<int> {132, 0, 255},
+ std::vector<int> {0, 0, 0},
+};
+
+void findRandomColor(std::vector<int>& theValues, bool theReset)
+{
+ static int i = 0;
+ static std::vector<std::vector<int>> usedGeneratedColor;
+
+ // True when disabling auto-color
+ if ( theReset ) {
+ i = 0;
+ return;
+ }
+
+ theValues.clear();
+ if (i < myColorTab.size()) {
+ theValues = myColorTab[i++];
+ } else {
+ int timeout = 0;
+ std::vector<int> aHSVColor;
+ std::vector<int> aRGBColor;
+ do {
+ aHSVColor = {rand() % 360 , rand() % (100 - 50 + 1) + 50, rand() % (100 - 50 + 1) + 50};
+ aRGBColor = HSVtoRGB(aHSVColor[0], aHSVColor[1], aHSVColor[2]);
+ timeout++;
+ } while (
+ timeout < 20 &&
+ std::find(usedGeneratedColor.begin(), usedGeneratedColor.end(), aHSVColor)
+ != usedGeneratedColor.end() &&
+ std::find(myColorTab.begin(), myColorTab.end(), aRGBColor) != myColorTab.end());
+ usedGeneratedColor.push_back(aHSVColor);
+ theValues = aRGBColor;
+ }
+}
+// LCOV_EXCL_STOP
} // namespace ModelAPI_Tools