X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModelHighAPI%2FModelHighAPI_Dumper.cpp;h=e7b03dd00fde6d212038676d32fbe982893f0f71;hb=b73fb7468bea81901dbeed8e229d742f788ec282;hp=985e6761ea60da801a77c61a13e2fcb18134a133;hpb=5c6be24fd6035f7a030e76b8a369ef57b81893ca;p=modules%2Fshaper.git diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp index 985e6761e..e7b03dd00 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -49,11 +50,13 @@ #include #include #include -#include #include #include +#include #include +#include + #include #include @@ -65,6 +68,7 @@ static int gCompositeStackDepth = 0; ModelHighAPI_Dumper* ModelHighAPI_Dumper::mySelf = 0; ModelHighAPI_Dumper::ModelHighAPI_Dumper() + : myGeometricalSelection(false) { clear(); } @@ -161,6 +165,17 @@ const std::string& ModelHighAPI_Dumper::name(const EntityPtr& theEntity, if (aNbFeatures.first == anId && aNbFeatures.second < anId) { // name is not user-defined isDefaultName = true; + + // check there are postponed features of this kind, + // dump their names, because the sequence of features may be changed + for (std::list::const_iterator aPpIt = myPostponed.begin(); + aPpIt != myPostponed.end(); ++aPpIt) { + FeaturePtr aCurFeature = std::dynamic_pointer_cast(*aPpIt); + if (aCurFeature && aCurFeature->getKind() == aKind) { + myNames[*aPpIt].myIsDefault = false; + isDefaultName = false; + } + } } if (anId > aNbFeatures.second) @@ -216,32 +231,15 @@ void ModelHighAPI_Dumper::saveResultNames(const FeaturePtr& theFeature) // Save only names of results which is not correspond to default feature name const std::list& aResults = theFeature->results(); - std::list::const_iterator aResIt = aResults.begin(); - for (int i = 0; aResIt != aResults.end(); ++aResIt, ++i) { - std::pair aName = ModelAPI_Tools::getDefaultName(*aResIt, i); + std::list allRes; + ModelAPI_Tools::allResults(theFeature, allRes); + for(std::list::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) { + std::pair aName = ModelAPI_Tools::getDefaultName(*aRes); std::string aDefaultName = aName.first; - std::string aResName = (*aResIt)->data()->name(); - + std::string aResName = (*aRes)->data()->name(); bool isUserDefined = !(isFeatureDefaultName && aDefaultName == aResName); - - myNames[*aResIt] = EntityName(aResName, - (isUserDefined ? aResName : std::string()), !isUserDefined); - - // check names of sub-results for CompSolid - ResultCompSolidPtr aCompSolid = std::dynamic_pointer_cast(*aResIt); - if (aCompSolid) { - int aNbSubs = aCompSolid->numberOfSubs(); - for (int j = 0; j < aNbSubs; ++j) { - ResultPtr aSub = aCompSolid->subResult(j); - std::string aSubName = aSub->data()->name(); - aName = ModelAPI_Tools::getDefaultName(aSub, j); - aDefaultName = aName.first; - - bool isUserDefinedSubName = isUserDefined || aDefaultName != aSubName; - myNames[aSub] = EntityName(aSubName, - (isUserDefinedSubName ? aSubName : std::string()), !isUserDefinedSubName); - } - } + myNames[*aRes] = + EntityName(aResName, (isUserDefined ? aResName : std::string()), !isUserDefined); } } @@ -579,12 +577,28 @@ bool ModelHighAPI_Dumper::isDumped(const AttributeRefListPtr& theRefList) const return true; } +static bool isSketchSub(const FeaturePtr& theFeature) +{ + static const std::string SKETCH("Sketch"); + CompositeFeaturePtr anOwner = ModelAPI_Tools::compositeOwner(theFeature); + return anOwner && anOwner->getKind() == SKETCH; +} + bool ModelHighAPI_Dumper::isDefaultColor(const ResultPtr& theResult) const { AttributeIntArrayPtr aColor = theResult->data()->intArray(ModelAPI_Result::COLOR_ID()); if (!aColor || !aColor->isInitialized()) return true; + // check the result belongs to sketch entity, do not dump color in this way + ResultConstructionPtr aResConstr = + std::dynamic_pointer_cast(theResult); + if (aResConstr) { + FeaturePtr aFeature = ModelAPI_Feature::feature(theResult->data()->owner()); + if (isSketchSub(aFeature)) + return true; + } + std::string aSection, aName, aDefault; theResult->colorConfigInfo(aSection, aName, aDefault); @@ -783,24 +797,12 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity bool isUserDefinedName = !myNames[theEntity].myIsDefault; // store results if they have user-defined names or colors std::list aResultsWithNameOrColor; - const std::list& aResults = theEntity->results(); - std::list::const_iterator aResIt = aResults.begin(); - for (; aResIt != aResults.end(); ++aResIt) { - if (!myNames[*aResIt].myIsDefault || !isDefaultColor(*aResIt) || - !isDefaultDeflection(*aResIt) || !isDefaultTransparency(*aResIt)) - aResultsWithNameOrColor.push_back(*aResIt); - - ResultCompSolidPtr aCompSolid = - std::dynamic_pointer_cast(*aResIt); - if (aCompSolid) { - int aNbSubs = aCompSolid->numberOfSubs(); - for (int i = 0; i < aNbSubs; ++i) { - ResultPtr aCurRes = aCompSolid->subResult(i); - if (!myNames[aCurRes].myIsDefault || !isDefaultColor(aCurRes) || - !isDefaultDeflection(aCurRes) || !isDefaultTransparency(aCurRes)) - aResultsWithNameOrColor.push_back(aCurRes); - } - } + std::list allRes; + ModelAPI_Tools::allResults(theEntity, allRes); + for(std::list::iterator aRes = allRes.begin(); aRes != allRes.end(); aRes++) { + if(!myNames[*aRes].myIsDefault || !isDefaultColor(*aRes) || + !isDefaultDeflection(*aRes) || !isDefaultTransparency(*aRes)) + aResultsWithNameOrColor.push_back(*aRes); } // store just dumped entity to stack if (myEntitiesStack.empty() || myEntitiesStack.top().myEntity != theEntity) @@ -815,37 +817,40 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const ResultPtr& theResult) { + // iterate in the structure of sub-results to the parent + ResultPtr aCurRes = theResult; FeaturePtr aFeature = ModelAPI_Feature::feature(theResult); - int anIndex = 0; - int aSubIndex = -1; - std::list aResults = aFeature->results(); - for(std::list::const_iterator - anIt = aResults.cbegin(); anIt != aResults.cend(); ++anIt, ++anIndex) { - if(theResult->isSame(*anIt)) { - break; - } - - ResultCompSolidPtr aCompSolid = std::dynamic_pointer_cast(*anIt); - if (aCompSolid) { - int aNbSubs = aCompSolid->numberOfSubs(); - for (aSubIndex = 0; aSubIndex < aNbSubs; ++aSubIndex) - if (theResult->isSame(aCompSolid->subResult(aSubIndex))) + std::list anIndices; // indexes of results in the parent result, starting from topmost + while(aCurRes.get()) { + ResultBodyPtr aParent = ModelAPI_Tools::bodyOwner(aCurRes); + if (aParent) { + anIndices.push_front(ModelAPI_Tools::bodyIndex(aCurRes)); + } else { // index of the result in the feature + std::list::const_iterator aRes = aFeature->results().cbegin(); + for(int anIndex = 0; aRes != aFeature->results().cend(); aRes++, anIndex++) { + if (*aRes == aCurRes) { + anIndices.push_front(anIndex); break; - if (aSubIndex < aNbSubs) - break; - aSubIndex = -1; + } + } } + aCurRes = aParent; } myDumpBuffer << name(aFeature); - if(anIndex == 0) { - myDumpBuffer << ".result()"; - } else { - myDumpBuffer << ".results()[" << anIndex << "]"; - } - if (aSubIndex >= 0) { - myDumpBuffer << ".subResult(" << aSubIndex << ")"; + for (std::list::iterator anI = anIndices.begin(); anI != anIndices.end(); anI++) { + if (anI == anIndices.begin()) { + if(*anI == 0) { + myDumpBuffer << ".result()"; + } + else { + myDumpBuffer << ".results()[" << *anI << "]"; + } + } else { + myDumpBuffer << ".subResult(" << *anI << ")"; + } } + return *this; } @@ -961,6 +966,76 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( return *this; } +static int possibleSelectionsByPoint(const GeomPointPtr& thePoint, + const ResultPtr& theResult, + const GeomShapePtr& theShape, + const FeaturePtr& theStartFeature, + const FeaturePtr& theEndFeature) +{ + DocumentPtr aDoc1 = theStartFeature->document(); + DocumentPtr aDoc2 = theEndFeature->document(); + + std::list aFeatures = aDoc1->allFeatures(); + if (aDoc1 != aDoc2) { + std::list anAdditionalFeatures = aDoc2->allFeatures(); + aFeatures.insert(aFeatures.end(), anAdditionalFeatures.begin(), anAdditionalFeatures.end()); + } + + CompositeFeaturePtr aLastCompositeFeature; + + std::list::const_iterator aFIt = aFeatures.begin(); + while (aFIt != aFeatures.end() && *aFIt != theStartFeature) { + CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast(*aFIt); + if (aCompFeat) + aLastCompositeFeature = aCompFeat; + ++aFIt; + } + + // collect the list of composite features, containing the last feature; + // these features should be excluded from searching, + // because the feature cannot select sub-shapes from its parent + std::set aEndFeatureParents = ModelAPI_Tools::getParents(theEndFeature); + + int aNbPossibleSelections = 0; + for (; aFIt != aFeatures.end() && *aFIt != theEndFeature; ++aFIt) { + bool isSkipFeature = false; + if (aLastCompositeFeature && aLastCompositeFeature->isSub(*aFIt)) + isSkipFeature = true; + CompositeFeaturePtr aCompFeat = std::dynamic_pointer_cast(*aFIt); + if (aCompFeat) { + ResultPartPtr aPartRes = + std::dynamic_pointer_cast(aCompFeat->firstResult()); + if (!aPartRes) + aLastCompositeFeature = aCompFeat; + if (aEndFeatureParents.find(aCompFeat) != aEndFeatureParents.end()) { + // do not process the parent for the last feature, + // because it cannot select objects from its parent + isSkipFeature = true; + } + } + if (isSkipFeature) + continue; + + std::list anApproproate; + if (ModelGeomAlgo_Shape::findSubshapeByPoint(*aFIt, thePoint, theShape->shapeType(), + anApproproate)) { + std::list::iterator anApIt = anApproproate.begin(); + for (; anApIt != anApproproate.end(); ++anApIt) { + ++aNbPossibleSelections; + + // stop if the target shape and result are found + GeomShapePtr aCurShape = anApIt->mySubshape; + if (!aCurShape) + aCurShape = anApIt->myResult->shape(); + + if (anApIt->myResult->isSame(theResult) && aCurShape->isSame(theShape)) + break; + } + } + } + return aNbPossibleSelections; +} + ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( const std::shared_ptr& theAttrSelect) { @@ -981,8 +1056,57 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( return *this; } - myDumpBuffer << "\"" << aShape->shapeTypeStr() << "\", \"" << - theAttrSelect->namingName() << "\")"; + // how to dump selection: construction features are dumped by name always + bool isDumpByGeom = myGeometricalSelection; + FeaturePtr aSelectedFeature; + if (isDumpByGeom) { + ResultPtr aRes = theAttrSelect->context(); + FeaturePtr aFeature = theAttrSelect->contextFeature(); + if (aRes && !aFeature) + aSelectedFeature = ModelAPI_Feature::feature(aRes->data()->owner()); + isDumpByGeom = aSelectedFeature && aSelectedFeature->isInHistory(); + } + + myDumpBuffer << "\"" << aShape->shapeTypeStr(); + bool aStandardDump = true; + if (isDumpByGeom) { + // check the selected item is a ResultPart; + // in this case it is necessary to get shape with full transformation + // for correct calculation of the middle point + ResultPartPtr aResPart = + std::dynamic_pointer_cast(theAttrSelect->context()); + if (aResPart && aShape->shapeType() == GeomAPI_Shape::COMPOUND) + aShape = aResPart->shape(); + GeomPointPtr aMiddlePoint = aShape->middlePoint(); + // calculate number of features, which could be selected by the same point + FeaturePtr anOwner = ModelAPI_Feature::feature(theAttrSelect->owner()); + int aNbPossibleSelections = possibleSelectionsByPoint(aMiddlePoint, + theAttrSelect->context(), aShape, aSelectedFeature, anOwner); + + // produce the index if the number of applicable features is greater than 1 + std::string anIndex; + if (aNbPossibleSelections > 1) { + std::ostringstream anOutput; + anOutput << "_" << aNbPossibleSelections; + anIndex = anOutput.str(); + } + + myDumpBuffer << anIndex << "\", "; + *this << aMiddlePoint; + aStandardDump = false; + } if (theAttrSelect->isWeakNaming() || + (myWeakNamingSelection && aShape.get() && theAttrSelect->context().get() && + aShape != theAttrSelect->context()->shape())) { // weak naming for local selection only + GeomAlgoAPI_NExplode aNExplode(theAttrSelect->context()->shape(), aShape->shapeType()); + int anIndex = aNExplode.index(aShape); + if (anIndex != 0) { // found a week-naming index, so, export it + myDumpBuffer<<"\", \""<context()->data()->name()<<"\", "<namingName() << "\""; + myDumpBuffer << ")"; return *this; } @@ -1020,8 +1144,7 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<( } else { isAdded = true; } - myDumpBuffer << "model.selection(\"" << - aShape->shapeTypeStr() << "\", \"" << anAttribute->namingName() << "\")"; + *this << anAttribute; } myDumpBuffer << "]";