Back to index

salome-geom  6.5.0
Defines | Functions
GEOMImpl_IBlocksOperations.cxx File Reference
#include <Standard_Stream.hxx>
#include <GEOMImpl_IBlocksOperations.hxx>
#include <GEOMImpl_Types.hxx>
#include <GEOMImpl_BlockDriver.hxx>
#include <GEOMImpl_IBlocks.hxx>
#include <GEOMImpl_IBlockTrsf.hxx>
#include <GEOMImpl_CopyDriver.hxx>
#include <GEOMImpl_Block6Explorer.hxx>
#include <GEOMImpl_IShapesOperations.hxx>
#include <GEOM_Function.hxx>
#include <GEOM_PythonDump.hxx>
#include <GEOMAlgo_GlueAnalyser.hxx>
#include <GEOMAlgo_CoupleOfShapes.hxx>
#include <GEOMAlgo_ListOfCoupleOfShapes.hxx>
#include <GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx>
#include <BlockFix_CheckTool.hxx>
#include <Basics_OCCTVersion.hxx>
#include "utilities.h"
#include <OpUtil.hxx>
#include <Utils_ExceptHandlers.hxx>
#include <TFunction_DriverTable.hxx>
#include <TFunction_Driver.hxx>
#include <TFunction_Logbook.hxx>
#include <TDataStd_Integer.hxx>
#include <TDF_Tool.hxx>
#include <BRep_Tool.hxx>
#include <BRep_Builder.hxx>
#include <BRepTools.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <BRepGProp.hxx>
#include <BRepBndLib.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepClass_FaceClassifier.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <TopAbs.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_Array1OfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_DataMapOfShapeInteger.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
#include <Bnd_Box.hxx>
#include <GProp_GProps.hxx>
#include <Geom_Surface.hxx>
#include <ShapeAnalysis_Surface.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_Array2OfInteger.hxx>
#include <Precision.hxx>
#include <Standard_Failure.hxx>
#include <Standard_ErrorHandler.hxx>

Go to the source code of this file.

Defines

#define REL_NOT_CONNECTED   0
#define REL_OK   1
#define REL_NOT_GLUED   2
#define REL_COLLISION_VV   3
#define REL_COLLISION_FF   4
#define REL_COLLISION_EE   5
#define REL_UNKNOWN   6

Functions

 Handle (GEOM_Object) GEOMImpl_IBlocksOperations
 MakeQuad.
void AddBlocksFromOld (const TopoDS_Shape &theShape, TopTools_ListOfShape &BLO, TopTools_ListOfShape &NOT, TopTools_ListOfShape &DEG, TopTools_ListOfShape &SEA)
Standard_Integer BlocksRelation (const TopoDS_Shape &theBlock1, const TopoDS_Shape &theBlock2)
void FindConnected (const Standard_Integer theBlockIndex, const TColStd_Array2OfInteger &theRelations, TColStd_MapOfInteger &theProcessedMap, TColStd_MapOfInteger &theConnectedMap)
Standard_Boolean HasAnyConnection (const Standard_Integer theBlockIndex, const TColStd_MapOfInteger &theWith, const TColStd_Array2OfInteger &theRelations, TColStd_MapOfInteger &theProcessedMap)
 Handle (TColStd_HSequenceOfTransient) GEOMImpl_IBlocksOperations
 ExplodeCompoundOfBlocks.

Define Documentation

#define REL_COLLISION_EE   5

Definition at line 1914 of file GEOMImpl_IBlocksOperations.cxx.

#define REL_COLLISION_FF   4

Definition at line 1913 of file GEOMImpl_IBlocksOperations.cxx.

#define REL_COLLISION_VV   3

Definition at line 1912 of file GEOMImpl_IBlocksOperations.cxx.

#define REL_NOT_CONNECTED   0

Definition at line 1909 of file GEOMImpl_IBlocksOperations.cxx.

#define REL_NOT_GLUED   2

Definition at line 1911 of file GEOMImpl_IBlocksOperations.cxx.

#define REL_OK   1

Definition at line 1910 of file GEOMImpl_IBlocksOperations.cxx.

#define REL_UNKNOWN   6

Definition at line 1915 of file GEOMImpl_IBlocksOperations.cxx.


Function Documentation

void AddBlocksFromOld ( const TopoDS_Shape &  theShape,
TopTools_ListOfShape &  BLO,
TopTools_ListOfShape &  NOT,
TopTools_ListOfShape &  DEG,
TopTools_ListOfShape &  SEA 
)

Definition at line 1816 of file GEOMImpl_IBlocksOperations.cxx.

{
  TopAbs_ShapeEnum aType = theShape.ShapeType();
  switch (aType) {
  case TopAbs_COMPOUND:
  case TopAbs_COMPSOLID:
    {
      TopoDS_Iterator It (theShape);
      for (; It.More(); It.Next()) {
        AddBlocksFromOld(It.Value(), BLO, NOT, DEG, SEA);
      }
    }
    break;
  case TopAbs_SOLID:
    {
      TopTools_MapOfShape mapFaces;
      TopExp_Explorer expF (theShape, TopAbs_FACE);
      Standard_Integer nbFaces = 0;
      Standard_Boolean hasNonQuadr = Standard_False;
      Standard_Boolean hasDegenerated = Standard_False;
      Standard_Boolean hasSeam = Standard_False;
      for (; expF.More(); expF.Next()) {
        if (mapFaces.Add(expF.Current())) {
          nbFaces++;
          if (nbFaces > 6) break;

          // Check number of edges in the face
          Standard_Integer nbEdges = 0;
          TopTools_MapOfShape mapEdges;

          // get wire
          TopoDS_Shape aF = expF.Current();
          TopExp_Explorer wires (aF, TopAbs_WIRE);
          if (!wires.More()) {
            // no wire in the face
            hasNonQuadr = Standard_True;
            break;
          }
          TopoDS_Shape aWire = wires.Current();
          wires.Next();
          if (wires.More()) {
            // multiple wires in the face
            hasNonQuadr = Standard_True;
            break;
          }

          // iterate on wire
          BRepTools_WireExplorer aWE (TopoDS::Wire(aWire), TopoDS::Face(aF));
          for (; aWE.More(); aWE.Next(), nbEdges++) {
            if (BRep_Tool::Degenerated(aWE.Current())) {
              // degenerated edge found
              hasDegenerated = Standard_True;
//              break;
            }
            if (mapEdges.Contains(aWE.Current())) {
              // seam edge found
              hasSeam = Standard_True;
//              break;
            }
            mapEdges.Add(aWE.Current());
          }
          if (nbEdges != 4) {
            hasNonQuadr = Standard_True;
          }
        }
      }
      if (nbFaces == 6) {
        if (hasDegenerated || hasSeam) {
          if (hasDegenerated) {
            DEG.Append(theShape);
          }
          if (hasSeam) {
            SEA.Append(theShape);
          }
        } else if (hasNonQuadr) {
          NOT.Append(theShape);
        } else {
          BLO.Append(theShape);
        }
      } else {
        NOT.Append(theShape);
      }
    }
    break;
  default:
    NOT.Append(theShape);
  }
}

Here is the caller graph for this function:

Standard_Integer BlocksRelation ( const TopoDS_Shape &  theBlock1,
const TopoDS_Shape &  theBlock2 
)

Definition at line 1917 of file GEOMImpl_IBlocksOperations.cxx.

{
  // Compare bounding boxes before calling BRepExtrema_DistShapeShape
  Standard_Real Xmin1, Ymin1, Zmin1, Xmax1, Ymax1, Zmax1;
  Standard_Real Xmin2, Ymin2, Zmin2, Xmax2, Ymax2, Zmax2;
  Bnd_Box B1, B2;
  BRepBndLib::Add(theBlock1, B1);
  BRepBndLib::Add(theBlock2, B2);
  B1.Get(Xmin1, Ymin1, Zmin1, Xmax1, Ymax1, Zmax1);
  B2.Get(Xmin2, Ymin2, Zmin2, Xmax2, Ymax2, Zmax2);
  if (Xmax2 < Xmin1 || Xmax1 < Xmin2 ||
      Ymax2 < Ymin1 || Ymax1 < Ymin2 ||
      Zmax2 < Zmin1 || Zmax1 < Zmin2) {
    return REL_NOT_CONNECTED;
  }

  BRepExtrema_DistShapeShape dst (theBlock1, theBlock2);
  if (!dst.IsDone()) {
    return REL_UNKNOWN;
  }

  if (dst.Value() > Precision::Confusion()) {
    return REL_NOT_CONNECTED;
  }

  if (dst.InnerSolution()) {
    return REL_COLLISION_VV;
  }

  Standard_Integer nbSol = dst.NbSolution();
  Standard_Integer relation = REL_OK;
  Standard_Integer nbVerts = 0;
  Standard_Integer nbEdges = 0;
  Standard_Integer sol = 1;
  for (; sol <= nbSol; sol++) {
    BRepExtrema_SupportType supp1 = dst.SupportTypeShape1(sol);
    BRepExtrema_SupportType supp2 = dst.SupportTypeShape2(sol);
    if (supp1 == BRepExtrema_IsVertex && supp2 == BRepExtrema_IsVertex) {
      nbVerts++;
    } else if (supp1 == BRepExtrema_IsInFace || supp2 == BRepExtrema_IsInFace) {
      return REL_COLLISION_FF;
    } else if (supp1 == BRepExtrema_IsOnEdge && supp2 == BRepExtrema_IsOnEdge) {
      nbEdges++;
    } else if ((supp1 == BRepExtrema_IsOnEdge && supp2 == BRepExtrema_IsVertex) ||
               (supp2 == BRepExtrema_IsOnEdge && supp1 == BRepExtrema_IsVertex)) {
      relation = REL_COLLISION_EE;
    } else {
    }
  }

  if (relation != REL_OK) {
    return relation;
  }

  TColStd_Array1OfInteger vertSol (1, nbVerts);
  TopTools_Array1OfShape V1 (1, nbVerts);
  TopTools_Array1OfShape V2 (1, nbVerts);
  Standard_Integer ivs = 0;
  for (sol = 1; sol <= nbSol; sol++) {
    if (dst.SupportTypeShape1(sol) == BRepExtrema_IsVertex &&
        dst.SupportTypeShape2(sol) == BRepExtrema_IsVertex) {
      TopoDS_Vertex Vcur = TopoDS::Vertex(dst.SupportOnShape1(sol));
      // Check, that this vertex is far enough from other solution vertices.
      Standard_Integer ii = 1;
      for (; ii <= ivs; ii++) {
        if (BRepTools::Compare(TopoDS::Vertex(V1(ii)), Vcur)) {
          continue;
        }
      }
      ivs++;
      vertSol(ivs) = sol;
      V1(ivs) = Vcur;
      V2(ivs) = dst.SupportOnShape2(sol);
    }
  }

  // As we deal only with quadrangles,
  // 2, 3 or 4 vertex solutions can be found.
  if (ivs <= 1) {
    if (nbEdges > 0) {
      return REL_COLLISION_FF;
    }
    return REL_NOT_CONNECTED;
  }
  if (ivs > 4) {
    return REL_UNKNOWN;
  }

  // Check sharing of coincident entities.
  if (ivs == 2 || ivs == 3) {
    // Map vertices and edges of the blocks
    TopTools_IndexedDataMapOfShapeListOfShape MVE1, MVE2;
    GEOMImpl_Block6Explorer::MapShapesAndAncestors
      (theBlock1, TopAbs_VERTEX, TopAbs_EDGE, MVE1);
    GEOMImpl_Block6Explorer::MapShapesAndAncestors
      (theBlock2, TopAbs_VERTEX, TopAbs_EDGE, MVE2);

    if (ivs == 2) {
      // Find common edge
      TopoDS_Shape anEdge1, anEdge2;
      GEOMImpl_Block6Explorer::FindEdge(anEdge1, V1(1), V1(2), MVE1);
      if (anEdge1.IsNull()) return REL_UNKNOWN;

      GEOMImpl_Block6Explorer::FindEdge(anEdge2, V2(1), V2(2), MVE2);
      if (anEdge2.IsNull()) return REL_UNKNOWN;

      if (!anEdge1.IsSame(anEdge2)) return REL_NOT_GLUED;

    } else { // ivs == 3
      // Find common edges
      Standard_Integer e1_v1 = 1;
      Standard_Integer e1_v2 = 2;
      Standard_Integer e2_v1 = 3;
      Standard_Integer e2_v2 = 1;

      TopoDS_Shape anEdge11, anEdge12;
      GEOMImpl_Block6Explorer::FindEdge(anEdge11, V1(e1_v1), V1(e1_v2), MVE1);
      if (anEdge11.IsNull()) {
        e1_v2 = 3;
        e2_v1 = 2;
        GEOMImpl_Block6Explorer::FindEdge(anEdge11, V1(e1_v1), V1(e1_v2), MVE1);
        if (anEdge11.IsNull()) return REL_UNKNOWN;
      }
      GEOMImpl_Block6Explorer::FindEdge(anEdge12, V1(e2_v1), V1(e2_v2), MVE1);
      if (anEdge12.IsNull()) {
        e2_v2 = 5 - e2_v1;
        GEOMImpl_Block6Explorer::FindEdge(anEdge12, V1(e2_v1), V1(e2_v2), MVE1);
        if (anEdge12.IsNull()) return REL_UNKNOWN;
      }

      TopoDS_Shape anEdge21, anEdge22;
      GEOMImpl_Block6Explorer::FindEdge(anEdge21, V2(e1_v1), V2(e1_v2), MVE2);
      if (anEdge21.IsNull()) return REL_UNKNOWN;
      GEOMImpl_Block6Explorer::FindEdge(anEdge22, V2(e2_v1), V2(e2_v2), MVE2);
      if (anEdge22.IsNull()) return REL_UNKNOWN;

      // Check of edges coincidence (with some precision) have to be done here
      // if (!anEdge11.IsEqual(anEdge21)) return REL_UNKNOWN;
      // if (!anEdge12.IsEqual(anEdge22)) return REL_UNKNOWN;

      // Check of edges sharing
      if (!anEdge11.IsSame(anEdge21)) return REL_NOT_GLUED;
      if (!anEdge12.IsSame(anEdge22)) return REL_NOT_GLUED;
    }
  }

  if (ivs == 4) {
    // Map vertices and faces of the blocks
    TopTools_IndexedDataMapOfShapeListOfShape MVF1, MVF2;
    GEOMImpl_Block6Explorer::MapShapesAndAncestors
      (theBlock1, TopAbs_VERTEX, TopAbs_FACE, MVF1);
    GEOMImpl_Block6Explorer::MapShapesAndAncestors
      (theBlock2, TopAbs_VERTEX, TopAbs_FACE, MVF2);

    TopoDS_Shape aFace1, aFace2;
    GEOMImpl_Block6Explorer::FindFace(aFace1, V1(1), V1(2), V1(3), V1(4), MVF1);
    if (aFace1.IsNull()) return REL_UNKNOWN;
    GEOMImpl_Block6Explorer::FindFace(aFace2, V2(1), V2(2), V2(3), V2(4), MVF2);
    if (aFace2.IsNull()) return REL_UNKNOWN;

    // Check of faces coincidence (with some precision) have to be done here
    // if (!aFace1.IsEqual(aFace2)) return REL_UNKNOWN;

    // Check of faces sharing
    if (!aFace1.IsSame(aFace2)) return REL_NOT_GLUED;
  }

  return REL_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void FindConnected ( const Standard_Integer  theBlockIndex,
const TColStd_Array2OfInteger &  theRelations,
TColStd_MapOfInteger &  theProcessedMap,
TColStd_MapOfInteger &  theConnectedMap 
)

Definition at line 2088 of file GEOMImpl_IBlocksOperations.cxx.

{
  theConnectedMap.Add(theBlockIndex);
  theProcessedMap.Add(theBlockIndex);

  Standard_Integer nbBlocks = theRelations.ColLength();
  Standard_Integer col = 1;
  for (; col <= nbBlocks; col++) {
    if (theRelations(theBlockIndex, col) == REL_OK ||
        theRelations(theBlockIndex, col) == REL_NOT_GLUED) {
      if (!theProcessedMap.Contains(col)) {
        FindConnected(col, theRelations, theProcessedMap, theConnectedMap);
      }
    }
  }
}

Here is the caller graph for this function:

MakeQuad.

GetObject.

MakeMultiTransformation2D.

MakeMultiTransformation1D.

GetBlockByParts.

GetBlockNearPoint.

CheckAndImprove.

RemoveExtraEdges.

GetShapesNearPoint.

GetFaceByNormale.

GetFaceNearPoint.

GetOppositeFace.

GetFaceByEdges.

GetFaceByPoints.

GetEdgeNearPoint.

GetEdge.

GetVertexNearPoint.

GetPoint.

MakeBlockCompound.

MakeHexa2Faces.

MakeHexa.

MakeQuad4Vertices.

MakeQuad2Edges.

Definition at line 133 of file GEOMImpl_IBlocksOperations.cxx.

{
  SetErrorCode(KO);

  if (theEdge1.IsNull() || theEdge2.IsNull() ||
      theEdge3.IsNull() || theEdge4.IsNull()) return NULL;

  //Add a new Face object
  Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);

  //Add a new Face function
  Handle(GEOM_Function) aFunction =
    aFace->AddFunction(GEOMImpl_BlockDriver::GetID(), BLOCK_FACE_FOUR_EDGES);

  //Check if the function is set correctly
  if (aFunction->GetDriverGUID() != GEOMImpl_BlockDriver::GetID()) return NULL;

  GEOMImpl_IBlocks aPI (aFunction);

  Handle(GEOM_Function) aRef1 = theEdge1->GetLastFunction();
  Handle(GEOM_Function) aRef2 = theEdge2->GetLastFunction();
  Handle(GEOM_Function) aRef3 = theEdge3->GetLastFunction();
  Handle(GEOM_Function) aRef4 = theEdge4->GetLastFunction();
  if (aRef1.IsNull() || aRef2.IsNull() ||
      aRef3.IsNull() || aRef4.IsNull()) return NULL;

  Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
  aShapesSeq->Append(aRef1);
  aShapesSeq->Append(aRef2);
  aShapesSeq->Append(aRef3);
  aShapesSeq->Append(aRef4);

  aPI.SetShapes(aShapesSeq);

  //Compute the Face value
  try {
#if OCC_VERSION_LARGE > 0x06010000
    OCC_CATCH_SIGNALS;
#endif
    if (!GetSolver()->ComputeFunction(aFunction)) {
      SetErrorCode("Block driver failed to compute a face");
      return NULL;
    }
  }
  catch (Standard_Failure) {
    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
    SetErrorCode(aFail->GetMessageString());
    return NULL;
  }

  //Make a Python command
  GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeQuad("
    << theEdge1 << ", " << theEdge2 << ", " << theEdge3 << ", " << theEdge4 << ")";

  SetErrorCode(OK);
  return aFace;
}

Here is the call graph for this function:

Handle ( TColStd_HSequenceOfTransient  )

ExplodeCompoundOfBlocks.

Propagate.

GetBlocksByParts.

Definition at line 2632 of file GEOMImpl_IBlocksOperations.cxx.

{
  SetErrorCode(KO);

  if (theCompound.IsNull()) return NULL;
  TopoDS_Shape aBlockOrComp = theCompound->GetValue();
  if (aBlockOrComp.IsNull()) return NULL;

  Handle(TColStd_HSequenceOfTransient) aBlocks = new TColStd_HSequenceOfTransient;
  Handle(GEOM_Object) anObj;
  Handle(GEOM_Function) aFunction;

  TopTools_MapOfShape mapShape;
  TCollection_AsciiString anAsciiList, anEntry;

  // Map shapes
  TopTools_IndexedMapOfShape anIndices;
  TopExp::MapShapes(aBlockOrComp, anIndices);
  Handle(TColStd_HArray1OfInteger) anArray;

  // Explode
  try {
#if OCC_VERSION_LARGE > 0x06010000
    OCC_CATCH_SIGNALS;
#endif
    TopExp_Explorer exp (aBlockOrComp, TopAbs_SOLID);
    for (; exp.More(); exp.Next()) {
      if (mapShape.Add(exp.Current())) {
        TopoDS_Shape aSolid = exp.Current();

        TopTools_MapOfShape mapFaces;
        TopExp_Explorer expF (aSolid, TopAbs_FACE);
        Standard_Integer nbFaces = 0;
        for (; expF.More(); expF.Next()) {
          if (mapFaces.Add(expF.Current())) {
            nbFaces++;
          }
        }

        if (theMinNbFaces <= nbFaces && nbFaces <= theMaxNbFaces) {
          anArray = new TColStd_HArray1OfInteger(1,1);
          anArray->SetValue(1, anIndices.FindIndex(aSolid));
          anObj = GetEngine()->AddSubShape(theCompound, anArray);
          aBlocks->Append(anObj);

          //Make a Python command
          TDF_Tool::Entry(anObj->GetEntry(), anEntry);
          anAsciiList += anEntry + ", ";
        }
      }
    }
  }
  catch (Standard_Failure) {
    Handle(Standard_Failure) aFail = Standard_Failure::Caught();
    SetErrorCode(aFail->GetMessageString());
    return aBlocks;
  }

  if (aBlocks->IsEmpty()) {
    SetErrorCode("There are no specified blocks in the given shape");
    return aBlocks;
  }

  anAsciiList.Trunc(anAsciiList.Length() - 2);

  //The explode doesn't change object so no new function is required.
  aFunction = theCompound->GetLastFunction();

  //Make a Python command
  GEOM::TPythonDump(aFunction, /*append=*/true)
    << "[" << anAsciiList.ToCString() << "] = geompy.MakeBlockExplode("
    << theCompound << ", " << theMinNbFaces << ", " << theMaxNbFaces << ")";

  SetErrorCode(OK);
  return aBlocks;
}

Here is the call graph for this function:

Standard_Boolean HasAnyConnection ( const Standard_Integer  theBlockIndex,
const TColStd_MapOfInteger &  theWith,
const TColStd_Array2OfInteger &  theRelations,
TColStd_MapOfInteger &  theProcessedMap 
)

Definition at line 2108 of file GEOMImpl_IBlocksOperations.cxx.

{
  theProcessedMap.Add(theBlockIndex);

  Standard_Integer nbBlocks = theRelations.ColLength();
  Standard_Integer col = 1;
  for (; col <= nbBlocks; col++) {
    if (theRelations(theBlockIndex, col) != REL_NOT_CONNECTED) {
      if (!theProcessedMap.Contains(col)) {
        if (theWith.Contains(col))
          return Standard_True;
        if (HasAnyConnection(col, theWith, theRelations, theProcessedMap))
          return Standard_True;
      }
    }
  }

  return Standard_False;
}

Here is the caller graph for this function: