AttributeSelectionListPtr aFaceRefs = selectionList(FeaturesPlugin_Extrusion::LIST_ID());
// for each selected face generate a result
- int anIndex = 0;
+ int anIndex = 0, aResultIndex = 0;
for(; anIndex < aFaceRefs->size(); anIndex++) {
std::shared_ptr<ModelAPI_AttributeSelection> aFaceRef = aFaceRefs->value(anIndex);
- if (!aFaceRef.get())
- continue;
- std::shared_ptr<GeomAPI_Shape> aFace = aFaceRef->value();
- if (!aFace.get())
- continue;
ResultPtr aContextRes = aFaceRef->context();
std::shared_ptr<GeomAPI_Shape> aContext = aContextRes->shape();
if (!aContext.get()) {
setError(aContextError);
break;
}
-
double aSize = real(FeaturesPlugin_Extrusion::SIZE_ID())->value();
if (boolean(FeaturesPlugin_Extrusion::REVERSE_ID())->value())
aSize = -aSize;
- ResultBodyPtr aResultBody = document()->createBody(data(), anIndex);
- GeomAlgoAPI_Extrusion aFeature(aFace, aSize);
- if(!aFeature.isDone()) {
- static const std::string aFeatureError = "Extrusion algorithm failed";
- setError(aFeatureError);
- break;
+ std::shared_ptr<GeomAPI_Shape> aValueFace = aFaceRef->value();
+ int aFacesNum = -1; // this mean that "aFace" is used
+ ResultConstructionPtr aConstruction =
+ std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContextRes);
+ if (!aValueFace.get()) { // this may be the whole sketch result selected, check and get faces
+ if (aConstruction.get()) {
+ aFacesNum = aConstruction->facesNum();
+ } else {
+ static const std::string aFaceError = "Can not find basis for extrusion";
+ setError(aFaceError);
+ break;
+ }
}
- // Check if shape is valid
- if (aFeature.shape()->isNull()) {
- static const std::string aShapeError = "Resulting shape is Null";
- setError(aShapeError);
- break;
+ for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
+ ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+ std::shared_ptr<GeomAPI_Shape> aFace =
+ aFacesNum == -1 ? aValueFace : aConstruction->face(aFaceIndex);
+ GeomAlgoAPI_Extrusion aFeature(aFace, aSize);
+ if(!aFeature.isDone()) {
+ static const std::string aFeatureError = "Extrusion algorithm failed";
+ setError(aFeatureError);
+ break;
+ }
+
+ // Check if shape is valid
+ if (aFeature.shape()->isNull()) {
+ static const std::string aShapeError = "Resulting shape is Null";
+ setError(aShapeError);
+ break;
+ }
+ if(!aFeature.isValid()) {
+ std::string aFeatureError = "Warning: resulting shape is not valid";
+ setError(aFeatureError);
+ break;
+ }
+ //LoadNamingDS
+ LoadNamingDS(aFeature, aResultBody, aFace, aContext);
+
+ setResult(aResultBody, aResultIndex);
+ aResultIndex++;
+
+ if (aFacesNum == -1)
+ break;
}
- if(!aFeature.isValid()) {
- std::string aFeatureError = "Warning: resulting shape is not valid";
- setError(aFeatureError);
- break;
- }
- //LoadNamingDS
- LoadNamingDS(aFeature, aResultBody, aFace, aContext);
-
- setResult(aResultBody, anIndex);
}
// remove the rest results if there were produced in the previous pass
- removeResults(anIndex);
+ removeResults(aResultIndex);
}
//============================================================================
static const int kSTART_VERTEX_DELTA = 1000000;
// identifier that there is simple reference: selection equals to context
Standard_GUID kSIMPLE_REF_ID("635eacb2-a1d6-4dec-8348-471fae17cb29");
+Standard_GUID kCONSTUCTION_SIMPLE_REF_ID("635eacb2-a1d6-4dec-8348-471fae17cb28");
// on this label is stored:
// TNaming_NamedShape - selected shape
const std::shared_ptr<GeomAPI_Shape>& theSubShape)
{
const std::shared_ptr<GeomAPI_Shape>& anOldShape = value();
- bool isOldShape =
+ bool isOldContext = theContext == myRef.value();
+ bool isOldShape = isOldContext &&
(theSubShape == anOldShape || (theSubShape && anOldShape && theSubShape->isEqual(anOldShape)));
if (isOldShape) return; // shape is the same, so context is also unchanged
// update the referenced object if needed
- bool isOldContext = theContext == myRef.value();
-
-
if (!isOldContext)
myRef.setValue(theContext);
// do noth use naming if selected shape is result shape itself, but not sub-shape
TDF_Label aSelLab = selectionLabel();
aSelLab.ForgetAttribute(kSIMPLE_REF_ID);
+ aSelLab.ForgetAttribute(kCONSTUCTION_SIMPLE_REF_ID);
if (theContext->groupName() == ModelAPI_ResultBody::group()) {
// do not select the whole shape for body:it is already must be in the data framework
if (theContext->shape().get() && theContext->shape()->isEqual(theSubShape)) {
selectBody(theContext, theSubShape);
}
} else if (theContext->groupName() == ModelAPI_ResultConstruction::group()) {
- selectConstruction(theContext, theSubShape);
+ if (!theSubShape.get()) {
+ // to sub, so the whole result is selected
+ aSelLab.ForgetAllAttributes(true);
+ TDataStd_UAttribute::Set(aSelLab, kCONSTUCTION_SIMPLE_REF_ID);
+ } else {
+ selectConstruction(theContext, theSubShape);
+ }
}
myIsInitialized = true;
return aResult; // empty result
return aContext->shape();
}
+ if (aSelLab.IsAttribute(kCONSTUCTION_SIMPLE_REF_ID)) { // it is just reference to construction, nothing is in value
+ return aResult; // empty result
+ }
Handle(TNaming_NamedShape) aSelection;
if (selectionLabel().FindAttribute(TNaming_NamedShape::GetID(), aSelection)) {
if (aSelLab.IsAttribute(kSIMPLE_REF_ID)) { // it is just reference to shape, not sub-shape
return aContext->shape() && !aContext->shape()->isNull();
}
+ if (aSelLab.IsAttribute(kCONSTUCTION_SIMPLE_REF_ID)) { // it is just reference to construction, not sub-shape
+ return aContext->shape() && !aContext->shape()->isNull();
+ }
if (aContext->groupName() == ModelAPI_ResultBody::group()) {
// body: just a named shape, use selection mechanism from OCCT
return false;
}
- if (aShapeType == TopAbs_FACE) {
+ if (aShapeType == TopAbs_FACE) { // compound is for the whole sketch selection
// If this is a wire with plane defined thin it is a sketch-like object
std::list<std::shared_ptr<GeomAPI_Shape> > aFaces;
GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(),
std::shared_ptr<GeomAPI_Shape> aSubSh = value();
ResultPtr aCont = context();
aName = "Undefined name";
- if(!aSubSh.get() || aSubSh->isNull() || !aCont.get() || aCont->shape()->isNull())
+ if(!aCont.get() || aCont->shape()->isNull())
return aName;
+ if (!aSubSh.get() || aSubSh->isNull()) { // no subshape, so just the whole feature name
+ return aCont->data()->name();
+ }
TopoDS_Shape aSubShape = aSubSh->impl<TopoDS_Shape>();
TopoDS_Shape aContext = aCont->shape()->impl<TopoDS_Shape>();
#ifdef DEB_NAMING
#include <ModelAPI_AttributeIntArray.h>
#include <Config_PropManager.h>
+#include <GeomAPI_PlanarEdges.h>
+#include <GeomAlgoAPI_SketchBuilder.h>
void Model_ResultConstruction::initAttributes()
{
void Model_ResultConstruction::setShape(std::shared_ptr<GeomAPI_Shape> theShape)
{
- myShape = theShape;
+ if (myShape != theShape) {
+ myShape = theShape;
+ if (theShape.get() && (!myShape.get() || !theShape->isEqual(myShape))) {
+ myFacesUpToDate = false;
+ myFaces.clear();
+ }
+ }
}
std::shared_ptr<GeomAPI_Shape> Model_ResultConstruction::shape()
Model_ResultConstruction::Model_ResultConstruction()
{
myIsInHistory = true;
+ myFacesUpToDate = false;
setIsConcealed(false);
}
{
myIsInHistory = isInHistory;
}
+
+int Model_ResultConstruction::facesNum()
+{
+ if (!myFacesUpToDate) {
+ std::shared_ptr<GeomAPI_PlanarEdges> aWirePtr =
+ std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(myShape);
+ std::list<std::shared_ptr<GeomAPI_Shape> > aFaces;
+ GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(),
+ aWirePtr->dirY(), aWirePtr->norm(), aWirePtr, aFaces);
+ std::list<std::shared_ptr<GeomAPI_Shape> >::iterator aFIter = aFaces.begin();
+ for(; aFIter != aFaces.end(); aFIter++) {
+ std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(*aFIter));
+ if (aFace.get())
+ myFaces.push_back(aFace);
+ }
+ myFacesUpToDate = true;
+ }
+ return myFaces.size();
+}
+
+std::shared_ptr<GeomAPI_Face> Model_ResultConstruction::face(const int theIndex)
+{
+ return myFaces[theIndex];
+}
#include "Model.h"
#include <ModelAPI_ResultConstruction.h>
+#include <vector>
/**\class Model_ResultConstruction
* \ingroup DataModel
{
std::shared_ptr<ModelAPI_Feature> myOwner; ///< owner of this result
std::shared_ptr<GeomAPI_Shape> myShape; ///< shape of this result created "on the fly"
+ bool myFacesUpToDate; ///< is true if faces in myuFaces are computed and up to date
+ std::vector<std::shared_ptr<GeomAPI_Face> > myFaces; ///< stores the up to date faces if they exist
bool myIsInHistory;
public:
/// default color for a result construction
/// Sets the flag that it must be displayed in history (default is true)
MODEL_EXPORT virtual void setIsInHistory(const bool myIsInHistory);
+ /// if the construction result may be used as faces, this method returns not zero number of faces
+ MODEL_EXPORT virtual int facesNum();
+ /// if the construction result may be used as faces, this method returns face by zero based index
+ MODEL_EXPORT virtual std::shared_ptr<GeomAPI_Face> face(const int theIndex);
+
protected:
/// Makes a body on the given feature
Model_ResultConstruction();
}
std::list<std::shared_ptr<ModelAPI_Result> >::iterator aResIter = myResults.begin();
- for(int anIndex = 0; anIndex < theSinceIndex; anIndex++)
+ for(int anIndex = 0; anIndex < theSinceIndex && aResIter != myResults.end(); anIndex++)
aResIter++;
std::list<std::shared_ptr<ModelAPI_Result> >::iterator aNextIter = aResIter;
for(; aNextIter != myResults.end(); aNextIter++) {
#include "ModelAPI_Result.h"
#include <GeomAPI_Shape.h>
+#include <GeomAPI_Face.h>
#include <string>
/// Sets the flag that it must be displayed in history (default is true)
virtual void setIsInHistory(const bool isInHistory) = 0;
+
+ /// if the construction result may be used as faces, this method returns not zero number of faces
+ virtual int facesNum() = 0;
+ /// if the construction result may be used as faces, this method returns face by zero based index
+ virtual std::shared_ptr<GeomAPI_Face> face(const int theIndex) = 0;
};
//! Pointer on feature object