NCollection_List<TopoDS_Shape> aNew; // very new connected to new connected
NCollection_List<TopoDS_Shape>::Iterator aNotIter(aNotConnected);
while(aNotIter.More()) {
+ // optimization to avoid TopExp_Explorer double-cycle, collect all vertices in the list first
+ NCollection_List<TopoDS_Shape> aNotVertices;
+ for(TopExp_Explorer anExp1(aNotIter.Value(), TopAbs_VERTEX); anExp1.More(); anExp1.Next()) {
+ aNotVertices.Append(anExp1.Current());
+ }
+
bool aConnected = false;
NCollection_List<TopoDS_Shape>::Iterator aNewIter(aNewConnected);
for(; !aConnected && aNewIter.More(); aNewIter.Next()) {
// checking topological connecion of aNotIter and aNewIter (if shapes are connected, vertices are connected for sure)
- TopExp_Explorer anExp1(aNotIter.Value(), TopAbs_VERTEX);
- for(; !aConnected && anExp1.More(); anExp1.Next()) {
- TopExp_Explorer anExp2(aNewIter.Value(), TopAbs_VERTEX);
- for(; anExp2.More(); anExp2.Next()) {
- if (anExp1.Current().IsSame(anExp2.Current())) {
+ TopExp_Explorer anExp2(aNewIter.Value(), TopAbs_VERTEX);
+ for(; !aConnected && anExp2.More(); anExp2.Next()) {
+ NCollection_List<TopoDS_Shape>::Iterator aNotIter(aNotVertices);
+ for(; aNotIter.More(); aNotIter.Next()) {
+ if (aNotIter.Value().IsSame(anExp2.Current())) {
aConnected = true;
break;
}
{
myBuilder = new Model_BodyBuilder(this);
myWasConcealed = false;
+ myConnect = ConnectionNotComputed;
}
void Model_ResultBody::initAttributes()
/// Flag that stores the previous state of "concealed": if it is changed,
/// The event is used to redisplay the body.
bool myWasConcealed;
+
public:
/// Request for initialization of data model of the result: adding all attributes
virtual void initAttributes();
ModelAPI_ResultBody::ModelAPI_ResultBody()
: myBuilder(0)
{
+ myConnect = ConnectionNotComputed;
}
ModelAPI_ResultBody::~ModelAPI_ResultBody()
const bool theIsStoreSameShapes)
{
myBuilder->store(theShape, theIsStoreSameShapes);
+ myConnect = ConnectionNotComputed;
static Events_Loop* aLoop = Events_Loop::loop();
static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
const std::shared_ptr<GeomAPI_Shape>& theToShape)
{
myBuilder->storeGenerated(theFromShape, theToShape);
+ myConnect = ConnectionNotComputed;
static Events_Loop* aLoop = Events_Loop::loop();
static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
const int theDecomposeSolidsTag)
{
myBuilder->storeModified(theOldShape, theNewShape, theDecomposeSolidsTag);
+ myConnect = ConnectionNotComputed;
static Events_Loop* aLoop = Events_Loop::loop();
static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
void ModelAPI_ResultBody::storeWithoutNaming(const std::shared_ptr<GeomAPI_Shape>& theShape)
{
myBuilder->storeWithoutNaming(theShape);
+ myConnect = ConnectionNotComputed;
static Events_Loop* aLoop = Events_Loop::loop();
static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
{
myBuilder->loadDisconnectedVertexes(theShape, theName, theTag);
}
+
+bool ModelAPI_ResultBody::isConnectedTopology()
+{
+ if (myConnect == ConnectionNotComputed) {
+ myConnect = shape()->isConnectedTopology() ? IsConnected : IsNotConnected;
+ }
+ return myConnect == IsConnected;
+}
return RESULT_BODY_COLOR;
}
+ /// Iternal enumeration for storage the information of connected topology flag
+ enum ConnectedTopologyFlag {
+ ConnectionNotComputed, ///< not yet computed
+ IsConnected, ///< the topology is connected
+ IsNotConnected ///< the topology is connected
+ };
+ /// Keeps (not persistently) the connected topology flag
+ ConnectedTopologyFlag myConnect;
+
/// \brief Stores the shape (called by the execution method).
/// param[in] theShape shape to store.
/// param[in] theIsStoreSameShapes if false stores reference to the same shape if it is already in document.
// is equal to the given shape
MODELAPI_EXPORT virtual bool isLatestEqual(const std::shared_ptr<GeomAPI_Shape>& theShape) = 0;
+ /// Returns true is the topology is connected. Cashes this information for the current shape,
+ /// so it is more effective to use this method than directly GeomAPI_Shape.
+ MODELAPI_EXPORT virtual bool isConnectedTopology();
+
protected:
/// Default constructor accessible only from Model_Objects
MODELAPI_EXPORT ModelAPI_ResultBody();
GeomShapePtr aShape = aResult->shape();
if(aShape.get()) {
switch(aShape->shapeType()) {
- case GeomAPI_Shape::COMPOUND: return aShape->isConnectedTopology() ?
- QIcon(":pictures/compoundofsolids.png") : QIcon(":pictures/compound.png");
+ case GeomAPI_Shape::COMPOUND: {
+ ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aResult);
+ if (aBody.get() && aBody->isConnectedTopology())
+ return QIcon(":pictures/compoundofsolids.png");
+ return QIcon(":pictures/compound.png");
+ }
case GeomAPI_Shape::COMPSOLID: return QIcon(":pictures/compsolid.png");
case GeomAPI_Shape::SOLID: return QIcon(":pictures/solid.png");
case GeomAPI_Shape::SHELL: return QIcon(":pictures/shell.png");