//=======================================================================
//function : Perform
//purpose  : 
//=======================================================================
void ShHealOper_ShapeProcess::Perform(const TopoDS_Shape& theOldShape, 
                                           TopoDS_Shape& theNewShape)
{
  
  myMapModifications.Clear();
  //ShapeProcessAPI_ApplySequence aOperations(myResource,myPrefix.ToCString());
  //myDone = Standard_False;
  myOperations.ClearMap();
  ShapeAnalysis_ShapeTolerance aSatol;
  Standard_Real ainitTol = aSatol.Tolerance(theOldShape,0);

  // PAL6487: san -- preserve the original shape from being modified
  TopoDS_Shape anOldShape;
  TColStd_IndexedDataMapOfTransientTransient aMap;
  TNaming_CopyShape::CopyTool(theOldShape, aMap, anOldShape);
  // PAL6487: san -- preserve the original shape from being modified

  theNewShape = myOperations.PrepareShape(anOldShape,mySaveHistoryMode,myLevel);
  if(mySaveHistoryMode)
    myMapModifications = myOperations.Map();
  myDone = !anOldShape.IsSame(theNewShape);
  if(!myDone) {
    Standard_Real aendTol =aSatol.Tolerance(theNewShape,0);
    myDone = (fabs(ainitTol - aendTol) > Precision::Confusion()); 
  }
}
Example #2
0
Standard_Boolean ShHealOper_Sewing::sewing(const TopTools_SequenceOfShape& theSeqShapes)
{
  myDone = Standard_False;
  myErrorStatus = ShHealOper_NotError;
  if(myInitShape.IsNull()) {
    myErrorStatus = ShHealOper_InvalidParameters;
    return myDone;
  }
  //sewing shape
  Handle(BRepBuilderAPI_Sewing) aSewing = new BRepBuilderAPI_Sewing;
  aSewing->Load(myInitShape);
  aSewing->SetTolerance(myTolerance);
  aSewing->SetFaceMode(myFacesMode);
  aSewing->SetFloatingEdgesMode(myEdgesMode);
  aSewing->SetNonManifoldMode(myNonManifoldMode);
  Standard_Integer j =1;
  for( ; j <= theSeqShapes.Length();j++)
    aSewing->Add(theSeqShapes.Value(j));

  aSewing->Perform();
  const TopoDS_Shape aSewShape = aSewing->SewedShape();
  if(aSewShape.IsNull()) {
    myErrorStatus = ShHealOper_ErrorExecution;
    return myDone;
  }
  if(aSewShape.IsSame(myInitShape))
    return myDone;

  //analysis either sewing was made by changing number of shells
  myDone = isSewed(aSewShape);

  //keep modification of the subshapes in the Context.
  TopExp_Explorer aExp(myInitShape,TopAbs_FACE);
  for( ; aExp.More(); aExp.Next())
    myDone = (getModifications( aExp.Current(),aSewing) || myDone);

  TopoDS_Shape aTempShape = myContext->Apply(aSewShape);
  //obtained shells with fixed orientation for manifold and nonmanifold shells
  if(myFacesMode) 
    myDone = getShells(aTempShape) || myDone;

  //obtained manifold wires if sewing edges was performed.
  if(myEdgesMode) 
    myDone = getWires(aTempShape) || myDone;
  
  if(myDone)
    myResultShape = myContext->Apply(aTempShape);
    
  return myDone;
}
TopoDS_Edge
        StdMeshers_Hexa_3D::EdgeNotInFace(SMESH_Mesh & aMesh,
        const TopoDS_Shape & aShape,
        const TopoDS_Face & aFace,
        const TopoDS_Vertex & aVertex,
        const TopTools_IndexedDataMapOfShapeListOfShape & MS)
{
        //MESSAGE("StdMeshers_Hexa_3D::EdgeNotInFace");
        TopTools_IndexedDataMapOfShapeListOfShape MF;
        TopExp::MapShapesAndAncestors(aFace, TopAbs_VERTEX, TopAbs_EDGE, MF);
        const TopTools_ListOfShape & ancestorsInSolid = MS.FindFromKey(aVertex);
        const TopTools_ListOfShape & ancestorsInFace = MF.FindFromKey(aVertex);
//      SCRUTE(ancestorsInSolid.Extent());
//      SCRUTE(ancestorsInFace.Extent());
        ASSERT(ancestorsInSolid.Extent() == 6); // 6 (edges doublees)
        ASSERT(ancestorsInFace.Extent() == 2);

        TopoDS_Edge E;
        E.Nullify();
        TopTools_ListIteratorOfListOfShape its(ancestorsInSolid);
        for (; its.More(); its.Next())
        {
                TopoDS_Shape ancestor = its.Value();
                TopTools_ListIteratorOfListOfShape itf(ancestorsInFace);
                bool isInFace = false;
                for (; itf.More(); itf.Next())
                {
                        TopoDS_Shape ancestorInFace = itf.Value();
                        if (ancestorInFace.IsSame(ancestor))
                        {
                                isInFace = true;
                                break;
                        }
                }
                if (!isInFace)
                {
                        E = TopoDS::Edge(ancestor);
                        break;
                }
        }
        return E;
}
Example #4
0
bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
                        const TopoDS_Shape &  aShape,
                        const bool            aShapeOnly /*=false*/,
                        const bool            anUpward /*=false*/,
                        const ::MeshDimension aDim /*=::MeshDim_3D*/,
                        TSetOfInt*            aShapesId /*=0*/)
{
  MESSAGE("SMESH_Gen::Compute");
  MEMOSTAT;

  bool ret = true;

  SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);

  const bool includeSelf = true;
  const bool complexShapeFirst = true;
  const int  globalAlgoDim = 100;

  SMESH_subMeshIteratorPtr smIt;

  // Fix of Issue 22150. Due to !BLSURF->OnlyUnaryInput(), BLSURF computes edges
  // that must be computed by Projection 1D-2D when Projection asks to compute
  // one face only.
  SMESH_subMesh::compute_event computeEvent =
    aShapeOnly ? SMESH_subMesh::COMPUTE_SUBMESH : SMESH_subMesh::COMPUTE;

  if ( anUpward ) // is called from the below code in this method
  {
    // ===============================================
    // Mesh all the sub-shapes starting from vertices
    // ===============================================

    smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst);
    while ( smIt->more() )
    {
      SMESH_subMesh* smToCompute = smIt->next();

      // do not mesh vertices of a pseudo shape
      const TopoDS_Shape&        shape = smToCompute->GetSubShape();
      const TopAbs_ShapeEnum shapeType = shape.ShapeType();
      if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX )
        continue;

      // check for preview dimension limitations
      if ( aShapesId && GetShapeDim( shapeType ) > (int)aDim )
      {
        // clear compute state not to show previous compute errors
        //  if preview invoked less dimension less than previous
        smToCompute->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
        continue;
      }

      if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
      {
        if (_compute_canceled)
          return false;
        setCurrentSubMesh( smToCompute );
        smToCompute->ComputeStateEngine( computeEvent );
        setCurrentSubMesh( NULL );
      }

      // we check all the sub-meshes here and detect if any of them failed to compute
      if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE &&
          ( shapeType != TopAbs_EDGE || !SMESH_Algo::isDegenerated( TopoDS::Edge( shape ))))
        ret = false;
      else if ( aShapesId )
        aShapesId->insert( smToCompute->GetId() );
    }
    //aMesh.GetMeshDS()->Modified();
    return ret;
  }
  else
  {
    // ================================================================
    // Apply algos that do NOT require discreteized boundaries
    // ("all-dimensional") and do NOT support sub-meshes, starting from
    // the most complex shapes and collect sub-meshes with algos that 
    // DO support sub-meshes
    // ================================================================

    list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes[4]; // for each dim

    // map to sort sm with same dim algos according to dim of
    // the shape the algo assigned to (issue 0021217).
    // Other issues influenced the algo applying order:
    // 21406, 21556, 21893, 20206
    multimap< int, SMESH_subMesh* > shDim2sm;
    multimap< int, SMESH_subMesh* >::reverse_iterator shDim2smIt;
    TopoDS_Shape algoShape;
    int prevShapeDim = -1, aShapeDim;

    smIt = sm->getDependsOnIterator(includeSelf, complexShapeFirst);
    while ( smIt->more() )
    {
      SMESH_subMesh* smToCompute = smIt->next();
      if ( smToCompute->GetComputeState() != SMESH_subMesh::READY_TO_COMPUTE )
        continue;

      const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
      aShapeDim = GetShapeDim( aSubShape );
      if ( aShapeDim < 1 ) break;
      
      // check for preview dimension limitations
      if ( aShapesId && aShapeDim > (int)aDim )
        continue;

      SMESH_Algo* algo = GetAlgo( smToCompute, &algoShape );
      if ( algo && !algo->NeedDiscreteBoundary() )
      {
        if ( algo->SupportSubmeshes() )
        {
          // reload sub-meshes from shDim2sm into smWithAlgoSupportingSubmeshes
          // so that more local algos to go first
          if ( prevShapeDim != aShapeDim )
          {
            prevShapeDim = aShapeDim;
            for ( shDim2smIt = shDim2sm.rbegin(); shDim2smIt != shDim2sm.rend(); ++shDim2smIt )
              if ( shDim2smIt->first == globalAlgoDim )
                smWithAlgoSupportingSubmeshes[ aShapeDim ].push_back( shDim2smIt->second );
              else
                smWithAlgoSupportingSubmeshes[ aShapeDim ].push_front( shDim2smIt->second );
            shDim2sm.clear();
          }
          // add smToCompute to shDim2sm map
          if ( algoShape.IsSame( aMesh.GetShapeToMesh() ))
          {
            aShapeDim = globalAlgoDim; // to compute last
          }
          else
          {
            aShapeDim = GetShapeDim( algoShape );
            if ( algoShape.ShapeType() == TopAbs_COMPOUND )
            {
              TopoDS_Iterator it( algoShape );
              aShapeDim += GetShapeDim( it.Value() );
            }
          }
          shDim2sm.insert( make_pair( aShapeDim, smToCompute ));
        }
        else // Compute w/o support of sub-meshes
        {
          if (_compute_canceled)
            return false;
          setCurrentSubMesh( smToCompute );
          smToCompute->ComputeStateEngine( computeEvent );
          setCurrentSubMesh( NULL );
          if ( aShapesId )
            aShapesId->insert( smToCompute->GetId() );
        }
      }
    }
    // reload sub-meshes from shDim2sm into smWithAlgoSupportingSubmeshes
    for ( shDim2smIt = shDim2sm.rbegin(); shDim2smIt != shDim2sm.rend(); ++shDim2smIt )
      if ( shDim2smIt->first == globalAlgoDim )
        smWithAlgoSupportingSubmeshes[3].push_back( shDim2smIt->second );
      else
        smWithAlgoSupportingSubmeshes[0].push_front( shDim2smIt->second );

    // ======================================================
    // Apply all-dimensional algorithms supporing sub-meshes
    // ======================================================

    std::vector< SMESH_subMesh* > smVec;
    for ( aShapeDim = 0; aShapeDim < 4; ++aShapeDim )
    {
      // ------------------------------------------------
      // sort list of sub-meshes according to mesh order
      // ------------------------------------------------
      smVec.assign( smWithAlgoSupportingSubmeshes[ aShapeDim ].begin(),
                    smWithAlgoSupportingSubmeshes[ aShapeDim ].end() );
      aMesh.SortByMeshOrder( smVec );

      // ------------------------------------------------------------
      // compute sub-meshes with local uni-dimensional algos under
      // sub-meshes with all-dimensional algos
      // ------------------------------------------------------------
      // start from lower shapes
      for ( size_t i = 0; i < smVec.size(); ++i )
      {
        sm = smVec[i];

        // get a shape the algo is assigned to
        if ( !GetAlgo( sm, & algoShape ))
          continue; // strange...

        // look for more local algos
        smIt = sm->getDependsOnIterator(!includeSelf, !complexShapeFirst);
        while ( smIt->more() )
        {
          SMESH_subMesh* smToCompute = smIt->next();

          const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
          const int aShapeDim = GetShapeDim( aSubShape );
          //if ( aSubShape.ShapeType() == TopAbs_VERTEX ) continue;
          if ( aShapeDim < 1 ) continue;

          // check for preview dimension limitations
          if ( aShapesId && GetShapeDim( aSubShape.ShapeType() ) > (int)aDim )
            continue;

          SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() );
          filter
            .And( SMESH_HypoFilter::IsApplicableTo( aSubShape ))
            .And( SMESH_HypoFilter::IsMoreLocalThan( algoShape, aMesh ));

          if ( SMESH_Algo* subAlgo = (SMESH_Algo*) aMesh.GetHypothesis( smToCompute, filter, true))
          {
            if ( ! subAlgo->NeedDiscreteBoundary() ) continue;
            SMESH_Hypothesis::Hypothesis_Status status;
            if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status ))
              // mesh a lower smToCompute starting from vertices
              Compute( aMesh, aSubShape, aShapeOnly, /*anUpward=*/true, aDim, aShapesId );
          }
        }
      }
      // --------------------------------
      // apply the all-dimensional algos
      // --------------------------------
      for ( size_t i = 0; i < smVec.size(); ++i )
      {
        sm = smVec[i];
        if ( sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
        {
          const TopAbs_ShapeEnum shapeType = sm->GetSubShape().ShapeType();
          // check for preview dimension limitations
          if ( aShapesId && GetShapeDim( shapeType ) > (int)aDim )
            continue;

          if (_compute_canceled)
            return false;
          setCurrentSubMesh( sm );
          sm->ComputeStateEngine( computeEvent );
          setCurrentSubMesh( NULL );
          if ( aShapesId )
            aShapesId->insert( sm->GetId() );
        }
      }
    } // loop on shape dimensions

    // -----------------------------------------------
    // mesh the rest sub-shapes starting from vertices
    // -----------------------------------------------
    ret = Compute( aMesh, aShape, aShapeOnly, /*anUpward=*/true, aDim, aShapesId );
  }

  MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
  MEMOSTAT;

  SMESHDS_Mesh *myMesh = aMesh.GetMeshDS();
  MESSAGE("*** compactMesh after compute");
  myMesh->compactMesh();

  // fix quadratic mesh by bending iternal links near concave boundary
  if ( aShape.IsSame( aMesh.GetShapeToMesh() ) &&
       !aShapesId && // not preview
       ret ) // everything is OK
  {
    SMESH_MesherHelper aHelper( aMesh );
    if ( aHelper.IsQuadraticMesh() != SMESH_MesherHelper::LINEAR )
    {
      aHelper.FixQuadraticElements( sm->GetComputeError() );
    }
  }
  return ret;
}
bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape)
{
  if ( !_sourceHypo )
    return false;

  SMESH_Mesh * srcMesh = _sourceHypo->GetSourceMesh();
  SMESH_Mesh * tgtMesh = & aMesh;
  if ( !srcMesh )
    srcMesh = tgtMesh;

  SMESHDS_Mesh * srcMeshDS = srcMesh->GetMeshDS();
  SMESHDS_Mesh * tgtMeshDS = tgtMesh->GetMeshDS();

  // get shell from shape3D
  TopoDS_Shell srcShell, tgtShell;
  TopExp_Explorer exp( _sourceHypo->GetSource3DShape(), TopAbs_SHELL );
  int nbShell;
  for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
    srcShell = TopoDS::Shell( exp.Current() );
  if ( nbShell != 1 )
    return error(COMPERR_BAD_SHAPE,
                 SMESH_Comment("Source shape must have 1 shell but not ") << nbShell);

  exp.Init( aShape, TopAbs_SHELL );
  for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
    tgtShell = TopoDS::Shell( exp.Current() );
  if ( nbShell != 1 )
    return error(COMPERR_BAD_SHAPE,
                 SMESH_Comment("Target shape must have 1 shell but not ") << nbShell);

  // Check that shapes are blocks
  if ( TAssocTool::Count( tgtShell, TopAbs_FACE , 1 ) != 6 ||
       TAssocTool::Count( tgtShell, TopAbs_EDGE , 1 ) != 12 ||
       TAssocTool::Count( tgtShell, TopAbs_WIRE , 1 ) != 6 )
    return error(COMPERR_BAD_SHAPE, "Target shape is not a block");
  if ( TAssocTool::Count( srcShell, TopAbs_FACE , 1 ) != 6 ||
       TAssocTool::Count( srcShell, TopAbs_EDGE , 1 ) != 12 ||
       TAssocTool::Count( srcShell, TopAbs_WIRE , 1 ) != 6 )
    return error(COMPERR_BAD_SHAPE, "Source shape is not a block");

  // Assure that mesh on a source shape is computed

  SMESH_subMesh* srcSubMesh = srcMesh->GetSubMesh( _sourceHypo->GetSource3DShape() );
  //SMESH_subMesh* tgtSubMesh = tgtMesh->GetSubMesh( aShape );

  if ( tgtMesh == srcMesh && !aShape.IsSame( _sourceHypo->GetSource3DShape() )) {
    if ( !TAssocTool::MakeComputed( srcSubMesh ))
      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
  }
  else {
    if ( !srcSubMesh->IsMeshComputed() )
      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
  }

  // Find 2 pairs of corresponding vertices

  TopoDS_Vertex tgtV000, tgtV100, srcV000, srcV100;
  TAssocTool::TShapeShapeMap shape2ShapeMap;

  if ( _sourceHypo->HasVertexAssociation() )
  {
    tgtV000 = _sourceHypo->GetTargetVertex(1);
    tgtV100 = _sourceHypo->GetTargetVertex(2);
    srcV000 = _sourceHypo->GetSourceVertex(1);
    srcV100 = _sourceHypo->GetSourceVertex(2);
  }
  else
  {
    if ( !TAssocTool::FindSubShapeAssociation( tgtShell, tgtMesh, srcShell, srcMesh,
                                               shape2ShapeMap) )
      return error(COMPERR_BAD_SHAPE,"Topology of source and target shapes seems different" );

    exp.Init( tgtShell, TopAbs_EDGE );
    TopExp::Vertices( TopoDS::Edge( exp.Current() ), tgtV000, tgtV100 );

    if ( !shape2ShapeMap.IsBound( tgtV000 ) || !shape2ShapeMap.IsBound( tgtV100 ))
      return error("Association of subshapes failed" );
    srcV000 = TopoDS::Vertex( shape2ShapeMap( tgtV000 ));
    srcV100 = TopoDS::Vertex( shape2ShapeMap( tgtV100 ));
    if ( !TAssocTool::IsSubShape( srcV000, srcShell ) ||
         !TAssocTool::IsSubShape( srcV100, srcShell ))
      return error("Incorrect association of subshapes" );
  }

  // Load 2 SMESH_Block's with src and tgt shells

  SMESH_Block srcBlock, tgtBlock;
  TopTools_IndexedMapOfOrientedShape scrShapes, tgtShapes;
  if ( !tgtBlock.LoadBlockShapes( tgtShell, tgtV000, tgtV100, tgtShapes ))
    return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?");

  if ( !srcBlock.LoadBlockShapes( srcShell, srcV000, srcV100, scrShapes ))
    return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?");

  // Find matching nodes of src and tgt shells

  TNodeNodeMap src2tgtNodeMap;
  for ( int fId = SMESH_Block::ID_FirstF; fId < SMESH_Block::ID_Shell; ++fId )
  {
    // Corresponding subshapes
    TopoDS_Face srcFace = TopoDS::Face( scrShapes( fId ));
    TopoDS_Face tgtFace = TopoDS::Face( tgtShapes( fId ));
    if ( _sourceHypo->HasVertexAssociation() ) { // associate face subshapes
      shape2ShapeMap.Clear();
      vector< int > edgeIdVec;
      SMESH_Block::GetFaceEdgesIDs( fId, edgeIdVec );
      for ( int i = 0; i < edgeIdVec.size(); ++i ) {
        int eID = edgeIdVec[ i ];
        shape2ShapeMap.Bind( tgtShapes( eID ), scrShapes( eID ));
        if ( i < 2 ) {
          vector< int > vertexIdVec;
          SMESH_Block::GetEdgeVertexIDs( eID, vertexIdVec );
          shape2ShapeMap.Bind( tgtShapes( vertexIdVec[0] ), scrShapes( vertexIdVec[0] ));
          shape2ShapeMap.Bind( tgtShapes( vertexIdVec[1] ), scrShapes( vertexIdVec[1] ));
        }
      }
    }
    // Find matching nodes of tgt and src faces
    TNodeNodeMap faceMatchingNodes;
    if ( ! TAssocTool::FindMatchingNodesOnFaces( srcFace, srcMesh, tgtFace, tgtMesh, 
                                                 shape2ShapeMap, faceMatchingNodes ))
    return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #")
                 << srcMeshDS->ShapeToIndex( srcFace ) << " and "
                 << tgtMeshDS->ShapeToIndex( tgtFace ) << " seems different" );

    // put found matching nodes of 2 faces to the global map
    src2tgtNodeMap.insert( faceMatchingNodes.begin(), faceMatchingNodes.end() );
  }

  // ------------------
  // Make mesh
  // ------------------

  SMDS_VolumeTool volTool;
  SMESH_MesherHelper helper( *tgtMesh );
  helper.IsQuadraticSubMesh( aShape );

  SMESHDS_SubMesh* srcSMDS = srcSubMesh->GetSubMeshDS();
  SMDS_ElemIteratorPtr volIt = srcSMDS->GetElements();
  while ( volIt->more() ) // loop on source volumes
  {
    const SMDS_MeshElement* srcVol = volIt->next();
    if ( !srcVol || srcVol->GetType() != SMDSAbs_Volume )
        continue;
    int nbNodes = srcVol->NbNodes();
    SMDS_VolumeTool::VolumeType  volType = volTool.GetType( nbNodes );
    if ( srcVol->IsQuadratic() )
      nbNodes = volTool.NbCornerNodes( volType );

    // Find or create a new tgt node for each node of a src volume

    vector< const SMDS_MeshNode* > nodes( nbNodes );
    for ( int i = 0; i < nbNodes; ++i )
    {
      const SMDS_MeshNode* srcNode = srcVol->GetNode( i );
      const SMDS_MeshNode* tgtNode = 0;
      TNodeNodeMap::iterator sN_tN = src2tgtNodeMap.find( srcNode );
      if ( sN_tN != src2tgtNodeMap.end() ) // found
      {
        tgtNode = sN_tN->second;
      }
      else // Create a new tgt node
      {
        // compute normalized parameters of source node in srcBlock
        gp_Pnt srcCoord = gpXYZ( srcNode );
        gp_XYZ srcParam;
        if ( !srcBlock.ComputeParameters( srcCoord, srcParam ))
          return error(SMESH_Comment("Can't compute normalized parameters ")
                       << "for source node " << srcNode->GetID());
        // compute coordinates of target node by srcParam
        gp_XYZ tgtXYZ;
        if ( !tgtBlock.ShellPoint( srcParam, tgtXYZ ))
          return error("Can't compute coordinates by normalized parameters");
        // add node
        SMDS_MeshNode* newNode = tgtMeshDS->AddNode( tgtXYZ.X(), tgtXYZ.Y(), tgtXYZ.Z() );
        tgtMeshDS->SetNodeInVolume( newNode, helper.GetSubShapeID() );
        tgtNode = newNode;
        src2tgtNodeMap.insert( make_pair( srcNode, tgtNode ));
      }
      nodes[ i ] = tgtNode;
    }

    // Create a new volume

    SMDS_MeshVolume * tgtVol = 0;
    int id = 0, force3d = false;
    switch ( volType ) {
    case SMDS_VolumeTool::TETRA     :
    case SMDS_VolumeTool::QUAD_TETRA:
      tgtVol = helper.AddVolume( nodes[0],
                                 nodes[1],
                                 nodes[2],
                                 nodes[3], id, force3d); break;
    case SMDS_VolumeTool::PYRAM     :
    case SMDS_VolumeTool::QUAD_PYRAM:
      tgtVol = helper.AddVolume( nodes[0],
                                 nodes[1],
                                 nodes[2],
                                 nodes[3],
                                 nodes[4], id, force3d); break;
    case SMDS_VolumeTool::PENTA     :
    case SMDS_VolumeTool::QUAD_PENTA:
      tgtVol = helper.AddVolume( nodes[0],
                                 nodes[1],
                                 nodes[2],
                                 nodes[3],
                                 nodes[4],
                                 nodes[5], id, force3d); break;
    case SMDS_VolumeTool::HEXA      :
    case SMDS_VolumeTool::QUAD_HEXA :
      tgtVol = helper.AddVolume( nodes[0],
                                 nodes[1],
                                 nodes[2],
                                 nodes[3],
                                 nodes[4],
                                 nodes[5],
                                 nodes[6],
                                 nodes[7], id, force3d); break;
    default: // polyhedron
      const SMDS_PolyhedralVolumeOfNodes * poly =
        dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( srcVol );
      if ( !poly )
        RETURN_BAD_RESULT("Unexpected volume type");
      tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuanities() );
    }
    if ( tgtVol ) {
      tgtMeshDS->SetMeshElementOnShape( tgtVol, helper.GetSubShapeID() );
    }
  } // loop on volumes of src shell

  return true;
}
Example #6
0
//----------------------------------------------------------------
// Function: TopoDS_Shape level function to update the core Body
//           for any Boolean operation of the body.
// Author: Jane Hu
//----------------------------------------------------------------
CubitStatus OCCBody::update_OCC_entity(TopoDS_Shape& old_shape,
                                       TopoDS_Shape& new_shape,
                                       BRepBuilderAPI_MakeShape *op,
                                       LocOpe_SplitShape* sp)
{
  //set the Shells
  TopTools_IndexedMapOfShape M;
  TopExp::MapShapes(old_shape, TopAbs_SOLID, M);
  TopTools_IndexedMapOfShape M_new;
  TopExp::MapShapes(new_shape, TopAbs_SOLID, M_new);
  TopTools_ListOfShape shapes;
  TopoDS_Shape shape;

  CubitBoolean updated = CUBIT_FALSE;	
  if(!old_shape.IsNull() && old_shape.ShapeType() == TopAbs_COMPOUND && 
     !new_shape.IsNull() && new_shape.ShapeType() == TopAbs_COMPOUND &&
     !old_shape.IsSame(new_shape))
  {
    //By updating underling solids, shells etc., the old_shape will get changed.
    //trying to make sure the the number of each entity in the old and new 
    //shapes are the same, which means that nothing is delete, that we can 
    //update the map here. Otherwise, when deleting solids, it'll delete the
    //the old body and create new body. This is Ok for general boolean operation    //except imprint when booleans are called, usually the original body are
    // supposed to be kept. 
    updated = CUBIT_TRUE;
    OCCQueryEngine::instance()->update_OCC_map(old_shape, new_shape);
  }
 
  DLIList<int> new_solid_nums;
  DLIList<int> unfound_nums;
  for(int ii=1; ii<=M.Extent(); ii++)
  {
    TopoDS_Solid solid = TopoDS::Solid(M(ii));

    TopTools_ListOfShape shapes;
    if(op)
    {
      shapes.Assign(op->Modified(solid));
      if(shapes.Extent() == 0)
         shapes.Assign(op->Generated(solid));
    }
    else if(sp)
      shapes.Assign(sp->DescendantShapes(solid));

    if (shapes.Extent() == 1)
      shape = shapes.First();

    else if(shapes.Extent() > 1)
    {
      //update all attributes first.
      TopTools_ListIteratorOfListOfShape it;
      it.Initialize(shapes);
      for(; it.More(); it.Next())
      {
        shape = it.Value();
        OCCQueryEngine::instance()->copy_attributes(solid, shape);
      } 
      shape = shapes.First();
    }

    else if(op->IsDeleted(solid))
    {
       if (M_new.Extent()== 1 && ii == 1)
         shape = M_new(1);
       else if(M_new.Extent()== 1 && ii > 1)
         shape.Nullify();
       else if(M_new.Extent() > 1)
       {
         GProp_GProps myProps;
         BRepGProp::VolumeProperties(solid, myProps);
         double bf_mass = myProps.Mass();
         gp_Pnt old_center = myProps.CentreOfMass();
         CubitBoolean found = CUBIT_FALSE;
         for(int l = 1; l <= M_new.Extent(); l++)
         {
           BRepGProp::VolumeProperties(M_new(l), myProps);
           double af_mass = myProps.Mass();
           double dTol = OCCQueryEngine::instance()->get_sme_resabs_tolerance();
           if(fabs(bf_mass-af_mass) < dTol) //unchanged
           {
             gp_Pnt  new_center = myProps.CentreOfMass(); 
             if(new_center.IsEqual(old_center, dTol))
             {
               found = CUBIT_TRUE;
               shape = M_new(l);
               new_solid_nums.append(l);
               break;
             }
           }
         }
         if(!found)
         {
           unfound_nums.append(ii); 
           continue;
         }
       }
       else
         shape.Nullify();
    }
    else
    {
       shape = solid;
       continue;
    }

    if(shapes.Extent() > 0 || (op && op->IsDeleted(solid)))
      OCCLump::update_OCC_entity(solid, shape, op, sp);
  }

  if( unfound_nums.size() == 1 )
  {
    TopoDS_Solid solid = TopoDS::Solid(M(unfound_nums.get()));
    for(int kk = 1; kk <= M_new.Extent(); kk++)
    {
      if(!new_solid_nums.move_to(kk))
      {
        shape = M_new(kk);
        break;
      } 
    }
    OCCLump::update_OCC_entity(solid, shape, op, sp);
  }
  else if(unfound_nums.size() > 1)
  {
    shape.Nullify();
    for(int kk = 1; kk <=unfound_nums.size(); kk++)
    {
       TopoDS_Solid solid = TopoDS::Solid(M(unfound_nums.get_and_step()));
       OCCLump::update_OCC_entity(solid, shape, op, sp);
    }
  } 
  if(!old_shape.IsSame(new_shape) && !updated)
    OCCQueryEngine::instance()->update_OCC_map(old_shape, new_shape);
  return CUBIT_SUCCESS;
}
Example #7
0
int
EG_saveModel(const egObject *model, const char *name)
{
  int         i, len, outLevel;
  egadsModel *mshape;
  FILE        *fp;
  
  if (model == NULL)               return EGADS_NULLOBJ;
  if (model->magicnumber != MAGIC) return EGADS_NOTOBJ;
  if (model->oclass != MODEL)      return EGADS_NOTMODEL;
  outLevel = EG_outLevel(model);

  if (name == NULL) {
    if (outLevel > 0)
      printf(" EGADS Warning: NULL Filename (EG_saveModel)!\n");
    return EGADS_NONAME;
  }
  
  /* does file exist? */

  fp = fopen(name, "r");
  if (fp != NULL) {
    if (outLevel > 0)
      printf(" EGADS Warning: File %s Exists (EG_saveModel)!\n", name);
    fclose(fp);
    return EGADS_NOTFOUND;
  }
  
  /* find extension */
  
  len = strlen(name);
  for (i = len-1; i > 0; i--)
    if (name[i] == '.') break;
  if (i == 0) {
    if (outLevel > 0)
      printf(" EGADS Warning: No Extension in %s (EG_saveModel)!\n", name);
    return EGADS_NODATA;
  }
  
  mshape = (egadsModel *) model->blind;
  
  if ((strcasecmp(&name[i],".step") == 0) || 
      (strcasecmp(&name[i],".stp") == 0)) {

    /* STEP files */
    
    STEPControl_Writer aWriter;
    TopExp_Explorer Exp;
    const STEPControl_StepModelType aVal = STEPControl_AsIs;
    for (Exp.Init(mshape->shape, TopAbs_WIRE,  TopAbs_FACE);
         Exp.More(); Exp.Next()) aWriter.Transfer(Exp.Current(), aVal);
    for (Exp.Init(mshape->shape, TopAbs_FACE,  TopAbs_SHELL);
         Exp.More(); Exp.Next()) aWriter.Transfer(Exp.Current(), aVal);
    for (Exp.Init(mshape->shape, TopAbs_SHELL, TopAbs_SOLID);
         Exp.More(); Exp.Next()) aWriter.Transfer(Exp.Current(), aVal);
    for (Exp.Init(mshape->shape, TopAbs_SOLID); 
         Exp.More(); Exp.Next()) aWriter.Transfer(Exp.Current(), aVal);	
  
    if (!aWriter.Write(name)) {
      printf(" EGADS Warning: STEP Write Error (EG_saveModel)!\n");
      return EGADS_WRITERR;
    }
    
  } else if ((strcasecmp(&name[i],".iges") == 0) || 
             (strcasecmp(&name[i],".igs") == 0)) {
             
    /* IGES files */

    try {
      IGESControl_Controller::Init();
      IGESControl_Writer iWrite;
      TopExp_Explorer Exp;
      for (Exp.Init(mshape->shape, TopAbs_WIRE,  TopAbs_FACE);
           Exp.More(); Exp.Next()) iWrite.AddShape(Exp.Current());
      for (Exp.Init(mshape->shape, TopAbs_FACE,  TopAbs_SHELL);
           Exp.More(); Exp.Next()) iWrite.AddShape(Exp.Current());
      for (Exp.Init(mshape->shape, TopAbs_SHELL, TopAbs_SOLID);
           Exp.More(); Exp.Next()) iWrite.AddShape(Exp.Current());
      for (Exp.Init(mshape->shape, TopAbs_SOLID); 
           Exp.More(); Exp.Next()) iWrite.AddShape(Exp.Current());

      iWrite.ComputeModel();
      if (!iWrite.Write(name)) {
        printf(" EGADS Warning: IGES Write Error (EG_saveModel)!\n");
        return EGADS_WRITERR;
      }
    }
    catch (...)
    {
      printf(" EGADS Warning: Internal IGES Write Error (EG_saveModel)!\n");
      return EGADS_WRITERR;
    }

  } else if ((strcasecmp(&name[i],".brep") == 0) ||
             (strcasecmp(&name[i],".egads") == 0)) {
  
    /* Native OCC file or our filetype */

    if (!BRepTools::Write(mshape->shape, name)) {
      printf(" EGADS Warning: OCC Write Error (EG_saveModel)!\n");
      return EGADS_WRITERR;
    }
    if (strcasecmp(&name[i],".brep") == 0) return EGADS_SUCCESS;
    
    /* append the attributes -- output in the read order */
    
    FILE *fp = fopen(name, "a");
    if (fp == NULL) {
      printf(" EGADS Warning: EGADS Open Error (EG_saveModel)!\n");
      return EGADS_WRITERR;
    }
    fprintf(fp, "\n##EGADS HEADER FILE-REV 1 ##\n");
    /* write model attributes */
    EG_writeAttrs(model, fp);
    TopExp_Explorer Exp;
    for (Exp.Init(mshape->shape, TopAbs_WIRE,  TopAbs_FACE); 
         Exp.More(); Exp.Next()) {
      TopoDS_Shape shape = Exp.Current();
      for (i = 0; i < mshape->nbody; i++) {
        egObject  *obj   = mshape->bodies[i];
        egadsBody *pbody = (egadsBody *) obj->blind;
        if (shape.IsSame(pbody->shape)) {
          EG_writeAttrs(obj, fp);
          break;
        }
      }
    }
    for (Exp.Init(mshape->shape, TopAbs_FACE,  TopAbs_SHELL);
         Exp.More(); Exp.Next()) {
      TopoDS_Shape shape = Exp.Current();
      for (i = 0; i < mshape->nbody; i++) {
        egObject  *obj   = mshape->bodies[i];
        egadsBody *pbody = (egadsBody *) obj->blind;
        if (shape.IsSame(pbody->shape)) {
          EG_writeAttrs(obj, fp);
          break;
        }
      }
    }
    for (Exp.Init(mshape->shape, TopAbs_SHELL, TopAbs_SOLID);
         Exp.More(); Exp.Next()) {
      TopoDS_Shape shape = Exp.Current();
      for (i = 0; i < mshape->nbody; i++) {
        egObject  *obj   = mshape->bodies[i];
        egadsBody *pbody = (egadsBody *) obj->blind;
        if (shape.IsSame(pbody->shape)) {
          EG_writeAttrs(obj, fp);
          break;
        }
      }
    }
    for (Exp.Init(mshape->shape, TopAbs_SOLID); Exp.More(); Exp.Next()) {
      TopoDS_Shape shape = Exp.Current();
      for (i = 0; i < mshape->nbody; i++) {
        egObject  *obj   = mshape->bodies[i];
        egadsBody *pbody = (egadsBody *) obj->blind;
        if (shape.IsSame(pbody->shape)) {
          EG_writeAttrs(obj, fp);
          break;
        }
      }
    }
   
   fclose(fp);

  } else {
    if (outLevel > 0)
      printf(" EGADS Warning: Extension in %s Not Supported (EG_saveModel)!\n",
             name);
    return EGADS_NODATA;
  }

  return EGADS_SUCCESS;
}
Example #8
0
int
EG_attriBodyDup(const egObject *src, egObject *dst)
{
  int          i, j, nents, nattr;
  egObject     *aobj, *dobj;
  egAttrs      *attrs;
  TopoDS_Shape shape;
  
  if ((src == NULL) || (dst == NULL)) return EGADS_NULLOBJ;
  if  (src->magicnumber != MAGIC)     return EGADS_NOTOBJ;
  if  (src->oclass < NODE)            return EGADS_NOTTOPO;
  if  (src->blind == NULL)            return EGADS_NODATA;
  int outLevel = EG_outLevel(src);
  
  if (src->oclass == MODEL) {
    if (outLevel > 0)
      printf(" EGADS Error: src MODEL not supported (EG_attriBodyDup)!\n");
    return EGADS_NOTMODEL;
  }
  if (dst->magicnumber != MAGIC) {
    if (outLevel > 0)
      printf(" EGADS Error: dst not an EGO (EG_attriBodyDup)!\n");
    return EGADS_NOTOBJ;
  }
  if (dst->oclass != BODY) {
    if (outLevel > 0)
      printf(" EGADS Error: dst not a BODY (EG_attriBodyDup)!\n");
    return EGADS_NOTBODY;
  }
  if (EG_context(src) != EG_context(dst)) {
    if (outLevel > 0)
      printf(" EGADS Error: Context mismatch (EG_attriBodyDup)!\n");
    return EGADS_MIXCNTX;
  }
  if (dst->blind == NULL) {
    if (outLevel > 0)
      printf(" EGADS Error: NULL dst pointer (EG_attriBodyDup)!\n");
    return EGADS_NODATA;
  }
  egadsBody *pbody = (egadsBody *) dst->blind;
  
  if (src->oclass == BODY) {
  
    // use hashed body data on both ends
    egadsBody *pbods = (egadsBody *) src->blind;
    shape = pbody->shape;
    if (shape.IsSame(pbods->shape)) EG_attributeDup(src, dst);
    
    nents = pbods->shells.map.Extent();
    for (i = 0; i < nents; i++) {
      aobj = pbods->shells.objs[i];
      if (aobj->attrs == NULL) continue;
      attrs = (egAttrs *) aobj->attrs;
      nattr = attrs->nattrs;
      if (nattr <= 0) continue;
      shape = pbods->shells.map(i+1);
      j     = pbody->shells.map.FindIndex(shape);
      if (j == 0) continue;                     // not in the dst body
      dobj = pbody->shells.objs[j-1];
      EG_attributeDup(aobj, dobj);
    }

    nents = pbods->faces.map.Extent();
    for (i = 0; i < nents; i++) {
      aobj = pbods->faces.objs[i];
      if (aobj->attrs == NULL) continue;
      attrs = (egAttrs *) aobj->attrs;
      nattr = attrs->nattrs;
      if (nattr <= 0) continue;
      shape = pbods->faces.map(i+1);
      j     = pbody->faces.map.FindIndex(shape);
      if (j == 0) continue;                     // not in the dst body
      dobj = pbody->faces.objs[j-1];
      EG_attributeDup(aobj, dobj);
    }
    
    nents = pbods->loops.map.Extent();
    for (i = 0; i < nents; i++) {
      aobj = pbods->loops.objs[i];
      if (aobj->attrs == NULL) continue;
      attrs = (egAttrs *) aobj->attrs;
      nattr = attrs->nattrs;
      if (nattr <= 0) continue;
      shape = pbods->loops.map(i+1);
      j     = pbody->loops.map.FindIndex(shape);
      if (j == 0) continue;                     // not in the dst body
      dobj = pbody->loops.objs[j-1];
      EG_attributeDup(aobj, dobj);
    }

    nents = pbods->edges.map.Extent();
    for (i = 0; i < nents; i++) {
      aobj = pbods->edges.objs[i];
      if (aobj->attrs == NULL) continue;
      attrs = (egAttrs *) aobj->attrs;
      nattr = attrs->nattrs;
      if (nattr <= 0) continue;
      shape = pbods->edges.map(i+1);
      j     = pbody->edges.map.FindIndex(shape);
      if (j == 0) continue;                     // not in the dst body
      dobj = pbody->edges.objs[j-1];
      EG_attributeDup(aobj, dobj);
    }
  
    nents = pbods->nodes.map.Extent();
    for (i = 0; i < nents; i++) {
      aobj = pbods->nodes.objs[i];
      if (aobj->attrs == NULL) continue;
      attrs = (egAttrs *) aobj->attrs;
      nattr = attrs->nattrs;
      if (nattr <= 0) continue;
      shape = pbods->nodes.map(i+1);
      j     = pbody->nodes.map.FindIndex(shape);
      if (j == 0) continue;                     // not in the dst body
      dobj = pbody->nodes.objs[j-1];
      EG_attributeDup(aobj, dobj);
    }

  } else {
  
    // traverse the source to find objects with attributes
    EG_attriBodyTrav(src, pbody);
    
  }
  
  return EGADS_SUCCESS;
}
//=======================================================================
// function: MakeBlocks
// purpose:
//=======================================================================
void NMTTools_PaveFiller::MakeBlocks()
{
  myIsDone=Standard_False;
  //
  Standard_Boolean bIsExistingPaveBlock, bIsValidIn2D, bIsCoincided;
  Standard_Boolean bIsMicroEdge, bHasES;
  Standard_Integer i, aNbFFs, nF1, nF2;
  Standard_Integer nV1, nV2, j, aNbCurves;
  Standard_Real aTolR3D, aTol2D, aT1, aT2, aTolPPC=Precision::PConfusion();
  TopoDS_Face aF1, aF2;
  NMTTools_IndexedDataMapOfShapePaveBlock aMEPB;
  BooleanOperations_IndexedDataMapOfShapeInteger aMapEI;
  BOPTools_ListIteratorOfListOfPaveBlock anIt;
  //
  BOPTools_CArray1OfSSInterference& aFFs=myIP->SSInterferences();
  //

  //
  // 1. Make Section Edges from intersection curves
  //    between each pair of faces
  aNbFFs=aFFs.Extent();
  if (!aNbFFs) {
    return;
  }
  //
  FillFaceInfo();
  //
  for (i=1; i<=aNbFFs; ++i) {
    BOPTools_ListOfPaveBlock aLPB;
    TColStd_MapOfInteger aMVStick;
    TopTools_ListOfShape aLSE;
    TColStd_ListOfInteger aLNE;
    BOPTools_PaveSet aPSF;
    NMTTools_MapOfPaveBlock aMPBX;
    TColStd_MapIteratorOfMapOfInteger aItMI;
    NMTTools_MapIteratorOfMapOfPaveBlock aItMPB;
    //
    BOPTools_SSInterference& aFFi=aFFs(i);
    //
    // Faces
    aFFi.Indices(nF1, nF2);
    aF1=*((TopoDS_Face*)(&myDS->Shape(nF1)));
    aF2=*((TopoDS_Face*)(&myDS->Shape(nF2)));
    //
    SharedEdges(nF1, nF2, aLNE, aLSE);
    aFFi.SetSharedEdges(aLNE);
    //
    // aMVStick
    const NMTTools_FaceInfo& aFI1=myFaceInfo.Find(nF1);
    const NMTTools_FaceInfo& aFI2=myFaceInfo.Find(nF2);
    //
    const TColStd_MapOfInteger& aMVOn1=aFI1.VerticesOn();
    const TColStd_MapOfInteger& aMVIn1=aFI1.VerticesIn();
    const TColStd_MapOfInteger& aMVOn2=aFI2.VerticesOn();
    const TColStd_MapOfInteger& aMVIn2=aFI2.VerticesIn();
    //
    for (j=0; j<2; ++j) {
      const TColStd_MapOfInteger& aMV1=(!j) ? aMVOn1 :aMVIn1;
      aItMI.Initialize(aMV1);
      for (; aItMI.More(); aItMI.Next()) {
	nV1=aItMI.Key();
	if (aMVOn2.Contains(nV1) || aMVIn2.Contains(nV1)) {
	  aMVStick.Add(nV1);
	}
      }
    }
    //
    //  aLPB
    const NMTTools_MapOfPaveBlock& aMPBIn1=aFI1.PaveBlocksIn();
    const NMTTools_MapOfPaveBlock& aMPBOn1=aFI1.PaveBlocksOn();
    const NMTTools_MapOfPaveBlock& aMPBIn2=aFI2.PaveBlocksIn();
    const NMTTools_MapOfPaveBlock& aMPBOn2=aFI2.PaveBlocksOn();
    //
    aMPBX.Clear();
    for (j=0; j<4; ++j) {
      NMTTools_MapOfPaveBlock *pMPB;
      //
      if (!j) {
	pMPB=((NMTTools_MapOfPaveBlock*)&aMPBIn1);
      }
      else if (j==1) {
	pMPB=((NMTTools_MapOfPaveBlock*)&aMPBOn1);
      }
      else if (j==2) {
	pMPB=((NMTTools_MapOfPaveBlock*)&aMPBIn2);
      }
      else if (j==3) {
	pMPB=((NMTTools_MapOfPaveBlock*)&aMPBOn2);
      }
      //
      const NMTTools_MapOfPaveBlock& aMPB=*pMPB;
      aItMPB.Initialize(aMPB);
      for (; aItMPB.More(); aItMPB.Next()) {
	const BOPTools_PaveBlock& aPB=aItMPB.Key();
	if (aMPBX.Add(aPB)) {
	  aLPB.Append(aPB);
	}
	//
	else {
	  if (j>1) {
	    aFFi.AppendBlock(aPB);
	  }
	}
	//
      }
    }
    //
    BOPTools_SequenceOfCurves& aSCvs=aFFi.Curves();
    aNbCurves=aSCvs.Length();
    if (!aNbCurves) {
      continue;
    }
    //
    aTolR3D=aFFi.TolR3D();
    aTol2D=(aTolR3D < 1.e-3) ? 1.e-3 : aTolR3D;
    //
    CorrectTolR3D(aFFi, aMVStick, aTolR3D);
    //
    PrepareSetForFace (nF1, nF2, aLPB, aPSF);
    //
    // Put Paves On Curves
    for (j=1; j<=aNbCurves; ++j) {
      BOPTools_Curve& aBC=aSCvs(j);
      const IntTools_Curve& aC=aBC.Curve();
      // DEBUG f
      Handle(Geom_Curve) aC3D = aC.Curve();
      // DEBUG t
      PutPaveOnCurve (aPSF, aTolR3D, aBC);
    }
    //
    // Put bounding paves on curves
    for (j=1; j<=aNbCurves; ++j) {
      BOPTools_Curve& aBC=aSCvs(j);
      PutBoundPaveOnCurve (aBC, aFFi);
    }
    //modified by NIZNHY-PKV Wed Sep 14 13:12:14 2011f
#if OCC_VERSION_LARGE > 0x06050100 // For OCCT6.5.2 and higher
    //
    // Put closing pave if needded
    for (j=1; j<=aNbCurves; ++j) {
      BOPTools_Curve& aBC=aSCvs(j);
      PutClosingPaveOnCurve (aBC, aFFi);
    }
#endif // OCC_VERSION_LARGE > 0x06050100 // For OCCT6.5.2 and higher
    //modified by NIZNHY-PKV Wed Sep 14 13:12:17 2011t
    //
    //  Pave Blocks on Curves
    bHasES=Standard_False;
    for (j=1; j<=aNbCurves; ++j) {
      BOPTools_Curve& aBC=aSCvs(j);
      const IntTools_Curve& aIC= aBC.Curve();
      BOPTools_PaveSet& aPaveSet=aBC.Set();
      //
      BOPTools_PaveBlockIterator aPBIter(0, aPaveSet);
      for (; aPBIter.More(); aPBIter.Next()) {
        BOPTools_PaveBlock& aPBNew=aPBIter.Value();
        aPBNew.SetCurve(aIC);
        aPBNew.SetFace1(nF1);
        aPBNew.SetFace2(nF2);
        //
        nV1=aPBNew.Pave1().Index();
        nV2=aPBNew.Pave2().Index();
        aT1=aPBNew.Pave1().Param();
        aT2=aPBNew.Pave2().Param();
        //
        if((nV1==nV2) && (Abs(aT2 - aT1) < aTolPPC)) {
          continue;// mkk ft ???
        }
        //
        // 1
        bIsExistingPaveBlock=IsExistingPaveBlock(aPBNew, aLPB, aTolR3D);
        if (bIsExistingPaveBlock) {
          continue;
        }
        //
        bIsCoincided=CheckCoincidence(aPBNew, aLPB);
        if(bIsCoincided) {
          continue;
        }
        //
        // 2
        bIsExistingPaveBlock=IsExistingPaveBlock(aPBNew, aLSE, aTolR3D);
        if (bIsExistingPaveBlock) {
          continue;
        }
	//
        // Checking of validity in 2D
        //
        bIsValidIn2D=myContext->IsValidBlockForFaces(aT1, aT2, aIC, aF1, aF2, aTol2D);
        if (!bIsValidIn2D) {
          continue;
        }
        //
        //
        // Make Section Edge
        TopoDS_Edge aES;
        //
        const TopoDS_Vertex aV1=TopoDS::Vertex(myDS->Shape(nV1));
        const TopoDS_Vertex aV2=TopoDS::Vertex(myDS->Shape(nV2));
        //
        {
          Standard_Real aT;
          //
          myContext->IsVertexOnLine(aV1, aIC, aTolR3D, aT);
          BOPTools_Tools::UpdateVertex (aIC, aT, aV1);
          //
          myContext->IsVertexOnLine(aV2, aIC, aTolR3D, aT);
          BOPTools_Tools::UpdateVertex (aIC, aT, aV2);
        }
        //
        BOPTools_Tools::MakeSectEdge (aIC, aV1, aT1, aV2, aT2, aES);
        //
        NMTTools_Tools::UpdateEdge (aES, aTolR3D);
        bIsMicroEdge=IsMicroEdge(aES, myContext);
        if (bIsMicroEdge) {
          continue;
        }
        //
        {
          Handle(Geom2d_Curve) aC2D1, aC2D2;
          //
          aC2D1=aIC.FirstCurve2d();
          aC2D2=aIC.SecondCurve2d();
          //
          NMTTools_Tools::MakePCurve(aES, aF1, aC2D1);
          NMTTools_Tools::MakePCurve(aES, aF2, aC2D2);
        }
        //
        aMEPB.Add(aES, aPBNew);
        aMapEI.Add(aES, i);
        //
        bHasES=Standard_True;
      }// for (; aPBIter.More(); aPBIter.Next())
    } // end of for (j=1; j<=aNbCurves; ++j)
    // qqf
    if (bHasES) {
      myIP->Add(nF1, nF2, Standard_True, NMTDS_TI_FF);
    }
    // qqt
  }// for (i=1; i<=aNbFFs; ++i)
  //=============================================================
  //
  // II. Post treatment
  //
  // Input data: aMEPB, aMapEI
  // Result    : section edges in myDS
  //
  Standard_Integer aNbSE;
  //
  aNbSE=aMEPB.Extent();
  if (!aNbSE) {
    // there is nothing to do here
    return;
  }
  //
  BRep_Builder aBB;
  TopoDS_Compound aCompound;
  //
  // 1. Make compound from SE
  aBB.MakeCompound(aCompound);
  for (i=1; i<=aNbSE; ++i) {
    const TopoDS_Shape& aSE=aMEPB.FindKey(i);
    aBB.Add(aCompound, aSE);
  }
  //
  //
  // 2. Intersect SE using auxiliary Filler
  NMTTools_PaveFiller tPF;
  //
  tPF.SetCompositeShape(aCompound);
  //
  // 2.1.VV
  tPF.Init();
  tPF.PerformVV();
  //
  // 2.2.VE
  tPF.myPavePool.Resize (tPF.myNbEdges);
  tPF.PrepareEdges();
  tPF.PerformVE();
  //
  // 2.3.VF
  tPF.PerformVF();
  //
  // 2.4.EE
  tPF.myCommonBlockPool.Resize (tPF.myNbEdges);
  tPF.mySplitShapesPool.Resize (tPF.myNbEdges);
  tPF.myPavePoolNew    .Resize (tPF.myNbEdges);

  tPF.PreparePaveBlocks(TopAbs_VERTEX, TopAbs_EDGE);
  tPF.PreparePaveBlocks(TopAbs_EDGE, TopAbs_EDGE);
  //
  tPF.PerformEE();
  //
  tPF.RefinePavePool ();
  //
  tPF.myPavePoolNew.Destroy();
  //
  tPF.MakeSplitEdges();
  tPF.UpdateCommonBlocks();
  //
  // 3. Treatment of the result of intersection
  //
  Standard_Integer aNbOld, aNbLines, aNbPB, mV1, mV2, nE, mE, iFF;
  TopAbs_ShapeEnum aType;
  BOPTools_ListIteratorOfListOfPaveBlock aIt;
  BOPTColStd_IndexedDataMapOfIntegerInteger aMNewOld;
  //
  const NMTDS_ShapesDataStructure& tDS=*(tPF.DS());
  const BOPTools_SplitShapesPool& aSSP=tPF.mySplitShapesPool;
  const NMTTools_CommonBlockPool& aCBP=tPF.myCommonBlockPool;
  //
  aNbLines=tDS.NumberOfInsertedShapes();
  aNbOld=tDS.NumberOfShapesOfTheObject();
  //
  // 3.1 Links between indices in tDS and DS (kept in aMNewOld)
  //
  // 3.1.1.Old vertices [ links ]
  for (i=1; i<=aNbOld; ++i) {
    const TopoDS_Shape& aV=tDS.Shape(i);
    aType=aV.ShapeType();
    if (aType!=TopAbs_VERTEX) {
      continue;
    }
    //
    for (j=1; j<=aNbSE; ++j) {
      const BOPTools_PaveBlock& aPBSE=aMEPB(j);
      nV1=aPBSE.Pave1().Index();
      const TopoDS_Shape aV1=myDS->Shape(nV1);//mpv
      if (aV1.IsSame(aV)) {
        aMNewOld.Add(i, nV1);
        break;
      }
      nV2=aPBSE.Pave2().Index();
      const TopoDS_Shape aV2=myDS->Shape(nV2);//mpv
      if (aV2.IsSame(aV)) {
        aMNewOld.Add(i, nV2);
        break;
      }
    }
  }
  //
  // 3.1.2. New vertices [ links ]
  i=tDS.NumberOfSourceShapes()+1;
  for (; i<=aNbLines; ++i) {
    const TopoDS_Shape& aV=tDS.Shape(i);
    aType=aV.ShapeType();
    if (aType!=TopAbs_VERTEX) {
      continue;
    }
    //
    // Insert new vertex in myDS
    BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
    myDS->InsertShapeAndAncestorsSuccessors(aV, anASSeq);
    nV1=myDS->NumberOfInsertedShapes();
    // link
    aMNewOld.Add(i, nV1);
  }
  //
  // 3.2. Treatment of section edges (SE)
  for (i=1; i<=aNbOld; ++i) {
    const TopoDS_Shape& aE=tDS.Shape(i);
    aType=aE.ShapeType();
    if (aType!=TopAbs_EDGE) {
      continue;
    }
    //
    //  block of section edge that we already have for this SE
    BOPTools_PaveBlock& aPBSE=aMEPB.ChangeFromKey(aE);
    //
    // Corresponding FF-interference
    iFF=aMapEI.FindFromKey(aE);
    BOPTools_SSInterference& aFFi=aFFs(iFF);
    BOPTools_SequenceOfCurves& aSCvs=aFFi.Curves();
    //
    BOPTools_Curve& aBC=aSCvs(1);
    //
    const BOPTools_ListOfPaveBlock& aLPB=aSSP(tDS.RefEdge(i));
    aNbPB=aLPB.Extent();
    //
    if (!aNbPB) {
      // no pave blocks -> use aPBSE and whole edge aE
      BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
      //
      nV1=aPBSE.Pave1().Index();
      const TopoDS_Shape aV1=myDS->Shape(nV1);//mpv
      nV2=aPBSE.Pave2().Index();
      const TopoDS_Shape aV2=myDS->Shape(nV2);//mpv
      //
      anASSeq.SetNewSuccessor(nV1);
      anASSeq.SetNewOrientation(aV1.Orientation());
      anASSeq.SetNewSuccessor(nV2);
      anASSeq.SetNewOrientation(aV2.Orientation());
      //
      myDS->InsertShapeAndAncestorsSuccessors(aE, anASSeq);
      nE=myDS->NumberOfInsertedShapes();
      //
      aPBSE.SetEdge(nE);
      aBC.AppendNewBlock(aPBSE);
      //
      continue;
    }
    //
    nF1=aPBSE.Face1();
    nF2=aPBSE.Face2();
    //
    const NMTTools_ListOfCommonBlock& aLCB=aCBP(tDS.RefEdge(i));
    NMTTools_CommonBlockAPI aCBAPI(aLCB);
    //
    aIt.Initialize(aLPB);
    for (; aIt.More(); aIt.Next()) {
      BOPTools_PaveBlock aPB=aIt.Value();
      //
      const TopoDS_Face aF1=TopoDS::Face(myDS->Shape(nF1));
      const TopoDS_Face aF2=TopoDS::Face(myDS->Shape(nF2));
      //
      if (aCBAPI.IsCommonBlock(aPB)) {
        // it can be Common Block
        Standard_Real aTolEx;
        Handle(Geom2d_Curve) aC2D1, aC2D2;
        TopoDS_Face aF1FWD, aF2FWD;
        //
        NMTTools_CommonBlock& aCB=aCBAPI.CommonBlock(aPB);
        //const BOPTools_ListOfPaveBlock& aLPBx=aCB.PaveBlocks();
        //
        aPB=aCB.PaveBlock1();
        mE=aPB.Edge(); // index of edge in tDS
        const TopoDS_Edge& aEx=TopoDS::Edge(tDS.Shape(mE));
        aTolEx=BRep_Tool::Tolerance(aEx);
        //
        aF1FWD=aF1;
        aF1FWD.Orientation(TopAbs_FORWARD);
        aF2FWD=aF2;
        aF2FWD.Orientation(TopAbs_FORWARD);
        //
        NMTTools_Tools::MakePCurve(aEx, aF1FWD, aC2D1);
        NMTTools_Tools::MakePCurve(aEx, aF2FWD, aC2D2);
        NMTTools_Tools::UpdateEdge (aEx, aTolEx);
      } //if (aCBAPI.IsCommonBlock(aPB))
      //
      // new SE
      mE=aPB.Edge(); // index of edge in tDS
      const TopoDS_Shape& aSp=tDS.Shape(mE);
      //
      const BOPTools_Pave& aPave1=aPB.Pave1();
      aT1=aPave1.Param();
      mV1=aPave1.Index();            // index in tDS
      nV1=aMNewOld.FindFromKey(mV1); // index in myDS
      const TopoDS_Shape aV1=myDS->Shape(nV1);//mpv
      //
      const BOPTools_Pave& aPave2=aPB.Pave2();
      aT2=aPave2.Param();
      mV2=aPave2.Index();
      nV2=aMNewOld.FindFromKey(mV2);
      const TopoDS_Shape aV2=myDS->Shape(nV2);//mpv
      //
      if (!aMNewOld.Contains(mE)) {
        // add new SE to the myDS
        BooleanOperations_AncestorsSeqAndSuccessorsSeq anASSeq;
        //
        anASSeq.SetNewSuccessor(nV1);
        anASSeq.SetNewOrientation(aV1.Orientation());

        anASSeq.SetNewSuccessor(nV2);
        anASSeq.SetNewOrientation(aV2.Orientation());

        myDS->InsertShapeAndAncestorsSuccessors(aSp, anASSeq);
        nE=myDS->NumberOfInsertedShapes();
        //
        aMNewOld.Add(mE, nE);
      }
      else {
        nE=aMNewOld.FindFromKey(mE);
      }
      // Form PaveBlock;
      BOPTools_PaveBlock aPBx;
      BOPTools_Pave aP1, aP2;
      //
      aPBx.SetFace1(nF1);
      aPBx.SetFace1(nF2);
      //
      aP1.SetIndex(nV1);
      aP1.SetParam(aT1);
      //
      aP2.SetIndex(nV2);
      aP2.SetParam(aT2);
      //
      aPBx.SetPave1(aP1);
      aPBx.SetPave2(aP2);
      //
      aPBx.SetEdge(nE);
      //
      aBC.AppendNewBlock(aPBx);
    }// for (; aIt.More(); aIt.Next())
  }// for (i=1; i<=aNbOld; ++i)
  //
  myIsDone=Standard_True;
}