* \brief Interface to the edge object
*/
-class GEOMAPI_EXPORT GeomAPI_Wire : public GeomAPI_Shape
+class GeomAPI_Wire : public GeomAPI_Shape
{
public:
/// Creation of empty (null) shape
- GeomAPI_Wire();
+ GEOMAPI_EXPORT GeomAPI_Wire();
- virtual bool isVertex() const
+ GEOMAPI_EXPORT virtual bool isVertex() const
{
return false;
}
/// Returns whether the shape is an edge
- virtual bool isEdge() const
+ GEOMAPI_EXPORT virtual bool isEdge() const
{
return false;
}
- void addEdge(boost::shared_ptr<GeomAPI_Shape> theEdge);
- std::list<boost::shared_ptr<GeomAPI_Shape> > getEdges();
+ GEOMAPI_EXPORT void addEdge(boost::shared_ptr<GeomAPI_Shape> theEdge);
+ GEOMAPI_EXPORT std::list<boost::shared_ptr<GeomAPI_Shape> > getEdges();
/// Returns True if the wire is defined in a plane
- bool hasPlane() const { return myOrigin && myNorm && myDirX && myDirY; }
+ GEOMAPI_EXPORT bool hasPlane() const { return myOrigin && myNorm && myDirX && myDirY; }
/// Set/Get origin point
- void setOrigin(const boost::shared_ptr<GeomAPI_Pnt>& theOrigin) { myOrigin = theOrigin; }
- boost::shared_ptr<GeomAPI_Pnt> origin() const { return myOrigin; }
+ GEOMAPI_EXPORT void setOrigin(const boost::shared_ptr<GeomAPI_Pnt>& theOrigin)
+ { myOrigin = theOrigin; }
+ GEOMAPI_EXPORT boost::shared_ptr<GeomAPI_Pnt> origin() const { return myOrigin; }
/// Set/Get X direction vector
- void setDirX(const boost::shared_ptr<GeomAPI_Dir>& theDirX) { myDirX = theDirX; }
- boost::shared_ptr<GeomAPI_Dir> dirX() const { return myDirX; }
+ GEOMAPI_EXPORT void setDirX(const boost::shared_ptr<GeomAPI_Dir>& theDirX) { myDirX = theDirX; }
+ GEOMAPI_EXPORT boost::shared_ptr<GeomAPI_Dir> dirX() const { return myDirX; }
/// Set/Get Y direction vector
- void setDirY(const boost::shared_ptr<GeomAPI_Dir>& theDirY) { myDirY = theDirY; }
- boost::shared_ptr<GeomAPI_Dir> dirY() const { return myDirY; }
+ GEOMAPI_EXPORT void setDirY(const boost::shared_ptr<GeomAPI_Dir>& theDirY) { myDirY = theDirY; }
+ GEOMAPI_EXPORT boost::shared_ptr<GeomAPI_Dir> dirY() const { return myDirY; }
/// Set/Get Normal direction vector
- void setNorm(const boost::shared_ptr<GeomAPI_Dir>& theNorm) { myNorm = theNorm; }
- boost::shared_ptr<GeomAPI_Dir> norm() const { return myNorm; }
+ GEOMAPI_EXPORT void setNorm(const boost::shared_ptr<GeomAPI_Dir>& theNorm) { myNorm = theNorm; }
+ GEOMAPI_EXPORT boost::shared_ptr<GeomAPI_Dir> norm() const { return myNorm; }
private:
boost::shared_ptr<GeomAPI_Pnt> myOrigin;
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_CompositeFeature.h>
#include <GeomAPI_Shape.h>
+#include <GeomAPI_Wire.h>
+#include <GeomAlgoAPI_SketchBuilder.h>
#include <TNaming_Selector.hxx>
#include <TNaming_NamedShape.hxx>
#include <TNaming_Tool.hxx>
#include <TNaming_Builder.hxx>
#include <TopoDS_Shape.hxx>
-#include <TDataStd_ReferenceList.hxx>
+#include <TDataStd_IntPackedMap.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopExp_Explorer.hxx>
+#include <TDF_LabelMap.hxx>
+#include <BRep_Tool.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS.hxx>
+#include <TColStd_MapOfTransient.hxx>
using namespace std;
myRef.setObject(theObject);
}
+bool Model_AttributeSelection::update()
+{
+ ResultPtr aContext = context();
+ if (aContext->groupName() == ModelAPI_ResultBody::group()) {
+ // body: just a named shape, use selection mechanism from OCCT
+ TNaming_Selector aSelector(myRef.myRef->Label());
+ TDF_LabelMap aScope; // empty means the whole document
+ return aSelector.Solve(aScope) == Standard_True;
+
+ } else if (aContext->groupName() == ModelAPI_ResultConstruction::group()) {
+ // construction: identification by the results indexes, recompute faces and
+ // take the face that more close by the indexes
+ boost::shared_ptr<GeomAPI_Wire> aWirePtr = boost::dynamic_pointer_cast<GeomAPI_Wire>(
+ boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext)->shape());
+ if (aWirePtr && aWirePtr->hasPlane()) {
+ // If this is a wire with plane defined thin it is a sketch-like object
+ std::list<boost::shared_ptr<GeomAPI_Shape> > aFaces;
+ GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(),
+ aWirePtr->dirY(), aWirePtr->norm(), aWirePtr, aFaces);
+ if (aFaces.empty()) // no faces, update can not work correctly
+ return false;
+ // if there is no edges indexes, any face can be used: take the first
+ boost::shared_ptr<Model_Data> aData =
+ boost::dynamic_pointer_cast<Model_Data>(owner()->data());
+ TDF_Label aLab = aData->label();
+ Handle(TDataStd_IntPackedMap) aSubIds;
+ boost::shared_ptr<GeomAPI_Shape> aNewSelected;
+ if (!aLab.FindAttribute(TDataStd_IntPackedMap::GetID(), aSubIds) || aSubIds->Extent() == 0) {
+ aNewSelected = *(aFaces.begin());
+ } else { // searching for most looks-like initial face by the indexes
+ // prepare edges of the current resut for the fast searching
+ TColStd_MapOfTransient allCurves;
+ FeaturePtr aContextFeature = owner()->document()->feature(aContext);
+ CompositeFeaturePtr aComposite =
+ boost::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aContextFeature);
+ if (!aComposite) // must be composite at least for the current implementation
+ return false;
+ const int aSubNum = aComposite->numberOfSubs();
+ for(int a = 0; a < aSubNum; a++) {
+ if (aSubIds->Contains(aComposite->subFeatureId(a))) {
+ FeaturePtr aSub = aComposite->subFeature(a);
+ const std::list<boost::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
+ std::list<boost::shared_ptr<ModelAPI_Result> >::const_iterator aRes = aResults.cbegin();
+ for(; aRes != aResults.cend(); aRes++) {
+ ResultConstructionPtr aConstr =
+ boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
+ if (aConstr->shape()) {
+ const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
+ TopoDS_Edge anEdge = TopoDS::Edge(aResShape);
+ if (!anEdge.IsNull()) {
+ Standard_Real aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+ allCurves.Add(aCurve);
+ }
+ }
+ }
+ }
+ }
+ // iterate new result faces and searching for these edges
+ std::list<boost::shared_ptr<GeomAPI_Shape> >::iterator aFacesIter = aFaces.begin();
+ double aBestFound = 0; // best percentage of found edges
+ for(; aFacesIter != aFaces.end(); aFacesIter++) {
+ int aFound = 0, aNotFound = 0;
+ TopExp_Explorer anEdgesExp((*aFacesIter)->impl<TopoDS_Shape>(), TopAbs_EDGE);
+ for(; anEdgesExp.More(); anEdgesExp.Next()) {
+ TopoDS_Edge anEdge = TopoDS::Edge(anEdgesExp.Current());
+ if (!anEdge.IsNull()) {
+ Standard_Real aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+ if (allCurves.Contains(aCurve)) {
+ aFound++;
+ } else {
+ aNotFound++;
+ }
+ }
+ }
+ if (aFound + aNotFound != 0) {
+ double aPercentage = double(aFound) / double(aFound + aNotFound);
+ if (aPercentage > aBestFound) {
+ aBestFound = aPercentage;
+ aNewSelected = *aFacesIter;
+ }
+ }
+ }
+ if (aNewSelected) { // store this new selection
+ selectConstruction(aContext, aNewSelected);
+ return true;
+ }
+ }
+ }
+ }
+ return false; // unknown case
+}
+
+
void Model_AttributeSelection::selectBody(
const ResultPtr& theContext, const boost::shared_ptr<GeomAPI_Shape>& theSubShape)
{
TDF_Label aLab = aData->label();
// identify the reuslts of sub-object of the composite by edges
const TopoDS_Shape& aSubShape = theSubShape->impl<TopoDS_Shape>();
- TopTools_MapOfShape allEdges;
+ TColStd_MapOfTransient allCurves;
for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_EDGE); anEdgeExp.More(); anEdgeExp.Next()) {
- allEdges.Add(anEdgeExp.Current());
+ TopoDS_Edge anEdge = TopoDS::Edge(anEdgeExp.Current());
+ Standard_Real aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+ allCurves.Add(aCurve);
}
// iterate and store the result ids of sub-elements
- Handle(TDataStd_ReferenceList) aRefs = TDataStd_ReferenceList::Set(aLab);
+ Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab);
const int aSubNum = aComposite->numberOfSubs();
for(int a = 0; a < aSubNum; a++) {
FeaturePtr aSub = aComposite->subFeature(a);
boost::dynamic_pointer_cast<ModelAPI_ResultConstruction>(*aRes);
if (aConstr->shape()) {
const TopoDS_Shape& aResShape = aConstr->shape()->impl<TopoDS_Shape>();
- if (allEdges.Contains(aResShape)) {
- boost::shared_ptr<Model_Data> aSubData = boost::dynamic_pointer_cast<Model_Data>(aSub->data());
- TDF_Label aSubLab = aSubData->label();
- aRefs->Append(aSubLab);
+ TopoDS_Edge anEdge = TopoDS::Edge(aResShape);
+ if (!anEdge.IsNull()) {
+ Standard_Real aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+ if (allCurves.Contains(aCurve)) {
+ boost::shared_ptr<Model_Data> aSubData = boost::dynamic_pointer_cast<Model_Data>(aSub->data());
+ TDF_Label aSubLab = aSubData->label();
+ aRefs->Add(aComposite->subFeatureId(a));
+ }
}
}
}