Exemplo n.º 1
0
//=======================================================================
//function : CorrectWires
//purpose  :
//=======================================================================
  Standard_Boolean GEOMAlgo_Tools::CorrectWires(const TopoDS_Shape& aShape)
{
  Standard_Boolean bRet;
  TopoDS_Iterator aItF;
  TopExp_Explorer aExp;
  TopTools_MapOfShape aMF;
  GeomAdaptor_Surface aGAS;
  GeomAbs_SurfaceType aTS;
  TopLoc_Location aLoc;
  //
  bRet=Standard_False;
  //
  aExp.Init(aShape, TopAbs_FACE);
  for (; aExp.More(); aExp.Next()) {
    const TopoDS_Face& aF=*((TopoDS_Face*)&aExp.Current());
    if (aMF.Add(aF)) {
      const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aF, aLoc);
      aGAS.Load(aS);
      aTS=aGAS.GetType();
      if (aTS==GeomAbs_Cylinder || aTS==GeomAbs_Plane) {
	aItF.Initialize(aF);
	for (; aItF.More(); aItF.Next()) {
	  const TopoDS_Wire& aW=*((TopoDS_Wire*)&aItF.Value());
	  if (CorrectWire(aW, aF)) {
	   bRet=Standard_True;
	  }
	}
      }
    }
  }
  return bRet;
}
Exemplo n.º 2
0
//=======================================================================
//function : FillContainers
//purpose  :
//=======================================================================
void GEOMAlgo_Gluer2::FillContainers(const TopAbs_ShapeEnum aType)
{
  Standard_Boolean bHasImage, bToReverse;
  Standard_Integer i, aNbW;
  TopoDS_Shape aWnew, aEnew;
  TopoDS_Iterator aItS;
  BRep_Builder aBB;
  TopTools_IndexedMapOfShape aMW;
  TopTools_MapOfShape aMFence;
  //
  myErrorStatus=0;
  myWarningStatus=0;
  //
  TopExp::MapShapes(myArgument, aType, aMW);
  //
  aNbW=aMW.Extent();
  for (i=1; i<=aNbW; ++i) {
    const TopoDS_Shape& aW=aMW(i);
    //
    if (!aMFence.Add(aW)) {
      continue;
    }
    //
    bHasImage=HasImage(aW);
    if (!bHasImage) {
      continue;
    }
    //
    GEOMAlgo_Tools3D::MakeContainer(aType, aWnew);
    aWnew.Orientation(aW.Orientation());
    //
    aItS.Initialize(aW);
    for (; aItS.More(); aItS.Next()) {
      const TopoDS_Shape& aE=aItS.Value();
      if (myOrigins.IsBound(aE)) {
        aEnew=myOrigins.Find(aE);
        //
        bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aEnew, aE, myContext);
        if (bToReverse) {
          aEnew.Reverse();
        }
        //
        aBB.Add(aWnew, aEnew);
      }
      else {
        aBB.Add(aWnew, aE);
      }
    }
    //
    //myImages / myOrigins
    TopTools_ListOfShape aLSD;
    //
    aLSD.Append(aW);
    myImages.Bind(aWnew, aLSD);
    myOrigins.Bind(aW, aWnew);
    //
  }//for (i=1; i<=aNbE; ++i) {
}
Exemplo n.º 3
0
//=======================================================================
//function : FillBRepShapes
//purpose  :
//=======================================================================
void GEOMAlgo_Gluer2::FillBRepShapes(const TopAbs_ShapeEnum theType)
{
  Standard_Boolean bHasImage, bIsToWork;
  Standard_Integer i, aNbE;
  TopoDS_Iterator aItS;
  TopoDS_Shape aEnew;
  TopTools_IndexedMapOfShape aME;
  TopTools_MapOfShape aMFence;
  TopTools_ListIteratorOfListOfShape aItLS;
  //
  myErrorStatus=0;
  myWarningStatus=0;
  //
  TopExp::MapShapes(myArgument, theType, aME);
  //
  aNbE=aME.Extent();
  for (i=1; i<=aNbE; ++i) {
    const TopoDS_Shape& aE=aME(i);
    //
    if (!aMFence.Add(aE)) {
      continue;
    }
    //
    bIsToWork=myOriginsToWork.IsBound(aE);
    bHasImage=HasImage(aE);
    if (!bHasImage && !bIsToWork) {
      continue;
    }
    //
    MakeBRepShapes(aE, aEnew);
    //
    //myImages / myOrigins
    if (bIsToWork) {
      const TopoDS_Shape& aSkey=myOriginsToWork.Find(aE);
      const TopTools_ListOfShape& aLSD=myImagesToWork.Find(aSkey);
      //
      myImages.Bind(aEnew, aLSD);
      //
      aItLS.Initialize(aLSD);
      for (; aItLS.More(); aItLS.Next()) {
        const TopoDS_Shape& aEx=aItLS.Value();
        myOrigins.Bind(aEx, aEnew);
        //
        aMFence.Add(aEx);
      }
    }
    else {
      TopTools_ListOfShape aLSD;
      //
      aLSD.Append(aE);
      myImages.Bind(aEnew, aLSD);
      myOrigins.Bind(aE, aEnew);
    }
  }//for (i=1; i<=aNbF; ++i) {
}
Exemplo n.º 4
0
int SMESH_MesherHelper::NbAncestors(const TopoDS_Shape& shape,
                                    const SMESH_Mesh&   mesh,
                                    TopAbs_ShapeEnum    ancestorType/*=TopAbs_SHAPE*/)
{
  TopTools_MapOfShape ancestors;
  TopTools_ListIteratorOfListOfShape ansIt( mesh.GetAncestors(shape) );
  for ( ; ansIt.More(); ansIt.Next() ) {
    if ( ancestorType == TopAbs_SHAPE || ansIt.Value().ShapeType() == ancestorType )
      ancestors.Add( ansIt.Value() );
  }
  return ancestors.Extent();
}
Exemplo n.º 5
0
//=======================================================================
//function :  SupressFaces
//purpose  :
//=======================================================================
void SuppressFacesRec (const TopTools_SequenceOfShape& theShapesFaces,
                       const TopoDS_Shape&             theOriginalShape,
                       TopoDS_Shape&                   theOutShape)
{
  if ((theOriginalShape.ShapeType() != TopAbs_COMPOUND &&
       theOriginalShape.ShapeType() != TopAbs_COMPSOLID))
  {
    ShHealOper_RemoveFace aHealer (theOriginalShape);
    Standard_Boolean aResult = aHealer.Perform(theShapesFaces);

    if (aResult)
      theOutShape = aHealer.GetResultShape();
    else
      raiseNotDoneExeption(aHealer.GetErrorStatus());
  }
  else
  {
    BRep_Builder BB;
    TopoDS_Compound CC;
    BB.MakeCompound(CC);

    TopTools_MapOfShape mapShape;
    TopoDS_Iterator It (theOriginalShape, Standard_True, Standard_True);

    for (; It.More(); It.Next()) {
      TopoDS_Shape aShape_i = It.Value();
      if (mapShape.Add(aShape_i)) {
        // check, if current shape contains at least one of faces to be removed
        bool isFound = false;
        TopTools_IndexedMapOfShape aShapes_i;
        TopExp::MapShapes(aShape_i, aShapes_i);
        for (int i = 1; i <= theShapesFaces.Length() && !isFound; i++) {
          const TopoDS_Shape& aFace_i = theShapesFaces.Value(i);
          if (aShapes_i.Contains(aFace_i)) isFound = true;
        }
        if (isFound) {
          TopoDS_Shape anOutSh_i;
          SuppressFacesRec(theShapesFaces, aShape_i, anOutSh_i);
          if ( !anOutSh_i.IsNull() )
            BB.Add(CC, anOutSh_i);
        }
        else {
          // nothing to do
          BB.Add(CC, aShape_i);
        }
      }
    }
    theOutShape = CC;
  }
}
Exemplo n.º 6
0
//=======================================================================
//function : MakeInternalWires
//purpose  : 
//=======================================================================
void MakeInternalWires(const TopTools_MapOfShape& theME,
		       TopTools_ListOfShape& theWires)
{
  TopTools_MapIteratorOfMapOfShape aItM;
  TopTools_MapOfShape aAddedMap;
  TopTools_ListIteratorOfListOfShape aItE;
  TopTools_IndexedDataMapOfShapeListOfShape aMVE;
  BRep_Builder aBB;
  //
  aItM.Initialize(theME);
  for (; aItM.More(); aItM.Next()) {
    const TopoDS_Shape& aE=aItM.Key();
    TopExp::MapShapesAndAncestors(aE, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
  }
  //
  aItM.Initialize(theME);
  for (; aItM.More(); aItM.Next()) {
    TopoDS_Shape aEE=aItM.Key();
    if (!aAddedMap.Add(aEE)) {
      continue;
    }
    //
    // make a new shell
    TopoDS_Wire aW;
    aBB.MakeWire(aW);    
    aEE.Orientation(TopAbs_INTERNAL);
    aBB.Add(aW, aEE);
    //
    TopoDS_Iterator aItAdded (aW);
    for (; aItAdded.More(); aItAdded.Next()) {
      const TopoDS_Shape& aE =aItAdded.Value();
      //
      TopExp_Explorer aExp(aE, TopAbs_VERTEX);
      for (; aExp.More(); aExp.Next()) {
        const TopoDS_Shape& aV =aExp.Current();
	const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aV);
	aItE.Initialize(aLE);
	for (; aItE.More(); aItE.Next()) { 
	  TopoDS_Shape aEL=aItE.Value();
	  if (aAddedMap.Add(aEL)){
	    aEL.Orientation(TopAbs_INTERNAL);
	    aBB.Add(aW, aEL);
	  }
	}
      }
    }
    theWires.Append(aW);
  }
}
void BRepOffsetAPI_MakeOffsetFix::MakeWire(TopoDS_Shape& wire)
{
    // get the edges of the wire and check which of the stored edges
    // serve as input of the wire
    TopTools_MapOfShape aMap;
    TopExp_Explorer xp(wire, TopAbs_EDGE);
    while (xp.More()) {
        aMap.Add(xp.Current());
        xp.Next();
    }

    std::list<TopoDS_Edge> edgeList;
    for (auto itLoc : myLocations) {
        const TopTools_ListOfShape& newShapes = mkOffset.Generated(itLoc.first);
        for (TopTools_ListIteratorOfListOfShape it(newShapes); it.More(); it.Next()) {
            TopoDS_Shape newShape = it.Value();

            if (aMap.Contains(newShape)) {
                newShape.Move(itLoc.second);
                edgeList.push_back(TopoDS::Edge(newShape));
            }
        }
    }

    if (!edgeList.empty()) {
        BRepBuilderAPI_MakeWire mkWire;
        mkWire.Add(edgeList.front());
        edgeList.pop_front();
        wire = mkWire.Wire();

        bool found = false;
        do {
            found = false;
            for (std::list<TopoDS_Edge>::iterator pE = edgeList.begin(); pE != edgeList.end(); ++pE) {
                mkWire.Add(*pE);
                if (mkWire.Error() != BRepBuilderAPI_DisconnectedWire) {
                    // edge added ==> remove it from list
                    found = true;
                    edgeList.erase(pE);
                    wire = mkWire.Wire();
                    break;
                }
            }
        }
        while (found);
    }
}
Exemplo n.º 8
0
Standard_Boolean ShHealOper_Sewing::getWires(const TopoDS_Shape& theSewShape) const
{
  if(theSewShape.ShapeType() != TopAbs_COMPOUND)
    return Standard_False;
  
  Handle(TopTools_HSequenceOfShape) aSeqEdges = new TopTools_HSequenceOfShape;
  TopExp_Explorer aexpEdges(theSewShape,TopAbs_EDGE,TopAbs_WIRE);
  for ( ; aexpEdges.More(); aexpEdges.Next()) {
    aSeqEdges->Append(aexpEdges.Current());
  }
  if(aSeqEdges->Length() <2)
    return Standard_False;
  //get manifold wires from sewed edges.
  Standard_Real aTol = 0.;
  Standard_Boolean aShared = Standard_True;
  Handle(TopTools_HSequenceOfShape) aTmpWires = new TopTools_HSequenceOfShape;
  ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdges, aTol, aShared, aTmpWires);

  TopTools_MapOfShape aMapEdges;
  Standard_Integer i =1;
  for( ; i <= aSeqEdges->Length(); i++)
    aMapEdges.Add(aSeqEdges->Value(i));
  
  //remove free edges from result shape.
  TopoDS_Compound aNewComp;
  deleteFreeEdges(theSewShape,aMapEdges,aNewComp);
  
  //add new wires in the result shape.
  BRep_Builder aB;
  for( i =1; i <= aTmpWires->Length(); i++) {
    TopoDS_Iterator aite(aTmpWires->Value(i));
    Standard_Integer nbe =0;
    TopoDS_Shape aE;
    for( ; aite.More() && nbe < 3; aite.Next(),nbe++)
      aE = aite.Value();
    if(!nbe)
      continue;
    else if(nbe ==1)
      aB.Add(aNewComp,aE);
    else
      aB.Add(aNewComp,aTmpWires->Value(i));
  }
  
  myContext->Replace(theSewShape,aNewComp);
  return Standard_True;
}
Exemplo n.º 9
0
//=======================================================================
//function : MapShapes
//purpose  :
//=======================================================================
void MapShapes(const TopoDS_Shape& theS,
               TopTools_MapOfShape& theM)
{
    theM.Add(theS);
    TopoDS_Iterator anIt;
    anIt.Initialize(theS);
    for (; anIt.More(); anIt.Next()) {
        const TopoDS_Shape& aSx=anIt.Value();
        MapShapes(aSx, theM);
    }
}
Exemplo n.º 10
0
//=======================================================================
//function : FillImagesCompound
//purpose  :
//=======================================================================
void FillImagesCompound(const TopoDS_Shape& theS,
                        BRepAlgo_Image& theImages,
                        TopTools_MapOfShape& theMFP)
{
    Standard_Boolean bInterferred;
    TopAbs_ShapeEnum aTypeX;
    TopAbs_Orientation aOrX;
    TopoDS_Iterator aIt;
    BRep_Builder aBB;
    TopTools_ListIteratorOfListOfShape aItIm;
    //
    if (!theMFP.Add(theS)) {
        return;
    }
    //
    bInterferred=Standard_False;
    aIt.Initialize(theS);
    for (; aIt.More(); aIt.Next()) {
        const TopoDS_Shape& aSX=aIt.Value();
        aTypeX=aSX.ShapeType();
        if (aTypeX==TopAbs_COMPOUND) {
            FillImagesCompound(aSX, theImages, theMFP);
        }
        if (theImages.HasImage(aSX)) {
            bInterferred=Standard_True;
        }
    }
    if (!bInterferred) {
        return;
    }
    //
    TopoDS_Shape aCIm;
    GEOMAlgo_Tools3D::MakeContainer(TopAbs_COMPOUND, aCIm);
    //
    aIt.Initialize(theS);
    for (; aIt.More(); aIt.Next()) {
        const TopoDS_Shape& aSX=aIt.Value();
        aOrX=aSX.Orientation();
        if (theImages.HasImage(aSX)) {
            const TopTools_ListOfShape& aLFIm=theImages.Image(aSX);
            aItIm.Initialize(aLFIm);
            for (; aItIm.More(); aItIm.Next()) {
                TopoDS_Shape aSXIm=aItIm.Value();
                aSXIm.Orientation(aOrX);
                aBB.Add(aCIm, aSXIm);
            }
        }
        else {
            aBB.Add(aCIm, aSX);
        }
    }
    theImages.Bind(theS, aCIm);
}
Exemplo n.º 11
0
//=======================================================================
//function : CompsolidToCompound
//purpose  :
//=======================================================================
TopoDS_Shape GEOMUtils::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
{
  if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
    return theCompsolid;
  }

  TopoDS_Compound aCompound;
  BRep_Builder B;
  B.MakeCompound(aCompound);

  TopTools_MapOfShape mapShape;
  TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);

  for (; It.More(); It.Next()) {
    TopoDS_Shape aShape_i = It.Value();
    if (mapShape.Add(aShape_i)) {
      B.Add(aCompound, aShape_i);
    }
  }

  return aCompound;
}
Exemplo n.º 12
0
//modified by NIZNHY-PKV Thu Feb 16 12:25:16 2012f
//=======================================================================
//function : IsClosed
//purpose  :
//=======================================================================
Standard_Boolean IsClosed(const TopoDS_Edge& aE,
			  const TopoDS_Face& aF)
{
  Standard_Boolean bRet;
  //
  bRet=BRep_Tool::IsClosed(aE, aF);
  if (bRet) {
    TopTools_MapOfShape aM;
    TopExp_Explorer aExp(aF, TopAbs_EDGE);
    for (; aExp.More(); aExp.Next()) {
      const TopoDS_Shape& aEx=aExp.Current();
      //
      if (aM.Add(aEx)) {
	bRet=aEx.IsSame(aE);
	if (bRet) {
	  break;
	}
      }
    }
  }
  return bRet;
}
Exemplo n.º 13
0
//=======================================================================
//function : AddSimpleShapes
//purpose  :
//=======================================================================
void GEOMUtils::AddSimpleShapes (const TopoDS_Shape& theShape, TopTools_ListOfShape& theList)
{
  if (theShape.ShapeType() != TopAbs_COMPOUND &&
      theShape.ShapeType() != TopAbs_COMPSOLID) {
    theList.Append(theShape);
    return;
  }

  TopTools_MapOfShape mapShape;
  TopoDS_Iterator It (theShape, Standard_True, Standard_True);

  for (; It.More(); It.Next()) {
    TopoDS_Shape aShape_i = It.Value();
    if (mapShape.Add(aShape_i)) {
      if (aShape_i.ShapeType() == TopAbs_COMPOUND ||
          aShape_i.ShapeType() == TopAbs_COMPSOLID) {
        AddSimpleShapes(aShape_i, theList);
      } else {
        theList.Append(aShape_i);
      }
    }
  }
}
//=======================================================================
//function : isGoodForChamfer
//purpose  :
//=======================================================================
static Standard_Boolean isGoodForChamfer (const TopoDS_Shape& theShape)
{
  if (theShape.ShapeType() == TopAbs_SHELL ||
      theShape.ShapeType() == TopAbs_SOLID ||
      theShape.ShapeType() == TopAbs_COMPSOLID) {
    return Standard_True;
  }

  if (theShape.ShapeType() == TopAbs_COMPOUND) {
    TopTools_MapOfShape mapShape;
    TopoDS_Iterator It (theShape, Standard_False, Standard_False);
    for (; It.More(); It.Next()) {
      if (mapShape.Add(It.Value())) {
        if (!isGoodForChamfer(It.Value())) {
          return Standard_False;
        }
      }
    }
    return Standard_True;
  }

  return Standard_False;
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IFillet1d aCI (aFunction);

  Handle(GEOM_Function) aRefShape = aCI.GetShape();
  TopoDS_Shape aShape = aRefShape->GetValue();
  if (aShape.IsNull())
    return 0;
  if (aShape.ShapeType() != TopAbs_WIRE)
    Standard_ConstructionError::Raise("Wrong arguments: polyline as wire must be given");

  TopoDS_Wire aWire = TopoDS::Wire(aShape);

  double rad = aCI.GetR();

  if ( rad < Precision::Confusion())
    return 0;

  // collect vertices for make fillet
  TopTools_ListOfShape aVertexList;
  TopTools_MapOfShape mapShape;
  int aLen = aCI.GetLength();
  if ( aLen > 0 ) {
    for (int ind = 1; ind <= aLen; ind++) {
      TopoDS_Shape aShapeVertex;
      if (GEOMImpl_ILocalOperations::GetSubShape
          (aWire, aCI.GetVertex(ind), aShapeVertex))
        if (mapShape.Add(aShapeVertex))
          aVertexList.Append( aShapeVertex );
    }
  } else { // get all vertices from wire
    TopExp_Explorer anExp( aWire, TopAbs_VERTEX );
    for ( ; anExp.More(); anExp.Next() ) {
      if (mapShape.Add(anExp.Current()))
        aVertexList.Append( anExp.Current() );
    }
  }
  if (aVertexList.IsEmpty())
    Standard_ConstructionError::Raise("Invalid input no vertices to make fillet");

  //INFO: this algorithm implemented in assumption that user can select both
  //  vertices of some edges to make fillet. In this case we should remember
  //  already modified initial edges to take care in next fillet step
  TopTools_DataMapOfShapeShape anEdgeToEdgeMap;

  //iterates on vertices, and make fillet on each couple of edges
  //collect result fillet edges in list
  TopTools_ListOfShape aListOfNewEdge;
  // remember relation between initial and modified map
  TopTools_IndexedDataMapOfShapeListOfShape aMapVToEdges;
  TopExp::MapShapesAndAncestors( aWire, TopAbs_VERTEX, TopAbs_EDGE, aMapVToEdges );
  TopTools_ListIteratorOfListOfShape anIt( aVertexList );
  for ( ; anIt.More(); anIt.Next() ) {
    TopoDS_Vertex aV = TopoDS::Vertex( anIt.Value() );
    if ( aV.IsNull() || !aMapVToEdges.Contains( aV ) )
      continue;
    const TopTools_ListOfShape& aVertexEdges = aMapVToEdges.FindFromKey( aV );
    if ( aVertexEdges.Extent() != 2 )
      continue; // no input data to make fillet
    TopoDS_Edge anEdge1 = TopoDS::Edge( aVertexEdges.First() );
    TopoDS_Edge anEdge2 = TopoDS::Edge( aVertexEdges.Last() );
    // check if initial edges already modified in previous fillet operation
    if ( anEdgeToEdgeMap.IsBound( anEdge1 ) ) anEdge1 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge1 ));
    if ( anEdgeToEdgeMap.IsBound( anEdge2 ) ) anEdge2 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge2 ));
    if ( anEdge1.IsNull() || anEdge2.IsNull() || anEdge1.IsSame( anEdge2 ) )
      continue; //no input data to make fillet

    // create plane on 2 edges
    gp_Pln aPlane;
    if ( !takePlane(anEdge1, anEdge2, aV, aPlane) )
      continue; // seems edges does not belong to same plane or parallel (fillet can not be build)

    GEOMImpl_Fillet1d aFilletAlgo(anEdge1, anEdge2, aPlane);
    if ( !aFilletAlgo.Perform(rad) )
      continue; // can not create fillet with given radius

    // take fillet result in given vertex
    TopoDS_Edge aModifE1, aModifE2;
    TopoDS_Edge aNewE = aFilletAlgo.Result(BRep_Tool::Pnt(aV), aModifE1, aModifE2);
    if (aNewE.IsNull())
      continue; // no result found

    // add  new created edges and take modified edges
    aListOfNewEdge.Append( aNewE );

    // check if face edges modified,
    // if yes, than map to original edges (from vertex-edges list), because edges can be modified before
    if (aModifE1.IsNull() || !anEdge1.IsSame( aModifE1 ))
      addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.First()), aModifE1 );
    if (aModifE2.IsNull() || !anEdge2.IsSame( aModifE2 ))
      addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.Last()), aModifE2 );
  }

  if ( anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty() ) {
    StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius");
    return 0;
  }

  // create new wire instead of original
  for ( TopExp_Explorer anExp( aWire, TopAbs_EDGE ); anExp.More(); anExp.Next() ) {
    TopoDS_Shape anEdge = anExp.Current();
    if ( !anEdgeToEdgeMap.IsBound( anEdge ) )
      aListOfNewEdge.Append( anEdge );
    else if (!anEdgeToEdgeMap.Find( anEdge ).IsNull())
      aListOfNewEdge.Append( anEdgeToEdgeMap.Find( anEdge ) );
  }

  GEOMImpl_IShapesOperations::SortShapes( aListOfNewEdge );

  BRepBuilderAPI_MakeWire aWireTool;
  aWireTool.Add( aListOfNewEdge );
  aWireTool.Build();
  if (!aWireTool.IsDone())
    return 0;

  aWire = aWireTool.Wire();
  aFunction->SetValue(aWire);
  log.SetTouched(Label());

  return 1;
}
bool NETGENPlugin_Mesher::fillNgMesh(netgen::OCCGeometry&           occgeom,
                                     netgen::Mesh&                  ngMesh,
                                     vector<SMDS_MeshNode*>&        nodeVec,
                                     const list< SMESH_subMesh* > & meshedSM)
{
  TNode2IdMap nodeNgIdMap;

  TopTools_MapOfShape visitedShapes;

  SMESH_MesherHelper helper (*_mesh);

  int faceID = occgeom.fmap.Extent();
  _faceDescriptors.clear();

  list< SMESH_subMesh* >::const_iterator smIt, smEnd = meshedSM.end();
  for ( smIt = meshedSM.begin(); smIt != smEnd; ++smIt )
  {
    SMESH_subMesh* sm = *smIt;
    if ( !visitedShapes.Add( sm->GetSubShape() ))
      continue;

    SMESHDS_SubMesh * smDS = sm->GetSubMeshDS();

    switch ( sm->GetSubShape().ShapeType() )
    {
    case TopAbs_EDGE: { // EDGE
      // ----------------------
      const TopoDS_Edge& geomEdge  = TopoDS::Edge( sm->GetSubShape() );

      // Add ng segments for each not meshed face the edge bounds
      TopTools_MapOfShape visitedAncestors;
      const TopTools_ListOfShape& ancestors = _mesh->GetAncestors( geomEdge );
      TopTools_ListIteratorOfListOfShape ancestorIt ( ancestors );
      for ( ; ancestorIt.More(); ancestorIt.Next() )
      {
        const TopoDS_Shape & ans = ancestorIt.Value();
        if ( ans.ShapeType() != TopAbs_FACE || !visitedAncestors.Add( ans ))
          continue;
        const TopoDS_Face& face = TopoDS::Face( ans );

        int faceID = occgeom.fmap.FindIndex( face );
        if ( faceID < 1 )
          continue; // meshed face

        // find out orientation of geomEdge within face
        bool isForwad = false;
        for ( TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next() ) {
          if ( geomEdge.IsSame( exp.Current() )) {
            isForwad = ( exp.Current().Orientation() == geomEdge.Orientation() );
            break;
          }
        }
        bool isQuad = smDS->GetElements()->next()->IsQuadratic();

        // get all nodes from geomEdge
        StdMeshers_FaceSide fSide( face, geomEdge, _mesh, isForwad, isQuad );
        const vector<UVPtStruct>& points = fSide.GetUVPtStruct();
        int i, nbSeg = fSide.NbSegments();

        double otherSeamParam = 0;
        helper.SetSubShape( face );
        bool isSeam = helper.IsRealSeam( geomEdge );
        if ( isSeam )
          otherSeamParam =
            helper.GetOtherParam( helper.GetPeriodicIndex() == 1 ? points[0].u : points[0].v );

        // add segments

        int prevNgId = ngNodeId( points[0].node, ngMesh, nodeNgIdMap );

        for ( i = 0; i < nbSeg; ++i )
        {
          const UVPtStruct& p1 = points[ i ];
          const UVPtStruct& p2 = points[ i+1 ];

          netgen::Segment seg;
          // ng node ids
          seg.p1 = prevNgId;
          seg.p2 = prevNgId = ngNodeId( p2.node, ngMesh, nodeNgIdMap );
          // node param on curve
          seg.epgeominfo[ 0 ].dist = p1.param;
          seg.epgeominfo[ 1 ].dist = p2.param;
          // uv on face
          seg.epgeominfo[ 0 ].u = p1.u;
          seg.epgeominfo[ 0 ].v = p1.v;
          seg.epgeominfo[ 1 ].u = p2.u;
          seg.epgeominfo[ 1 ].v = p2.v;

          //seg.epgeominfo[ iEnd ].edgenr = edgeID; //  = geom.emap.FindIndex(edge);
          seg.si = faceID;                   // = geom.fmap.FindIndex (face);
          seg.edgenr = ngMesh.GetNSeg() + 1; // segment id
          ngMesh.AddSegment (seg);

          if ( isSeam )
          {
            if ( helper.GetPeriodicIndex() == 1 ) {
              seg.epgeominfo[ 0 ].u = otherSeamParam;
              seg.epgeominfo[ 1 ].u = otherSeamParam;
              swap (seg.epgeominfo[0].v, seg.epgeominfo[1].v);
            } else {
              seg.epgeominfo[ 0 ].v = otherSeamParam;
              seg.epgeominfo[ 1 ].v = otherSeamParam;
              swap (seg.epgeominfo[0].u, seg.epgeominfo[1].u);
            }
            swap (seg.p1, seg.p2);
            swap (seg.epgeominfo[0].dist, seg.epgeominfo[1].dist);
            seg.edgenr = ngMesh.GetNSeg() + 1; // segment id
            ngMesh.AddSegment (seg);
          }
        }
      } // loop on geomEdge ancestors

      break;
    } // case TopAbs_EDGE

    case TopAbs_FACE: { // FACE
      // ----------------------
      const TopoDS_Face& geomFace  = TopoDS::Face( sm->GetSubShape() );
      helper.SetSubShape( geomFace );

      // Find solids the geomFace bounds
      int solidID1 = 0, solidID2 = 0;
      const TopTools_ListOfShape& ancestors = _mesh->GetAncestors( geomFace );
      TopTools_ListIteratorOfListOfShape ancestorIt ( ancestors );
      for ( ; ancestorIt.More(); ancestorIt.Next() )
      {
        const TopoDS_Shape & solid = ancestorIt.Value();
        if ( solid.ShapeType() == TopAbs_SOLID  ) {
          int id = occgeom.somap.FindIndex ( solid );
          if ( solidID1 && id != solidID1 ) solidID2 = id;
          else                              solidID1 = id;
        }
      }
      faceID++;
      _faceDescriptors[ faceID ].first  = solidID1;
      _faceDescriptors[ faceID ].second = solidID2;

      // Orient the face correctly in solidID1 (issue 0020206)
      bool reverse = false;
      if ( solidID1 ) {
        TopoDS_Shape solid = occgeom.somap( solidID1 );
        for ( TopExp_Explorer f( solid, TopAbs_FACE ); f.More(); f.Next() ) {
          if ( geomFace.IsSame( f.Current() )) {
            reverse = SMESH_Algo::IsReversedSubMesh( TopoDS::Face( f.Current()), helper.GetMeshDS() );
            break;
          }
        }
      }

      // Add surface elements
      SMDS_ElemIteratorPtr faces = smDS->GetElements();
      while ( faces->more() ) {

        const SMDS_MeshElement* f = faces->next();
        if ( f->NbNodes() % 3 != 0 ) { // not triangle
          for ( ancestorIt.Initialize(ancestors); ancestorIt.More(); ancestorIt.Next() )
            if ( ancestorIt.Value().ShapeType() == TopAbs_SOLID  ) {
              sm = _mesh->GetSubMesh( ancestorIt.Value() );
              break;
            }
          SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
          smError.reset( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"Not triangle submesh"));
          smError->myBadElements.push_back( f );
          return false;
        }

        netgen::Element2d tri(3);
        tri.SetIndex ( faceID );

        for ( int i = 0; i < 3; ++i ) {
          const SMDS_MeshNode* node = f->GetNode( i ), * inFaceNode=0;
          if ( helper.IsSeamShape( node->GetPosition()->GetShapeId() ))
            if ( helper.IsSeamShape( f->GetNodeWrap( i+1 )->GetPosition()->GetShapeId() ))
              inFaceNode = f->GetNodeWrap( i-1 );
            else 
              inFaceNode = f->GetNodeWrap( i+1 );

          gp_XY uv = helper.GetNodeUV( geomFace, node, inFaceNode );
          if ( reverse ) {
            tri.GeomInfoPi(3-i).u = uv.X();
            tri.GeomInfoPi(3-i).v = uv.Y();
            tri.PNum      (3-i) = ngNodeId( node, ngMesh, nodeNgIdMap );
          } else {
            tri.GeomInfoPi(i+1).u = uv.X();
            tri.GeomInfoPi(i+1).v = uv.Y();
            tri.PNum      (i+1) = ngNodeId( node, ngMesh, nodeNgIdMap );
          }
        }

        ngMesh.AddSurfaceElement (tri);

      }
      break;
    } //

    case TopAbs_VERTEX: { // VERTEX
      // --------------------------
      SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes();
      if ( nodeIt->more() )
        ngNodeId( nodeIt->next(), ngMesh, nodeNgIdMap );
      break;
    }
    default:;
    } // switch
  } // loop on submeshes

  // fill nodeVec
  nodeVec.resize( ngMesh.GetNP() + 1 );
  TNode2IdMap::iterator node_NgId, nodeNgIdEnd = nodeNgIdMap.end();
  for ( node_NgId = nodeNgIdMap.begin(); node_NgId != nodeNgIdEnd; ++node_NgId)
    nodeVec[ node_NgId->second ] = (SMDS_MeshNode*) node_NgId->first;

  return true;
}
//=============================================================================
bool NETGENPlugin_Mesher::Compute()
{
#ifdef WNT
  netgen::MeshingParameters& mparams = netgen::GlobalMeshingParameters();
#else
  netgen::MeshingParameters& mparams = netgen::mparam;
#endif  
  MESSAGE("Compute with:\n"
          " max size = " << mparams.maxh << "\n"
          " segments per edge = " << mparams.segmentsperedge);
  MESSAGE("\n"
          " growth rate = " << mparams.grading << "\n"
          " elements per radius = " << mparams.curvaturesafety << "\n"
          " second order = " << mparams.secondorder << "\n"
          " quad allowed = " << mparams.quad);

  SMESH_ComputeErrorPtr error = SMESH_ComputeError::New();
  nglib::Ng_Init();

  // -------------------------
  // Prepare OCC geometry
  // -------------------------

  netgen::OCCGeometry occgeo;
  list< SMESH_subMesh* > meshedSM;
  PrepareOCCgeometry( occgeo, _shape, *_mesh, &meshedSM );

  // -------------------------
  // Generate the mesh
  // -------------------------

  netgen::Mesh *ngMesh = NULL;

  SMESH_Comment comment;
  int err = 0;
  int nbInitNod = 0;
  int nbInitSeg = 0;
  int nbInitFac = 0;
  // vector of nodes in which node index == netgen ID
  vector< SMDS_MeshNode* > nodeVec;
  try
  {
    // ----------------
    // compute 1D mesh
    // ----------------
    // pass 1D simple parameters to NETGEN
    if ( _simpleHyp ) {
      if ( int nbSeg = _simpleHyp->GetNumberOfSegments() ) {
        // nb of segments
        mparams.segmentsperedge = nbSeg + 0.1;
        mparams.maxh = occgeo.boundingbox.Diam();
        mparams.grading = 0.01;
      }
      else {
        // segment length
        mparams.segmentsperedge = 1;
        mparams.maxh = _simpleHyp->GetLocalLength();
      }
    }
    // let netgen create ngMesh and calculate element size on not meshed shapes
    char *optstr = 0;
    int startWith = netgen::MESHCONST_ANALYSE;
    int endWith   = netgen::MESHCONST_ANALYSE;
    err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr);
    if (err) comment << "Error in netgen::OCCGenerateMesh() at MESHCONST_ANALYSE step";

    // fill ngMesh with nodes and elements of computed submeshes
    err = ! fillNgMesh(occgeo, *ngMesh, nodeVec, meshedSM);
    nbInitNod = ngMesh->GetNP();
    nbInitSeg = ngMesh->GetNSeg();
    nbInitFac = ngMesh->GetNSE();

    // compute mesh
    if (!err)
    {
      startWith = endWith = netgen::MESHCONST_MESHEDGES;
      err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr);
      if (err) comment << "Error in netgen::OCCGenerateMesh() at 1D mesh generation";
    }
    // ---------------------
    // compute surface mesh
    // ---------------------
    if (!err)
    {
      // pass 2D simple parameters to NETGEN
      if ( _simpleHyp ) {
        if ( double area = _simpleHyp->GetMaxElementArea() ) {
          // face area
          mparams.maxh = sqrt(2. * area/sqrt(3.0));
          mparams.grading = 0.4; // moderate size growth
        }
        else {
          // length from edges
          double length = 0;
          TopTools_MapOfShape tmpMap;
          for ( TopExp_Explorer exp( _shape, TopAbs_EDGE ); exp.More(); exp.Next() )
            if( tmpMap.Add(exp.Current()) )
              length += SMESH_Algo::EdgeLength( TopoDS::Edge( exp.Current() ));

          if ( ngMesh->GetNSeg() ) {
            // we have to multiply length by 2 since for each TopoDS_Edge there
            // are double set of NETGEN edges or, in other words, we have to
            // divide ngMesh->GetNSeg() on 2.
            mparams.maxh = 2*length / ngMesh->GetNSeg();
          }
          else
            mparams.maxh = 1000;
          mparams.grading = 0.2; // slow size growth
        }
        mparams.maxh = min( mparams.maxh, occgeo.boundingbox.Diam()/2 );
        ngMesh->SetGlobalH (mparams.maxh);
        netgen::Box<3> bb = occgeo.GetBoundingBox();
        bb.Increase (bb.Diam()/20);
        ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparams.grading);
      }
      // let netgen compute 2D mesh
      startWith = netgen::MESHCONST_MESHSURFACE;
      endWith = _optimize ? netgen::MESHCONST_OPTSURFACE : netgen::MESHCONST_MESHSURFACE;
      err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr);
      if (err) comment << "Error in netgen::OCCGenerateMesh() at surface mesh generation";
    }
    // ---------------------
    // generate volume mesh
    // ---------------------
    if (!err && _isVolume)
    {
      // add ng face descriptors of meshed faces
      std::map< int, std::pair<int,int> >::iterator fId_soIds = _faceDescriptors.begin();
      for ( ; fId_soIds != _faceDescriptors.end(); ++fId_soIds ) {
        int faceID   = fId_soIds->first;
        int solidID1 = fId_soIds->second.first;
        int solidID2 = fId_soIds->second.second;
        ngMesh->AddFaceDescriptor (netgen::FaceDescriptor(faceID, solidID1, solidID2, 0));
      }
      // pass 3D simple parameters to NETGEN
      const NETGENPlugin_SimpleHypothesis_3D* simple3d =
        dynamic_cast< const NETGENPlugin_SimpleHypothesis_3D* > ( _simpleHyp );
      if ( simple3d ) {
        if ( double vol = simple3d->GetMaxElementVolume() ) {
          // max volume
          mparams.maxh = pow( 72, 1/6. ) * pow( vol, 1/3. );
          mparams.maxh = min( mparams.maxh, occgeo.boundingbox.Diam()/2 );
        }
        else {
          // length from faces
          mparams.maxh = ngMesh->AverageH();
        }
//      netgen::ARRAY<double> maxhdom;
//      maxhdom.SetSize (occgeo.NrSolids());
//      maxhdom = mparams.maxh;
//      ngMesh->SetMaxHDomain (maxhdom);
        ngMesh->SetGlobalH (mparams.maxh);
        mparams.grading = 0.4;
        ngMesh->CalcLocalH();
      }
      // let netgen compute 3D mesh
      startWith = netgen::MESHCONST_MESHVOLUME;
      endWith = _optimize ? netgen::MESHCONST_OPTVOLUME : netgen::MESHCONST_MESHVOLUME;
      err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr);
      if (err) comment << "Error in netgen::OCCGenerateMesh()";
    }
    if (!err && mparams.secondorder > 0)
    {
      netgen::OCCRefinementSurfaces ref (occgeo);
      ref.MakeSecondOrder (*ngMesh);
    }
  }
  catch (netgen::NgException exc)
  {
    error->myName = err = COMPERR_ALGO_FAILED;
    comment << exc.What();
  }

  int nbNod = ngMesh->GetNP();
  int nbSeg = ngMesh->GetNSeg();
  int nbFac = ngMesh->GetNSE();
  int nbVol = ngMesh->GetNE();

  MESSAGE((err ? "Mesh Generation failure" : "End of Mesh Generation") <<
          ", nb nodes: " << nbNod <<
          ", nb segments: " << nbSeg <<
          ", nb faces: " << nbFac <<
          ", nb volumes: " << nbVol);

  // -----------------------------------------------------------
  // Feed back the SMESHDS with the generated Nodes and Elements
  // -----------------------------------------------------------

  SMESHDS_Mesh* meshDS = _mesh->GetMeshDS();
  bool isOK = ( !err && (_isVolume ? (nbVol > 0) : (nbFac > 0)) );
  if ( true /*isOK*/ ) // get whatever built
  {
    // map of nodes assigned to submeshes
    NCollection_Map<int> pindMap;
    // create and insert nodes into nodeVec
    nodeVec.resize( nbNod + 1 );
    int i;
    for (i = nbInitNod+1; i <= nbNod /*&& isOK*/; ++i )
    {
      const netgen::MeshPoint& ngPoint = ngMesh->Point(i);
      SMDS_MeshNode* node = NULL;
      bool newNodeOnVertex = false;
      TopoDS_Vertex aVert;
      if (i-nbInitNod <= occgeo.vmap.Extent())
      {
        // point on vertex
        aVert = TopoDS::Vertex(occgeo.vmap(i-nbInitNod));
        SMESHDS_SubMesh * submesh = meshDS->MeshElements(aVert);
        if (submesh)
        {
          SMDS_NodeIteratorPtr it = submesh->GetNodes();
          if (it->more())
          {
            node = const_cast<SMDS_MeshNode*> (it->next());
            pindMap.Add(i);
          }
        }
        if (!node)
          newNodeOnVertex = true;
      }
      if (!node)
        node = meshDS->AddNode(ngPoint.X(), ngPoint.Y(), ngPoint.Z());
      if (!node)
      {
        MESSAGE("Cannot create a mesh node");
        if ( !comment.size() ) comment << "Cannot create a mesh node";
        nbSeg = nbFac = nbVol = isOK = 0;
        break;
      }
      nodeVec.at(i) = node;
      if (newNodeOnVertex)
      {
        // point on vertex
        meshDS->SetNodeOnVertex(node, aVert);
        pindMap.Add(i);
      }
    }

    // create mesh segments along geometric edges
    NCollection_Map<Link> linkMap;
    for (i = nbInitSeg+1; i <= nbSeg/* && isOK*/; ++i )
    {
      const netgen::Segment& seg = ngMesh->LineSegment(i);
      Link link(seg.p1, seg.p2);
      if (linkMap.Contains(link))
        continue;
      linkMap.Add(link);
      TopoDS_Edge aEdge;
      int pinds[3] = { seg.p1, seg.p2, seg.pmid };
      int nbp = 0;
      double param2 = 0;
      for (int j=0; j < 3; ++j)
      {
        int pind = pinds[j];
        if (pind <= 0) continue;
        ++nbp;
        double param;
        if (j < 2)
        {
          if (aEdge.IsNull())
          {
            int aGeomEdgeInd = seg.epgeominfo[j].edgenr;
            if (aGeomEdgeInd > 0 && aGeomEdgeInd <= occgeo.emap.Extent())
              aEdge = TopoDS::Edge(occgeo.emap(aGeomEdgeInd));
          }
          param = seg.epgeominfo[j].dist;
          param2 += param;
        }
        else
          param = param2 * 0.5;
        if (pind <= nbInitNod || pindMap.Contains(pind))
          continue;
        if (!aEdge.IsNull())
        {
          meshDS->SetNodeOnEdge(nodeVec.at(pind), aEdge, param);
          pindMap.Add(pind);
        }
      }
      SMDS_MeshEdge* edge;
      if (nbp < 3) // second order ?
        edge = meshDS->AddEdge(nodeVec.at(pinds[0]), nodeVec.at(pinds[1]));
      else
        edge = meshDS->AddEdge(nodeVec.at(pinds[0]), nodeVec.at(pinds[1]),
                                nodeVec.at(pinds[2]));
      if (!edge)
      {
        if ( !comment.size() ) comment << "Cannot create a mesh edge";
        MESSAGE("Cannot create a mesh edge");
        nbSeg = nbFac = nbVol = isOK = 0;
        break;
      }
      if (!aEdge.IsNull())
        meshDS->SetMeshElementOnShape(edge, aEdge);
    }

    // create mesh faces along geometric faces
    for (i = nbInitFac+1; i <= nbFac/* && isOK*/; ++i )
    {
      const netgen::Element2d& elem = ngMesh->SurfaceElement(i);
      int aGeomFaceInd = elem.GetIndex();
      TopoDS_Face aFace;
      if (aGeomFaceInd > 0 && aGeomFaceInd <= occgeo.fmap.Extent())
        aFace = TopoDS::Face(occgeo.fmap(aGeomFaceInd));
      vector<SMDS_MeshNode*> nodes;
      for (int j=1; j <= elem.GetNP(); ++j)
      {
        int pind = elem.PNum(j);
        SMDS_MeshNode* node = nodeVec.at(pind);
        nodes.push_back(node);
        if (pind <= nbInitNod || pindMap.Contains(pind))
          continue;
        if (!aFace.IsNull())
        {
          const netgen::PointGeomInfo& pgi = elem.GeomInfoPi(j);
          meshDS->SetNodeOnFace(node, aFace, pgi.u, pgi.v);
          pindMap.Add(pind);
        }
      }
      SMDS_MeshFace* face = NULL;
      switch (elem.GetType())
      {
      case netgen::TRIG:
        face = meshDS->AddFace(nodes[0],nodes[1],nodes[2]);
        break;
      case netgen::QUAD:
        face = meshDS->AddFace(nodes[0],nodes[1],nodes[2],nodes[3]);
        break;
      case netgen::TRIG6:
        face = meshDS->AddFace(nodes[0],nodes[1],nodes[2],nodes[5],nodes[3],nodes[4]);
        break;
      case netgen::QUAD8:
        face = meshDS->AddFace(nodes[0],nodes[1],nodes[2],nodes[3],
                               nodes[4],nodes[7],nodes[5],nodes[6]);
        break;
      default:
        MESSAGE("NETGEN created a face of unexpected type, ignoring");
        continue;
      }
      if (!face)
      {
        if ( !comment.size() ) comment << "Cannot create a mesh face";
        MESSAGE("Cannot create a mesh face");
        nbSeg = nbFac = nbVol = isOK = 0;
        break;
      }
      if (!aFace.IsNull())
        meshDS->SetMeshElementOnShape(face, aFace);
    }

    // create tetrahedra
    for (i = 1; i <= nbVol/* && isOK*/; ++i)
    {
      const netgen::Element& elem = ngMesh->VolumeElement(i);      
      int aSolidInd = elem.GetIndex();
      TopoDS_Solid aSolid;
      if (aSolidInd > 0 && aSolidInd <= occgeo.somap.Extent())
        aSolid = TopoDS::Solid(occgeo.somap(aSolidInd));
      vector<SMDS_MeshNode*> nodes;
      for (int j=1; j <= elem.GetNP(); ++j)
      {
        int pind = elem.PNum(j);
        SMDS_MeshNode* node = nodeVec.at(pind);
        nodes.push_back(node);
        if (pind <= nbInitNod || pindMap.Contains(pind))
          continue;
        if (!aSolid.IsNull())
        {
          // point in solid
          meshDS->SetNodeInVolume(node, aSolid);
          pindMap.Add(pind);
        }
      }
      SMDS_MeshVolume* vol = NULL;
      switch (elem.GetType())
      {
      case netgen::TET:
        vol = meshDS->AddVolume(nodes[0],nodes[1],nodes[2],nodes[3]);
        break;
      case netgen::TET10:
        vol = meshDS->AddVolume(nodes[0],nodes[1],nodes[2],nodes[3],
                                nodes[4],nodes[7],nodes[5],nodes[6],nodes[8],nodes[9]);
        break;
      default:
        MESSAGE("NETGEN created a volume of unexpected type, ignoring");
        continue;
      }
      if (!vol)
      {
        if ( !comment.size() ) comment << "Cannot create a mesh volume";
        MESSAGE("Cannot create a mesh volume");
        nbSeg = nbFac = nbVol = isOK = 0;
        break;
      }
      if (!aSolid.IsNull())
        meshDS->SetMeshElementOnShape(vol, aSolid);
    }
  }

  if ( error->IsOK() && ( !isOK || comment.size() > 0 ))
    error->myName = COMPERR_ALGO_FAILED;
  if ( !comment.empty() )
    error->myComment = comment;

  // set bad compute error to subshapes of all failed subshapes shapes
  if ( !error->IsOK() && err )
  {
    for (int i = 1; i <= occgeo.fmap.Extent(); i++) {
      int status = occgeo.facemeshstatus[i-1];
      if (status == 1 ) continue;
      if ( SMESH_subMesh* sm = _mesh->GetSubMeshContaining( occgeo.fmap( i ))) {
        SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
        if ( !smError || smError->IsOK() ) {
          if ( status == -1 )
            smError.reset( new SMESH_ComputeError( error->myName, error->myComment ));
          else
            smError.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED, "Ignored" ));
        }
      }
    }
  }

  nglib::Ng_DeleteMesh((nglib::Ng_Mesh*)ngMesh);
  nglib::Ng_Exit();

  RemoveTmpFiles();

  return error->IsOK();
}
Exemplo n.º 18
0
//=======================================================================
// function: FillInternalVertices
// purpose:
//=======================================================================
void GEOMAlgo_Builder::FillInternalVertices()
{
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  NMTTools_PaveFiller* pPF=myPaveFiller;
  NMTDS_InterfPool* pIP=pPF->IP();
  const Handle(IntTools_Context)& aCtx= pPF->Context();
  //
  BOPTools_CArray1OfVSInterference& aVFs=pIP->VSInterferences();
  BOPTools_CArray1OfESInterference& aEFs=pIP->ESInterferences();
  const NMTTools_IndexedDataMapOfIndexedMapOfInteger& aMAV=pPF->AloneVertices();
  //
  Standard_Boolean bHasImage;
  Standard_Integer i, j, nF, aNbS, nV, nVSD, n1, n2, iFlag;
  Standard_Integer aNbVFs, aNbAVF, aNbEFs, aNbVC, aNbE, aNbV;
  Standard_Real aU1, aU2, aTol;
  NMTTools_IndexedDataMapOfIndexedMapOfInteger aMFMV;
  TopTools_MapOfShape aMFence;
  TopTools_ListIteratorOfListOfShape aIt, aItV;
  BRep_Builder aBB;
  //
  // 1. Collect face-vertex candidates [aMFMV]
  //
  // 1.1. VFs
  aNbVFs=aVFs.Extent();
  for (i=1; i<=aNbVFs; ++i) {
    const BOPTools_VSInterference& aVS=aVFs(i);
    aVS.Indices(n1, n2);
    nF=n2;
    nV=n1;
    if (aDS.Shape(n1).ShapeType()==TopAbs_FACE) {
      nF=n1;
      nV=n2;
    }
    nVSD=pPF->FindSDVertex(nV);
    if (nVSD) {
      nV=nVSD;
    }
    //
    UpdateCandidates(nF, nV, aMFMV);
  }
  //
  // 1.2 EFs
  aNbEFs=aEFs.Extent();
  for (i=1; i<=aNbEFs; ++i) {
    const BOPTools_ESInterference& aEF=aEFs(i);
    aEF.Indices(n1, n2);
    nV=aEF.NewShape();
    if (!nV) {
      continue;
    }
    const TopoDS_Shape& aSnew=aDS.Shape(nV);
    if (aSnew.ShapeType()!=TopAbs_VERTEX) {
      continue;
    }
    //
    nF=(aDS.Shape(n1).ShapeType()==TopAbs_FACE) ? n1 : n2;
    nVSD=pPF->FindSDVertex(nV);
    if (nVSD) {
      nV=nVSD;
    }
    UpdateCandidates(nF, nV, aMFMV);
  }
  //
  aNbS=aDS.NumberOfShapesOfTheObject();
  for (nF=1; nF<=aNbS; ++nF) {
    const TopoDS_Shape& aF=aDS.Shape(nF);
    //
    if (aF.ShapeType()!=TopAbs_FACE) {
      continue;
    }
    if (!aMFence.Add(aF)) {
      continue;
    }
    //
    const TopoDS_Face& aFF=TopoDS::Face(aF);
    aTol=BRep_Tool::Tolerance(aFF);
    //
    // 1.3 FFs
    if (aMAV.Contains(nF)) {
      const TColStd_IndexedMapOfInteger& aMAVF=aMAV.FindFromKey(nF);
      aNbAVF=aMAVF.Extent();
      for (j=1; j<=aNbAVF; ++j) {
        nV=aMAVF(j);
        nVSD=pPF->FindSDVertex(nV);
        if (nVSD) {
          nV=nVSD;
        }
        //
        UpdateCandidates(nF, nV, aMFMV);
      }
    }
    //
    // 1.4 Internal vertices of the face nF
    BooleanOperations_OnceExplorer aExp(aDS);
    aExp.Init(nF, TopAbs_VERTEX);
    for (; aExp.More(); aExp.Next()) {
      nV=aExp.Current();
      const TopoDS_Shape& aV=aDS.Shape(nV);
      if (aV.Orientation()==TopAbs_INTERNAL) {
        nVSD=pPF->FindSDVertex(nV);
        if (nVSD) {
          nV=nVSD;
        }
        //
        UpdateCandidates(nF, nV, aMFMV);
      }
    }
    //
    // 2. Process face nF
    if (!aMFMV.Contains(nF)) {
      continue;
    }
    //
    const TColStd_IndexedMapOfInteger& aMVC=aMFMV.FindFromKey(nF);
    aNbVC=aMVC.Extent();
    if (!aNbVC) {
      continue;
    }
    //
    // 2.1 Refine candidates
    TopTools_IndexedDataMapOfShapeListOfShape aMVE;
    TopTools_ListOfShape aLV;
    //
    bHasImage=myImages.HasImage(aF);
    if (bHasImage) {
      const TopTools_ListOfShape& aLFx=myImages.Image(aF);
      aIt.Initialize(aLFx);
      for (; aIt.More(); aIt.Next()) {
        const TopoDS_Shape& aFx=aIt.Value();
        TopExp::MapShapesAndAncestors(aFx, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
      }
    }
    else {
      Standard_Boolean bFaceToProcess;
      //
      TopExp::MapShapesAndAncestors(aF, TopAbs_VERTEX, TopAbs_EDGE, aMVE);
      bFaceToProcess=Standard_False;
      for (j=1; j<=aNbVC; ++j) {
        nV=aMVC(j);
        const TopoDS_Shape& aV=aDS.Shape(nV);
        if (!aMVE.Contains(aV)) {
          bFaceToProcess=!bFaceToProcess;
          break;
        }
      }
      if (!bFaceToProcess) {
        continue;
      }
    }// else
    //
    for (j=1; j<=aNbVC; ++j) {
      nV=aMVC(j);
      const TopoDS_Shape& aV=aDS.Shape(nV);
      if (aMVE.Contains(aV)) {
        const TopTools_ListOfShape& aLE=aMVE.FindFromKey(aV);
        aNbE=aLE.Extent();
        if (aNbE) {
          continue;
        }
      }
      aLV.Append(aV);
    }
    //
    aNbV=aLV.Extent();
    if (aNbV) {
      //  3. Try to put vertices into the face(s)
      aItV.Initialize(aLV);
      for (; aItV.More(); aItV.Next()) {
        TopoDS_Vertex aV=TopoDS::Vertex(aItV.Value());
        aV.Orientation(TopAbs_INTERNAL);
        //
        bHasImage=myImages.HasImage(aF);
        if (bHasImage) {
          const TopTools_ListOfShape& aLFx=myImages.Image(aF);
          aIt.Initialize(aLFx);
          for (; aIt.More(); aIt.Next()) {
            TopoDS_Face aFx=TopoDS::Face(aIt.Value());
            // update classifier
            IntTools_FClass2d& aClsf=aCtx->FClass2d(aFx);
            aClsf.Init(aFx, aTol);
            //
            iFlag=aCtx->ComputeVS (aV, aFx, aU1, aU2);
            if (!iFlag) {
              aBB.Add(aFx, aV);
              break;
            }
          }
        }
        else {
          const TopoDS_Face& aFx=TopoDS::Face(aF);
          // update classifier
          IntTools_FClass2d& aClsf=aCtx->FClass2d(aFx);
          aClsf.Init(aFx, aTol);
          //
          iFlag=aCtx->ComputeVS (aV, aFx, aU1, aU2);
          if (!iFlag) {
            TopoDS_Face aFz;
            //
            GEOMAlgo_Tools3D::CopyFace(aFx, aFz);
            aBB.Add(aFz, aV);
            myImages.Bind(aF, aFz);
          }
        }
      }// for (; aItV.More(); aItV.Next()) {
    }// if (aNbV) {
  }// for (nF=1; nF<=aNb; ++nF) {
}
bool StdMeshers_RadialPrism_3D::Evaluate(SMESH_Mesh& aMesh,
                                         const TopoDS_Shape& aShape,
                                         MapShapeNbElems& aResMap)
{
  // get 2 shells
  TopoDS_Solid solid = TopoDS::Solid( aShape );
  TopoDS_Shell outerShell = BRepClass3d::OuterShell( solid );
  TopoDS_Shape innerShell;
  int nbShells = 0;
  for ( TopoDS_Iterator It (solid); It.More(); It.Next(), ++nbShells )
    if ( !outerShell.IsSame( It.Value() ))
      innerShell = It.Value();
  if ( nbShells != 2 ) {
    std::vector<int> aResVec(SMDSEntity_Last);
    for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
    aResMap.insert(std::make_pair(sm,aResVec));
    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
    return false;
  }

  // Associate sub-shapes of the shells
  ProjectionUtils::TShapeShapeMap shape2ShapeMap;
  if ( !ProjectionUtils::FindSubShapeAssociation( outerShell, &aMesh,
                                                  innerShell, &aMesh,
                                                  shape2ShapeMap) ) {
    std::vector<int> aResVec(SMDSEntity_Last);
    for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
    aResMap.insert(std::make_pair(sm,aResVec));
    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
    return false;
  }

  // get info for outer shell
  int nb0d_Out=0, nb2d_3_Out=0, nb2d_4_Out=0;
  //TopTools_SequenceOfShape FacesOut;
  for (TopExp_Explorer exp(outerShell, TopAbs_FACE); exp.More(); exp.Next()) {
    //FacesOut.Append(exp.Current());
    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
    MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
    std::vector<int> aVec = (*anIt).second;
    nb0d_Out += aVec[SMDSEntity_Node];
    nb2d_3_Out += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
    nb2d_4_Out += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
  }
  int nb1d_Out = 0;
  TopTools_MapOfShape tmpMap;
  for (TopExp_Explorer exp(outerShell, TopAbs_EDGE); exp.More(); exp.Next()) {
    if( tmpMap.Contains( exp.Current() ) )
      continue;
    tmpMap.Add( exp.Current() );
    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
    MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
    std::vector<int> aVec = (*anIt).second;
    nb0d_Out += aVec[SMDSEntity_Node];
    nb1d_Out += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
  }
  tmpMap.Clear();
  for (TopExp_Explorer exp(outerShell, TopAbs_VERTEX); exp.More(); exp.Next()) {
    if( tmpMap.Contains( exp.Current() ) )
      continue;
    tmpMap.Add( exp.Current() );
    nb0d_Out++;
  }

  // get info for inner shell
  int nb0d_In=0, nb2d_3_In=0, nb2d_4_In=0;
  //TopTools_SequenceOfShape FacesIn;
  for (TopExp_Explorer exp(innerShell, TopAbs_FACE); exp.More(); exp.Next()) {
    //FacesIn.Append(exp.Current());
    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
    MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
    std::vector<int> aVec = (*anIt).second;
    nb0d_In += aVec[SMDSEntity_Node];
    nb2d_3_In += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
    nb2d_4_In += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
  }
  int nb1d_In = 0;
  tmpMap.Clear();
  bool IsQuadratic = false;
  bool IsFirst = true;
  for (TopExp_Explorer exp(innerShell, TopAbs_EDGE); exp.More(); exp.Next()) {
    if( tmpMap.Contains( exp.Current() ) )
      continue;
    tmpMap.Add( exp.Current() );
    SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
    MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
    std::vector<int> aVec = (*anIt).second;
    nb0d_In += aVec[SMDSEntity_Node];
    nb1d_In += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
    if(IsFirst) {
      IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]);
      IsFirst = false;
    }
  }
  tmpMap.Clear();
  for (TopExp_Explorer exp(innerShell, TopAbs_VERTEX); exp.More(); exp.Next()) {
    if( tmpMap.Contains( exp.Current() ) )
      continue;
    tmpMap.Add( exp.Current() );
    nb0d_In++;
  }

  bool IsOK = (nb0d_Out==nb0d_In) && (nb1d_Out==nb1d_In) && 
              (nb2d_3_Out==nb2d_3_In) && (nb2d_4_Out==nb2d_4_In);
  if(!IsOK) {
    std::vector<int> aResVec(SMDSEntity_Last);
    for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
    SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
    aResMap.insert(std::make_pair(sm,aResVec));
    SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
    smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
    return false;
  }

  int nbLayers = 0;
  if( myNbLayerHypo ) {
    nbLayers = myNbLayerHypo->GetNumberOfLayers();
  }
  if ( myDistributionHypo ) {
    if ( !myDistributionHypo->GetLayerDistribution() ) {
      std::vector<int> aResVec(SMDSEntity_Last);
      for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
      SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
      aResMap.insert(std::make_pair(sm,aResVec));
      SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
      smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
      return false;
    }
    TopExp_Explorer exp(outerShell, TopAbs_VERTEX);
    TopoDS_Vertex Vout = TopoDS::Vertex(exp.Current());
    TopoDS_Vertex Vin = TopoDS::Vertex( shape2ShapeMap(Vout) );
    if ( myLayerPositions.empty() ) {
      gp_Pnt pIn = BRep_Tool::Pnt(Vin);
      gp_Pnt pOut = BRep_Tool::Pnt(Vout);
      computeLayerPositions( pIn, pOut );
    }
    nbLayers = myLayerPositions.size() + 1;
  }

  std::vector<int> aResVec(SMDSEntity_Last);
  for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aResVec[i] = 0;
  if(IsQuadratic) {
    aResVec[SMDSEntity_Quad_Penta] = nb2d_3_Out * nbLayers;
    aResVec[SMDSEntity_Quad_Hexa] = nb2d_4_Out * nbLayers;
    int nb1d = ( nb2d_3_Out*3 + nb2d_4_Out*4 ) / 2;
    aResVec[SMDSEntity_Node] = nb0d_Out * ( 2*nbLayers - 1 ) - nb1d * nbLayers;
  }
  else {
    aResVec[SMDSEntity_Node] = nb0d_Out * ( nbLayers - 1 );
    aResVec[SMDSEntity_Penta] = nb2d_3_Out * nbLayers;
    aResVec[SMDSEntity_Hexa] = nb2d_4_Out * nbLayers;
  }
  SMESH_subMesh * sm = aMesh.GetSubMesh(aShape);
  aResMap.insert(std::make_pair(sm,aResVec));

  return true;
}
Exemplo n.º 20
0
//=======================================================================
// function: BuildSplitFaces
// purpose:
//=======================================================================
void GEOMAlgo_Builder::BuildSplitFaces()
{
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  NMTTools_PaveFiller* pPF=myPaveFiller;
  NMTDS_InterfPool* pIP=pPF->IP();
  BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
  const Handle(IntTools_Context)& aCtx= pPF->Context();
  //
  Standard_Boolean bToReverse, bIsClosed, bIsDegenerated;
  Standard_Integer i, aNb, aNbF, nF;
  TopTools_MapOfShape aMFence;
  TColStd_IndexedMapOfInteger aMFP;
  TopExp_Explorer anExp;
  TopoDS_Face aFF;
  TopoDS_Edge aSp, aEE;
  TopTools_ListIteratorOfListOfShape aIt;
  TopAbs_Orientation anOriF, anOriE;
  //
  mySplitFaces.Clear();
  //
  // 1. Select Faces to process (MFP)
  aNb=aDS.NumberOfShapesOfTheObject();
  for (i=1; i<=aNb; ++i) {
    const TopoDS_Shape& aF=aDS.Shape(i);
    if (aF.ShapeType()!=TopAbs_FACE) {
      continue;
    }
    if (!aMFence.Add(aF)) {
      continue;
    }
    //
    if (myInParts.Contains(aF)) {
      aMFP.Add(i);
      continue;
    }
    //
    anExp.Init(aF, TopAbs_EDGE);
    for (; anExp.More(); anExp.Next()) {
      const TopoDS_Shape& aE=anExp.Current();
      if (myImages.HasImage(aE)) {
        aMFP.Add(i);
        break;
      }
    }
    //
    //===
    {
      Standard_Integer aNbFFs, aNbSE, j, n1, n2;
      //
      aNbFFs=aFFs.Extent();
      for (j=1; j<=aNbFFs; ++j) {
        BOPTools_SSInterference& aFFj=aFFs(j);
        aFFj.Indices(n1, n2);
        if (!(n1==i || n2==i)) {
          continue;
        }
        //
        const TColStd_ListOfInteger& aLSE=aFFj.SharedEdges();
        aNbSE=aLSE.Extent();
        if (aNbSE) {
          aMFP.Add(i);
          break;
        }
      }
    }
    //===
    //
  }// for (i=1; i<=aNb; ++i)
  //
  // 2. ProcessFaces
  aNbF=aMFP.Extent();
  for (i=1; i<=aNbF; ++i) {
    nF=aMFP(i);
    const TopoDS_Face& aF=TopoDS::Face(aDS.Shape(nF));
    anOriF=aF.Orientation();
    aFF=aF;
    aFF.Orientation(TopAbs_FORWARD);
    //
    aMFence.Clear();
    //
    // 2.1. Fill WES
    GEOMAlgo_WireEdgeSet aWES;
    aWES.SetFace(aFF);
    //
    //  2.1.1. Add Split parts
    anExp.Init(aFF, TopAbs_EDGE);
    for (; anExp.More(); anExp.Next()) {
      const TopoDS_Edge& aE=TopoDS::Edge(anExp.Current());
      anOriE=aE.Orientation();
      //
      if (!myImages.HasImage(aE)) {
        if (anOriE==TopAbs_INTERNAL) {
          aEE=aE;
          aEE.Orientation(TopAbs_FORWARD);
          aWES.AddStartElement(aEE);
          aEE.Orientation(TopAbs_REVERSED);
          aWES.AddStartElement(aEE);
        }
        else {
          aWES.AddStartElement(aE);
        }
        continue;
      }
      //
      bIsDegenerated=BRep_Tool::Degenerated(aE);
      //modified by NIZNHY-PKV Wed Mar 07 07:46:09 2012f
      bIsClosed=IsClosed(aE, aF);
      //bIsClosed=BRep_Tool::IsClosed(aE, aF);
      //modified by NIZNHY-PKV Wed Mar 07 07:46:13 2012t
      //
      const TopTools_ListOfShape& aLIE=myImages.Image(aE);
      aIt.Initialize(aLIE);
      for (; aIt.More(); aIt.Next()) {
        aSp=TopoDS::Edge(aIt.Value());
        //
        if (bIsDegenerated) {
          aSp.Orientation(anOriE);
          aWES.AddStartElement(aSp);
          continue;
        }
        //
        if (anOriE==TopAbs_INTERNAL) {
          aSp.Orientation(TopAbs_FORWARD);
          aWES.AddStartElement(aSp);
          aSp.Orientation(TopAbs_REVERSED);
          aWES.AddStartElement(aSp);
          continue;
        }
        //
        if (bIsClosed){
          if (aMFence.Add(aSp)) {
            //
            if (!BRep_Tool::IsClosed(aSp, aF)){
              BOPTools_Tools3D::DoSplitSEAMOnFace(aSp, aF);
            }
            //
            aSp.Orientation(TopAbs_FORWARD);
            aWES.AddStartElement(aSp);
            aSp.Orientation(TopAbs_REVERSED);
            aWES.AddStartElement(aSp);
          }
          continue;
        }// if (aMFence.Add(aSp))
        //
        aSp.Orientation(anOriE);
        bToReverse=BOPTools_Tools3D::IsSplitToReverse1(aSp, aE, aCtx);
        if (bToReverse) {
          aSp.Reverse();
        }
        aWES.AddStartElement(aSp);
      }// for (; aIt.More(); aIt.Next()) {
    }// for (; anExp.More(); anExp.Next()) {
    //
    // 2.1.2. Add In2D Parts
    if (myInParts.Contains(aF)) {
      const TopTools_ListOfShape& aLE=myInParts.FindFromKey(aF);
      aIt.Initialize(aLE);
      for (; aIt.More(); aIt.Next()) {
        aSp=TopoDS::Edge(aIt.Value());
        //
        aSp.Orientation(TopAbs_FORWARD);
        aWES.AddStartElement(aSp);
        //
        aSp.Orientation(TopAbs_REVERSED);
        aWES.AddStartElement(aSp);
      }
    }
    //
    // 2.2. Build images Faces
    TopTools_ListOfShape aLFR;
    GEOMAlgo_ShapeSet aS1, aS2;
    //
    const TopTools_ListOfShape& aSE=aWES.StartElements();
    aS1.Add(aSE);
    aS2.Add(aFF, TopAbs_EDGE);
    if (aS1.IsEqual(aS2)) {
      aLFR.Append(aF);
    }
    else {
      GEOMAlgo_BuilderFace aBF;
      //
      aBF.SetFace(aFF);
      aBF.SetContext(aCtx);
      aBF.SetShapes(aSE);
      // <-DEB
      aBF.Perform();
      //
      const TopTools_ListOfShape& aLF=aBF.Areas();
      aIt.Initialize(aLF);
      for (; aIt.More(); aIt.Next()) {
        TopoDS_Shape& aFR=aIt.Value();
        if (anOriF==TopAbs_REVERSED) {
          aFR.Orientation(TopAbs_REVERSED);
        }
        aLFR.Append(aFR);
      }
    }
    //
    // 2.3. Collect draft images Faces
    mySplitFaces.Bind(aF, aLFR);
  }//for (i=1; i<=aNbF; ++i)
}
Exemplo n.º 21
0
//=======================================================================
// function: FillSameDomainFaces
// purpose:
//=======================================================================
void GEOMAlgo_Builder::FillSameDomainFaces()
{
  Standard_Boolean bIsSDF, bHasImage1, bHasImage2, bForward;
  Standard_Integer i, j, aNbFF, nF1, nF2, aNbPBInOn, aNbC, aNbSE;
  Standard_Integer aNbF1, aNbF2, i2s, aNbSD;
  TopTools_MapOfShape aMFence;
  TopTools_ListOfShape aLX1, aLX2;
  TopTools_ListIteratorOfListOfShape aItF1, aItF2;
  NMTTools_ListOfCoupleOfShape aLCS;
  //
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  NMTTools_PaveFiller* pPF=myPaveFiller;
  NMTDS_InterfPool* pIP=pPF->IP();
  BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
  const Handle(IntTools_Context)& aCtx= pPF->Context();
  //
  //
  //mySameDomainShapes.Clear();
  //
  // 1. For each FF find among images of faces
  //    all pairs of same domain faces (SDF) [=> aLCS]
  aNbFF=aFFs.Extent();
  for (i=1; i<=aNbFF; ++i) {
    BOPTools_SSInterference& aFF=aFFs(i);
    aFF.Indices(nF1, nF2);
    //
    const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
    const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2));
    //
    // if there are no in/on 2D split parts the faces nF1, nF2
    // can not be SDF
    const BOPTools_ListOfPaveBlock& aLPBInOn=aFF.PaveBlocks();
    aNbPBInOn=aLPBInOn.Extent();
    //
    //===
    const TColStd_ListOfInteger& aLSE=aFF.SharedEdges();
    aNbSE=aLSE.Extent();
    if (!aNbPBInOn && !aNbSE) {
      continue;
    }
    //===
    //
    // if there is at least one section edge between faces nF1, nF2
    // they can not be SDF
    BOPTools_SequenceOfCurves& aSC=aFF.Curves();
    aNbC=aSC.Length();
    if (aNbC) {
      continue;
    }
    //
    // the faces are suspected to be SDF.
    // Try to find SDF among images of nF1, nF2
    aMFence.Clear();
    //
    //--------------------------------------------------------
    bHasImage1=mySplitFaces.HasImage(aF1);
    bHasImage2=mySplitFaces.HasImage(aF2);
    //
    aLX1.Clear();
    if (!bHasImage1) {
      aLX1.Append(aF1);
    }
    //
    aLX2.Clear();
    if (!bHasImage2) {
      aLX2.Append(aF2);
    }
    //
    const TopTools_ListOfShape& aLF1r=(bHasImage1)? mySplitFaces.Image(aF1) : aLX1;
    const TopTools_ListOfShape& aLF2r=(bHasImage2)? mySplitFaces.Image(aF2) : aLX2;
    //
    TopTools_DataMapOfIntegerShape aMIS;
    TColStd_ListIteratorOfListOfInteger aItLI;
    NMTDS_BoxBndTreeSelector aSelector;
    NMTDS_BoxBndTree aBBTree;
    NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
    //
    aNbF1=aLF1r.Extent();
    aNbF2=aLF2r.Extent();
    bForward=(aNbF1<aNbF2);
    //
    const TopTools_ListOfShape& aLF1=bForward ? aLF1r : aLF2r;
    const TopTools_ListOfShape& aLF2=bForward ? aLF2r : aLF1r;
    //
    // 1. aTreeFiller
    aItF2.Initialize(aLF2);
    for (i2s=1; aItF2.More(); aItF2.Next(), ++i2s) {
      Bnd_Box aBoxF2s;
      //
      const TopoDS_Face& aF2s=*((TopoDS_Face*)(&aItF2.Value()));
      //
      BRepBndLib::Add(aF2s, aBoxF2s);
      //
      aMIS.Bind(i2s, aF2s);
      //
      aTreeFiller.Add(i2s, aBoxF2s);
    }//for (i2s=1; aItF2.More(); aItF2.Next(), ++i2s) {
    //
    aTreeFiller.Fill();
    //
    // 2.
    aItF1.Initialize(aLF1);
    for (j=1; aItF1.More(); aItF1.Next(), ++j) {
      Bnd_Box aBoxF1x;
      //
      const TopoDS_Face& aF1x=*((TopoDS_Face*)(&aItF1.Value()));
      //
      BRepBndLib::Add(aF1x, aBoxF1x);
      //
      aSelector.Clear();
      aSelector.SetBox(aBoxF1x);
      aNbSD=aBBTree.Select(aSelector);
      if (!aNbSD) {
        continue;
      }
      //
      const TColStd_ListOfInteger& aLI=aSelector.Indices();
      aItLI.Initialize(aLI);
      for (; aItLI.More(); aItLI.Next()) {
        i2s=aItLI.Value();
        const TopoDS_Face& aF2y=*((TopoDS_Face*)(&aMIS.Find(i2s)));
        //
        bIsSDF=NMTTools_Tools::AreFacesSameDomain(aF1x, aF2y, aCtx);
        if (bIsSDF) {
          if (aMFence.Contains(aF1x) || aMFence.Contains(aF2y)) {
            continue;
          }
          aMFence.Add(aF1x);
          aMFence.Add(aF2y);
          //
          NMTTools_CoupleOfShape aCS;
          //
          aCS.SetShape1(aF1x);
          aCS.SetShape2(aF2y);
          aLCS.Append(aCS);
          //
          if (bForward) {
            if (aF1x==aF1) {
              if (!mySplitFaces.HasImage(aF1)) {
                mySplitFaces.Bind(aF1, aF1);
              }
            }
            if (aF2y==aF2) {
              if (!mySplitFaces.HasImage(aF2)) {
                mySplitFaces.Bind(aF2, aF2);
              }
            }
          }
          else {
            if (aF1x==aF2) {
              if (!mySplitFaces.HasImage(aF2)) {
                mySplitFaces.Bind(aF2, aF2);
              }
            }
            if (aF2y==aF1) {
              if (!mySplitFaces.HasImage(aF1)) {
                mySplitFaces.Bind(aF1, aF1);
              }
            }
          }
          //
          break;
        }//if (bIsSDF) {
      }//for (; aItLI.More(); aItLI.Next()) {
    }//for (; aItF1.More(); aItF1.Next()) {
  }//for (i=1; i<=aNbFF; ++i)
  //-------------------------------------------------------------
  aNbC=aLCS.Extent();
  if (!aNbC) {
    return;
  }
  //
  // 2. Find Chains
  NMTTools_IndexedDataMapOfShapeIndexedMapOfShape aMC;
  //
  NMTTools_Tools::FindChains(aLCS, aMC);
  //
  Standard_Boolean bIsImage;
  Standard_Integer aIx, aIxMin, aNbMSDF, k, aNbMFj;
  TopoDS_Shape aFOld, aFSDmin;
  TopTools_IndexedMapOfShape aMFj;
  TopTools_DataMapOfShapeInteger aDMSI;
  //
  aItF1.Initialize(myShapes);
  for (j=1; aItF1.More(); aItF1.Next(), ++j) {
    const TopoDS_Shape& aSj=aItF1.Value();
    aMFj.Clear();
    TopExp::MapShapes(aSj, TopAbs_FACE, aMFj);
    aNbMFj=aMFj.Extent();
    for (k=1; k<=aNbMFj; ++k) {
      const TopoDS_Shape& aFk=aMFj(k);
      if (!aDMSI.IsBound(aFk)) {
	aDMSI.Bind(aFk, j);
      }
    }
  }
  //
  // 3. Fill the map of SDF mySameDomainFaces
  aNbC=aMC.Extent();
  for (i=1; i<=aNbC; ++i) {
   // const TopoDS_Shape& aF=aMC.FindKey(i);
    const TopTools_IndexedMapOfShape& aMSDF=aMC(i);
    //
    aNbMSDF=aMSDF.Extent();
    for (j=1; j<=aNbMSDF; ++j) {
      const TopoDS_Shape& aFSD=aMSDF(j);
      bIsImage=mySplitFaces.IsImage(aFSD);
      aFOld=aFSD;
      if (bIsImage) {
	aFOld=mySplitFaces.ImageFrom(aFSD);
      }
      //
      aIx=aDMSI.Find(aFOld);
      if (j==1) {
	aIxMin=aIx;
	aFSDmin=aFSD;
	continue;
      }
      else {
	if (aIx<aIxMin) {
	  aIxMin=aIx;
	  aFSDmin=aFSD;
	}
      }
    }
    //
    for (j=1; j<=aNbMSDF; ++j) {
      const TopoDS_Shape& aFSD=aMSDF(j);
      mySameDomainShapes.Add(aFSD, aFSDmin);
    }
  }
  //
}
Exemplo n.º 22
0
bool NETGENPlugin_NETGEN_3D::Evaluate(SMESH_Mesh& aMesh,
                                      const TopoDS_Shape& aShape,
                                      MapShapeNbElems& aResMap)
{
    int nbtri = 0, nbqua = 0;
    double fullArea = 0.0;
    for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
        TopoDS_Face F = TopoDS::Face( exp.Current() );
        SMESH_subMesh *sm = aMesh.GetSubMesh(F);
        MapShapeNbElemsItr anIt = aResMap.find(sm);
        if( anIt==aResMap.end() ) {
            SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
            smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
            return false;
        }
        std::vector<int> aVec = (*anIt).second;
        nbtri += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
        nbqua += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
        GProp_GProps G;
        BRepGProp::SurfaceProperties(F,G);
        double anArea = G.Mass();
        fullArea += anArea;
    }

    // collect info from edges
    int nb0d_e = 0, nb1d_e = 0;
    bool IsQuadratic = false;
    bool IsFirst = true;
    TopTools_MapOfShape tmpMap;
    for (TopExp_Explorer exp(aShape, TopAbs_EDGE); exp.More(); exp.Next()) {
        TopoDS_Edge E = TopoDS::Edge(exp.Current());
        if( tmpMap.Contains(E) )
            continue;
        tmpMap.Add(E);
        SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
        MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
        if( anIt==aResMap.end() ) {
            SMESH_ComputeErrorPtr& smError = aSubMesh->GetComputeError();
            smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,
                                                  "Submesh can not be evaluated",this));
            return false;
        }
        std::vector<int> aVec = (*anIt).second;
        nb0d_e += aVec[SMDSEntity_Node];
        nb1d_e += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
        if(IsFirst) {
            IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]);
            IsFirst = false;
        }
    }
    tmpMap.Clear();

    double ELen_face = sqrt(2.* ( fullArea/(nbtri+nbqua*2) ) / sqrt(3.0) );
    double ELen_vol = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. );
    double ELen = Min(ELen_vol,ELen_face*2);

    GProp_GProps G;
    BRepGProp::VolumeProperties(aShape,G);
    double aVolume = G.Mass();
    double tetrVol = 0.1179*ELen*ELen*ELen;
    double CoeffQuality = 0.9;
    int nbVols = (int)aVolume/tetrVol/CoeffQuality;
    int nb1d_f = (nbtri*3 + nbqua*4 - nb1d_e) / 2;
    int nb1d_in = (int) ( nbVols*6 - nb1d_e - nb1d_f ) / 5;
    std::vector<int> aVec(SMDSEntity_Last);
    for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i]=0;
    if( IsQuadratic ) {
        aVec[SMDSEntity_Node] = nb1d_in/6 + 1 + nb1d_in;
        aVec[SMDSEntity_Quad_Tetra] = nbVols - nbqua*2;
        aVec[SMDSEntity_Quad_Pyramid] = nbqua;
    }
    else {
        aVec[SMDSEntity_Node] = nb1d_in/6 + 1;
        aVec[SMDSEntity_Tetra] = nbVols - nbqua*2;
        aVec[SMDSEntity_Pyramid] = nbqua;
    }
    SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
    aResMap.insert(std::make_pair(sm,aVec));

    return true;
}
Exemplo n.º 23
0
//=======================================================================
// function: FillIn2DParts
// purpose:
//=======================================================================
void GEOMAlgo_Builder::FillIn2DParts()
{
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  NMTTools_PaveFiller* pPF=myPaveFiller;
  NMTDS_InterfPool* pIP=pPF->IP();
  BOPTools_CArray1OfSSInterference& aFFs=pIP->SSInterferences();
  NMTTools_CommonBlockPool& aCBP=pPF->ChangeCommonBlockPool();
  //
  Standard_Integer  j, nSpIn, nSpSc, aNbCurves;
  Standard_Integer aNbS, nF, aNbCBP, n1, n2, aNbFFs, aNbSpIn;
  TopTools_MapOfShape  aMFence;
  TopTools_ListOfShape aLSpIn;
  TopoDS_Face aF;
  NMTTools_ListIteratorOfListOfCommonBlock aItCB;
  BOPTools_ListIteratorOfListOfPaveBlock aItPB;
  //
  myInParts.Clear();
  //
  aNbFFs=aFFs.Extent();
  aNbCBP=aCBP.Extent();
  //
  aNbS=aDS.NumberOfShapesOfTheObject();
  for (nF=1; nF<=aNbS; ++nF) {
    if (aDS.GetShapeType(nF)!=TopAbs_FACE) {
      continue;
    }
    //
    aF=TopoDS::Face(aDS.Shape(nF));
    //
    aMFence.Clear();
    aLSpIn.Clear();
    //
    // 1. In Parts
    BOPTools_ListOfPaveBlock aLPBIn;
    //
    pPF->RealSplitsInFace(nF, aLPBIn);
    //
    aItPB.Initialize(aLPBIn);
    for (; aItPB.More(); aItPB.Next()) {
      const BOPTools_PaveBlock& aPB1=aItPB.Value();
      nSpIn=aPB1.Edge();
      const TopoDS_Shape& aSpIn=aDS.Shape(nSpIn);
      aLSpIn.Append(aSpIn);
    }
    //
    // 2. Section Parts
    for (j=1; j<=aNbFFs; ++j) {
      BOPTools_SSInterference& aFF=aFFs(j);
      aFF.Indices(n1, n2);
      if (!(n1==nF || n2==nF)) {
        continue;
      }
      BOPTools_SequenceOfCurves& aSC=aFF.Curves();
      aNbCurves=aSC.Length();
      if (!aNbCurves) {
        continue;
      }
      //
      const BOPTools_Curve& aBC=aSC(1);
      const BOPTools_ListOfPaveBlock& aLPB=aBC.NewPaveBlocks();
      aItPB.Initialize(aLPB);
      for (; aItPB.More(); aItPB.Next()) {
        const BOPTools_PaveBlock& aPBSc=aItPB.Value();
        nSpSc=aPBSc.Edge();
        const TopoDS_Shape& aSpSc=aDS.Shape(nSpSc);
        if (aMFence.Add(aSpSc)){
          aLSpIn.Append(aSpSc);
        }
      }
    }
    aNbSpIn=aLSpIn.Extent();
    if (aNbSpIn) {
      myInParts.Add(aF, aLSpIn);
    }
  }//for (nF=1; nF<=aNbS; ++nF) {
}
Exemplo n.º 24
0
//=======================================================================
// function: FillImagesContainers
// purpose:
//=======================================================================
void GEOMAlgo_Builder::FillImagesContainers(const TopAbs_ShapeEnum theType)
{
    myErrorStatus=0;
    //
    Standard_Boolean bInterferred, bToReverse;
    Standard_Integer i, aNbS;
    TopAbs_ShapeEnum aType;
    BRep_Builder aBB;
    TopoDS_Iterator aIt;
    TopTools_ListIteratorOfListOfShape aItIm;
    TopTools_MapOfShape aMS;
    TopTools_MapIteratorOfMapOfShape aItS;
    //
    const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
    NMTTools_PaveFiller* pPF=myPaveFiller;
    const Handle(IntTools_Context)& aCtx= pPF->Context();
    //
    aNbS=aDS.NumberOfShapesOfTheObject();
    for (i=1; i<=aNbS; ++i) {
        const TopoDS_Shape& aC=aDS.Shape(i);
        aType=aC.ShapeType();
        if (aType==theType) {
            aMS.Add(aC);
        }
    }
    //
    if (theType==TopAbs_COMPOUND) {
        FillImagesCompounds(aMS, myImages);
        return;
    }
    //
    aItS.Initialize(aMS);
    for (; aItS.More(); aItS.Next()) {
        const TopoDS_Shape& aC=aItS.Key();
        // whether the shape has image
        bInterferred=Standard_False;
        aIt.Initialize(aC);
        for (; aIt.More(); aIt.Next()) {
            const TopoDS_Shape& aF=aIt.Value();
            if (myImages.HasImage(aF)) {
                bInterferred=!bInterferred;
                break;
            }
        }
        if (!bInterferred) {
            continue;
        }
        //
        TopoDS_Shape aCIm;
        GEOMAlgo_Tools3D::MakeContainer(theType, aCIm);
        //
        aIt.Initialize(aC);
        for (; aIt.More(); aIt.Next()) {
            const TopoDS_Shape& aF=aIt.Value();
            if (myImages.HasImage(aF)) {
                const TopTools_ListOfShape& aLFIm=myImages.Image(aF);
                aItIm.Initialize(aLFIm);
                for (; aItIm.More(); aItIm.Next()) {
                    TopoDS_Shape aFIm=aItIm.Value();
                    //
                    bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aFIm, aF, aCtx);
                    if (bToReverse) {
                        aFIm.Reverse();
                    }
                    aBB.Add(aCIm, aFIm);
                }
            }
            else {
                aBB.Add(aCIm, aF);
            }
        }
        myImages.Bind(aC, aCIm);
    }// for (; aItS.More(); aItS.Next()) {
}
Exemplo n.º 25
0
//=======================================================================
//function : FillIn3DParts
//purpose  :
//=======================================================================
  void GEOMAlgo_Builder::FillIn3DParts()
{
  myErrorStatus=0;
  //
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  NMTTools_PaveFiller* pPF=myPaveFiller;
  const Handle(IntTools_Context)& aCtx= pPF->Context();
  //
  Standard_Boolean bIsIN, bHasImage;
  Standard_Integer aNbS, aNbSolids, i, j, aNbFaces, aNbFP, aNbFPx, aNbFIN, aNbLIF;
  TopAbs_ShapeEnum aType;
  TopAbs_State aState;
  TopTools_IndexedMapOfShape aMSolids, aMS, aMFaces, aMFIN;
  TopTools_MapOfShape aMFDone;
  TopTools_IndexedDataMapOfShapeListOfShape aMEF;
  TopTools_ListIteratorOfListOfShape aItS;
  TopoDS_Iterator aIt, aItF;
  BRep_Builder aBB;
  TopoDS_Solid aSolidSp;
  TopoDS_Face aFP;
  //
  myDraftSolids.Clear();
  //
  aNbS=aDS.NumberOfShapesOfTheObject();
  for (i=1; i<=aNbS; ++i) {
    const TopoDS_Shape& aS=aDS.Shape(i);
    //
    aType=aS.ShapeType();
    if (aType==TopAbs_SOLID) {
      // all solids from DS
      aMSolids.Add(aS);
    }
    else if (aType==TopAbs_FACE) {
      // all faces (originals from DS or theirs images)
      if (myImages.HasImage(aS)) {
        const TopTools_ListOfShape& aLS=myImages.Image(aS);
        aItS.Initialize(aLS);
        for (; aItS.More(); aItS.Next()) {
          const TopoDS_Shape& aFx=aItS.Value();
          //
          if (mySameDomainShapes.Contains(aFx)) {
            const TopoDS_Shape& aFSDx=mySameDomainShapes.FindFromKey(aFx);
            aMFaces.Add(aFSDx);
          }
          else {
            aMFaces.Add(aFx);
          }
        }
      }
      else {
        if (mySameDomainShapes.Contains(aS)) {
          const TopoDS_Shape& aFSDx=mySameDomainShapes.FindFromKey(aS);
          aMFaces.Add(aFSDx);
        }
        else {
          aMFaces.Add(aS);
        }
      }
    }
  }
  //
  aNbFaces=aMFaces.Extent();
  aNbSolids=aMSolids.Extent();
  //
  for (i=1; i<=aNbSolids; ++i) {
    const TopoDS_Solid& aSolid=TopoDS::Solid(aMSolids(i));
    aMFDone.Clear();
    aMFIN.Clear();
    aMEF.Clear();
    //
    aBB.MakeSolid(aSolidSp);
    //
    TopTools_ListOfShape aLIF;
    //
    BuildDraftSolid(aSolid, aSolidSp, aLIF);
    aNbLIF=aLIF.Extent();
    //
    // 1 all faces/edges from aSolid [ aMS ]
    bHasImage=Standard_False;
    aMS.Clear();
    aIt.Initialize(aSolid);
    for (; aIt.More(); aIt.Next()) {
      const TopoDS_Shape& aShell=aIt.Value();
      //
      if (myImages.HasImage(aShell)) {
        bHasImage=Standard_True;
        //
        const TopTools_ListOfShape& aLS=myImages.Image(aShell);
        aItS.Initialize(aLS);
        for (; aItS.More(); aItS.Next()) {
          const TopoDS_Shape& aSx=aItS.Value();
          aMS.Add(aSx);
          TopExp::MapShapes(aSx, TopAbs_FACE, aMS);
          TopExp::MapShapes(aSx, TopAbs_EDGE, aMS);
          TopExp::MapShapesAndAncestors(aSx, TopAbs_EDGE, TopAbs_FACE, aMEF);
        }
      }
      else {
        //aMS.Add(aShell);
        TopExp::MapShapes(aShell, TopAbs_FACE, aMS);
        //modified by NIZNHY-PKV Fri Dec 03 11:18:45 2010f
        TopExp::MapShapes(aShell, TopAbs_EDGE, aMS);
        //modified by NIZNHY-PKV Fri Dec 03 11:18:51 2010t
        TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
      }
    }
    //
    // 2 all faces that are not from aSolid [ aLFP1 ]
    Standard_Integer aNbEFP;
    TopTools_IndexedDataMapOfShapeListOfShape aMEFP;
    TopTools_ListIteratorOfListOfShape aItFP, aItEx;
    TopTools_MapOfShape aMFence;
    TopTools_ListOfShape aLFP1, aLFP2, aLFP, aLCBF, aLFIN, aLEx;//*pLFP,
    //
    // for all non-solid faces build EF map [ aMEFP ]
    for (j=1; j<=aNbFaces; ++j) {
      const TopoDS_Shape& aFace=aMFaces(j);
      if (!aMS.Contains(aFace)) {
        TopExp::MapShapesAndAncestors(aFace, TopAbs_EDGE, TopAbs_FACE, aMEFP);
      }
    }
    //
    // among all faces from aMEFP select these that have same edges
    // with the solid (i.e aMEF). These faces will be treated first
    // to prevent the usage of 3D classifier.
    // The full list of faces to process is aLFP1.
    aNbEFP=aMEFP.Extent();
    for (j=1; j<=aNbEFP; ++j) {
      const TopoDS_Shape& aE=aMEFP.FindKey(j);
      //
      if (aMEF.Contains(aE)) { // !!
        const TopTools_ListOfShape& aLF=aMEFP(j);
        aItFP.Initialize(aLF);
        for (; aItFP.More(); aItFP.Next()) {
          const TopoDS_Shape& aF=aItFP.Value();
          if (aMFence.Add(aF)) {
            aLFP1.Append(aF);
          }
        }
      }
      else {
        aLEx.Append(aE);
      }
    }
    //
    aItEx.Initialize(aLEx);
    for (; aItEx.More(); aItEx.Next()) {
      const TopoDS_Shape& aE=aItEx.Value();
      const TopTools_ListOfShape& aLF=aMEFP.FindFromKey(aE);
      aItFP.Initialize(aLF);
      for (; aItFP.More(); aItFP.Next()) {
        const TopoDS_Shape& aF=aItFP.Value();
        if (aMFence.Add(aF)) {
          aLFP2.Append(aF);
        }
      }
    }
    aLFP1.Append(aLFP2);
    //==========
    //
    // 3 Process faces aLFP1
    aNbFP=aLFP1.Extent();
    aItFP.Initialize(aLFP1);
    for (; aItFP.More(); aItFP.Next()) {
      const TopoDS_Shape& aSP=aItFP.Value();
      if (!aMFDone.Add(aSP)) {
        continue;
      }

      //
      // first face to process
      aFP=TopoDS::Face(aSP);
      bIsIN= GEOMAlgo_Tools3D::IsInternalFace(aFP, aSolidSp, aMEF, 1.e-14, aCtx);
      aState=(bIsIN) ? TopAbs_IN : TopAbs_OUT;
      //
      // collect faces to process [ aFP is the first ]
      aLFP.Clear();
      aLFP.Append(aFP);
      aItS.Initialize(aLFP1);
      for (; aItS.More(); aItS.Next()) {
        const TopoDS_Shape& aSk=aItS.Value();
        if (!aMFDone.Contains(aSk)) {
          aLFP.Append(aSk);
        }
      }
      //
      // Connexity Block that spreads from aFP the Bound
      // or till the end of the block itself
      aLCBF.Clear();
      GEOMAlgo_Tools3D::MakeConnexityBlock(aLFP, aMS, aLCBF);
      //
      // fill states for the Connexity Block
      aItS.Initialize(aLCBF);
      for (; aItS.More(); aItS.Next()) {
        const TopoDS_Shape& aSx=aItS.Value();
        aMFDone.Add(aSx);
        if (aState==TopAbs_IN) {
          aMFIN.Add(aSx);
        }
      }
      //
      aNbFPx=aMFDone.Extent();
      if (aNbFPx==aNbFP) {
        break;
      }
    }//for (; aItFP.More(); aItFP.Next())
    //
    // faces Inside aSolid
    aLFIN.Clear();
    aNbFIN=aMFIN.Extent();
    if (aNbFIN || aNbLIF) {
      for (j=1; j<=aNbFIN; ++j) {
        const TopoDS_Shape& aFIN=aMFIN(j);
        aLFIN.Append(aFIN);
      }
      //
      aItS.Initialize(aLIF);
      for (; aItS.More(); aItS.Next()) {
        const TopoDS_Shape& aFIN=aItS.Value();
        aLFIN.Append(aFIN);
      }
      //
      myInParts.Add(aSolid, aLFIN);
    }
    if (aNbFIN || bHasImage) {
      myDraftSolids.Add(aSolid, aSolidSp);
    }
  }//for (i=1; i<=aNbSolids; ++i) { // next solid
}
Exemplo n.º 26
0
//=======================================================================
// function: FillImagesEdges
// purpose:
//=======================================================================
void GEOMAlgo_Builder::FillImagesEdges()
{
    myErrorStatus=0;
    //
    const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
    NMTTools_PaveFiller* pPF=myPaveFiller;
    const BOPTools_SplitShapesPool& aSSP=pPF->SplitShapesPool();
    const Handle(IntTools_Context)& aCtx=pPF->Context();
    //
    Standard_Boolean bToReverse;
    Standard_Integer i, aNb, aNbSp, nSp, nSpR, nSpx, aIsCB, aNbLB;
    TColStd_ListIteratorOfListOfInteger aItLB;
    TColStd_ListOfInteger aLB;
    TopoDS_Edge aEE, aESpR;
    TopTools_MapOfShape aMFence;
    TopTools_ListOfShape aLSp;
    TopTools_ListIteratorOfListOfShape aIt1;
    BOPTools_ListIteratorOfListOfPaveBlock aIt;
    //
    aNb=aDS.NumberOfShapesOfTheObject();
    for (i=1; i<=aNb; ++i) {
        const TopoDS_Shape& aE=aDS.Shape(i);
        if (aE.ShapeType()!=TopAbs_EDGE) {
            continue;
        }
        //
        if (!aMFence.Add(aE)) {
            continue;
        }
        //
        const BOPTools_ListOfPaveBlock& aLPB=aSSP(aDS.RefEdge(i));
        aNbSp=aLPB.Extent();
        if (!aNbSp) {
            continue;
        }
        //
        aEE=TopoDS::Edge(aE);
        aLSp.Clear();
        //
        if (aNbSp==1) {
            const BOPTools_PaveBlock& aPB=aLPB.First();
            nSp=aPB.Edge();
            const TopoDS_Shape& aSp=aDS.Shape(nSp);
            //
            const BOPTools_PaveBlock& aPBR=pPF->RealPaveBlock(aPB, aLB, aIsCB);
            //modified by NIZNHY-PKV Wed Oct 27 11:19:30 2010f
            aNbLB=aLB.Extent();
            if (aIsCB && aNbLB<2) {
                aIsCB=0;
            }
            //modified by NIZNHY-PKV Wed Oct 27 11:19:34 2010t
            //
            nSpR=aPBR.Edge();
            const TopoDS_Shape& aSpR=aDS.Shape(nSpR);
            if (aSpR.IsSame(aSp) && aSpR.IsSame(aE) && !aIsCB) {
                continue;
            }
            //
            aESpR=TopoDS::Edge(aSpR);
            bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aESpR, aEE, aCtx);
            if (bToReverse) {
                aESpR.Reverse();
            }
            aLSp.Append(aESpR);
            //
            aItLB.Initialize(aLB);
            for (; aItLB.More(); aItLB.Next()) {
                nSpx=aItLB.Value();
                const TopoDS_Shape& aSpx=aDS.Shape(nSpx);
                mySameDomainShapes.Add(aSpx ,aSpR);
            }
            //
            //
        }// if (aNbSp==1) {
        else {
            aIt.Initialize(aLPB);
            for (; aIt.More(); aIt.Next()) {
                const BOPTools_PaveBlock& aPB=aIt.Value();
                const BOPTools_PaveBlock& aPBR=pPF->RealPaveBlock(aPB, aLB, aIsCB);
                nSpR=aPBR.Edge();
                const TopoDS_Shape& aSpR=aDS.Shape(nSpR);
                //
                aESpR=TopoDS::Edge(aSpR);
                bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aESpR, aEE, aCtx);
                if (bToReverse) {
                    aESpR.Reverse();
                }
                aLSp.Append(aESpR);
                //
                aItLB.Initialize(aLB);
                for (; aItLB.More(); aItLB.Next()) {
                    nSpx=aItLB.Value();
                    const TopoDS_Shape& aSpx=aDS.Shape(nSpx);
                    mySameDomainShapes.Add(aSpx ,aSpR);
                }
            }
        }
        //
        myImages.Bind(aE, aLSp);

    }//for (i=1; i<=aNb; ++i)
}
Exemplo n.º 27
0
//=======================================================================
//function : BuildSplitSolids
//purpose  :
//=======================================================================
  void GEOMAlgo_Builder::BuildSplitSolids()
{
  myErrorStatus=0;
  //
  const NMTDS_ShapesDataStructure& aDS=*myPaveFiller->DS();
  NMTTools_PaveFiller* pPF=myPaveFiller;
  const Handle(IntTools_Context)& aCtx= pPF->Context();
  //
  Standard_Integer i, aNbS, iErr;
  TopExp_Explorer aExp;
  TopTools_ListOfShape aSFS, aLSEmpty;
  TopTools_MapOfShape aMFence;
  TopTools_ListIteratorOfListOfShape aIt;
  GEOMAlgo_BuilderSolid aSB;
  GEOMAlgo_DataMapIteratorOfDataMapOfShapeShapeSet aItSS;
  GEOMAlgo_DataMapOfShapeShapeSet aMSS;
  GEOMAlgo_ShapeSet aSSi;
  //
  // 0. Find same domain solids for non-interferred solids
  aNbS=aDS.NumberOfShapesOfTheObject();
  for (i=1; i<=aNbS; ++i) {
    const TopoDS_Shape& aS=aDS.Shape(i);
    if (aS.ShapeType()!=TopAbs_SOLID) {
      continue;
    }
    if (!aMFence.Add(aS)) {
      continue;
    }
    if(myDraftSolids.Contains(aS)) {
      continue;
    }
    //
    aSSi.Clear();
    aSSi.Add(aS, TopAbs_FACE);
    //
    aMSS.Bind(aS, aSSi);
  } //for (i=1; i<=aNbS; ++i)
  //
  // 1. Build solids for interferred source solids
  aSB.SetContext(aCtx);
  aSB.ComputeInternalShapes(myComputeInternalShapes);
  aNbS=myDraftSolids.Extent();
  for (i=1; i<=aNbS; ++i) {
    const TopoDS_Shape& aS =myDraftSolids.FindKey(i);
    const TopoDS_Shape& aSD=myDraftSolids.FindFromIndex(i);
    const TopTools_ListOfShape& aLFIN=
      (myInParts.Contains(aS)) ? myInParts.FindFromKey(aS) : aLSEmpty;
    //
    // 1.1 Fill Shell Faces Set
    aSFS.Clear();

    aExp.Init(aSD, TopAbs_FACE);
    for (; aExp.More(); aExp.Next()) {
      const TopoDS_Shape& aF=aExp.Current();
      aSFS.Append(aF);
    }
    //
    aIt.Initialize(aLFIN);
    for (; aIt.More(); aIt.Next()) {
      TopoDS_Shape aF=aIt.Value();
      //
      aF.Orientation(TopAbs_FORWARD);
      aSFS.Append(aF);
      aF.Orientation(TopAbs_REVERSED);
      aSFS.Append(aF);
    }
    //
    Standard_Integer aNbSFS;
    aNbSFS=aSFS.Extent();
    //
    // 1.2
    // Check whether aSFS contains a subsets of faces
    // of solids that have been already built.
    // If yes, shrink aSFS by these subsets.
    aSSi.Clear();
    aSSi.Add(aSFS);
    //
    aItSS.Initialize(aMSS);
    for (; aItSS.More(); aItSS.Next()) {
      const TopoDS_Shape& aSR=aItSS.Key();
      const GEOMAlgo_ShapeSet& aSSR=aItSS.Value();
      if (aSSi.Contains(aSSR)) {
        // the aSR is SD solid for aS
        aSSi.Subtract(aSSR);
        // update images
        if(myImages.HasImage(aS)) {
          myImages.Add(aS, aSR);
        }
        else {
          myImages.Bind(aS, aSR);
        }
        //
        // update SD Shapes
        mySameDomainShapes.Add(aSR, aSR);
      }
    }
    const TopTools_ListOfShape& aSFS1=aSSi.GetSet();
    aNbSFS=aSFS1.Extent();
    //modified by NIZNHY-PKV Wed Oct 27 09:53:15 2010f
    if (!aNbSFS) {
      continue;
    }
    //modified by NIZNHY-PKV Wed Oct 27 09:53:18 2010t
    //
    // 1.3 Build new solids
    aSB.SetContext(aCtx);
    aSB.SetShapes(aSFS1);
    aSB.Perform();
    iErr=aSB.ErrorStatus();
    if (iErr) {
      myErrorStatus=30; // SolidBuilder failed
      return;
    }
    //
    const TopTools_ListOfShape& aLSR=aSB.Areas();
    //
      // 1.4 Collect resulting solids and theirs set of faces
    aIt.Initialize(aLSR);
    for (; aIt.More(); aIt.Next()) {
      const TopoDS_Shape& aSR=aIt.Value();
      //
      aSSi.Clear();
      aExp.Init(aSR, TopAbs_FACE);
      for (; aExp.More(); aExp.Next()) {
        const TopoDS_Shape& aF=aExp.Current();
        aSSi.Add(aF);
      }
      aMSS.Bind(aSR, aSSi);
    }
    //
    // Update images
    if (myImages.HasImage(aS)) {
      myImages.Add(aS, aLSR);
    }
    else {
      myImages.Bind(aS, aLSR);
    }
  } // for (i=1; i<=aNbS; ++i) {
}
//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_ChamferDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IChamfer aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;

  Handle(GEOM_Function) aRefShape = aCI.GetShape();
  TopoDS_Shape aShapeBase = aRefShape->GetValue();

  // Check the shape type. It have to be shell
  // or solid, or compsolid, or compound of these shapes.
  if (!isGoodForChamfer(aShapeBase)) {
    StdFail_NotDone::Raise
      ("Wrong shape. Must be shell or solid, or compsolid or compound of these shapes");
  }

  BRepFilletAPI_MakeChamfer fill (aShapeBase);

  if (aType == CHAMFER_SHAPE_ALL) {
    // symmetric chamfer on all edges
    double aD = aCI.GetD();
    TopTools_IndexedDataMapOfShapeListOfShape M;
    GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
    for (int i = 1; i <= M.Extent(); i++) {
      TopoDS_Edge E = TopoDS::Edge(M.FindKey(i));
      TopoDS_Face F = TopoDS::Face(M.FindFromIndex(i).First());
      if (!BRepTools::IsReallyClosed(E, F) &&
          !BRep_Tool::Degenerated(E) &&
          M.FindFromIndex(i).Extent() == 2)
        fill.Add(aD, E, F);
    }
  }
  else if (aType == CHAMFER_SHAPE_EDGE || aType == CHAMFER_SHAPE_EDGE_AD) {
    // chamfer on edges, common to two faces, with D1 on the first face

    TopoDS_Shape aFace1, aFace2;
    if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace1(), aFace1) &&
        GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace2(), aFace2))
    {
      TopoDS_Face F = TopoDS::Face(aFace1);

      // fill map of edges of the second face
      TopTools_MapOfShape aMap;
      TopExp_Explorer Exp2 (aFace2, TopAbs_EDGE);
      for (; Exp2.More(); Exp2.Next()) {
        aMap.Add(Exp2.Current());
      }

      // find edges of the first face, common with the second face
      TopExp_Explorer Exp (aFace1, TopAbs_EDGE);
      for (; Exp.More(); Exp.Next()) {
        if (aMap.Contains(Exp.Current())) {
          TopoDS_Edge E = TopoDS::Edge(Exp.Current());
          if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E))
          {
            if ( aType == CHAMFER_SHAPE_EDGE )
            {
              double aD1 = aCI.GetD1();
              double aD2 = aCI.GetD2();
              fill.Add(aD1, aD2, E, F);
            }
            else
            {
              double aD = aCI.GetD();
              double anAngle = aCI.GetAngle();
              if ( (anAngle > 0) && (anAngle < (M_PI/2.)) )
                fill.AddDA(aD, anAngle, E, F);
            }
          }
        }
      }
    }
  }
  else if (aType == CHAMFER_SHAPE_FACES || aType == CHAMFER_SHAPE_FACES_AD) {
    // chamfer on all edges of the selected faces, with D1 on the selected face
    // (on first selected face, if the edge belongs to two selected faces)

    int aLen = aCI.GetLength();
    int ind = 1;
    TopTools_MapOfShape aMap;
    TopTools_IndexedDataMapOfShapeListOfShape M;
    GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
    for (; ind <= aLen; ind++)
    {
      TopoDS_Shape aShapeFace;
      if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace(ind), aShapeFace))
      {
        TopoDS_Face F = TopoDS::Face(aShapeFace);
        TopExp_Explorer Exp (F, TopAbs_EDGE);
        for (; Exp.More(); Exp.Next()) {
          if (!aMap.Contains(Exp.Current()))
          {
            TopoDS_Edge E = TopoDS::Edge(Exp.Current());
            if (!BRepTools::IsReallyClosed(E, F) &&
                !BRep_Tool::Degenerated(E) &&
                M.FindFromKey(E).Extent() == 2)
            {
              if (aType == CHAMFER_SHAPE_FACES)
              {
                double aD1 = aCI.GetD1();
                double aD2 = aCI.GetD2();
                fill.Add(aD1, aD2, E, F);
              }
              else
              {
                double aD = aCI.GetD();
                double anAngle = aCI.GetAngle();
                if ( (anAngle > 0) && (anAngle < (M_PI/2.)) )
                  fill.AddDA(aD, anAngle, E, F);
              }
            }
          }
        }
      }
    }
  }
  else if (aType == CHAMFER_SHAPE_EDGES || aType == CHAMFER_SHAPE_EDGES_AD)
  {
    // chamfer on selected edges with lenght param D1 & D2.

    int aLen = aCI.GetLength();
    int ind = 1;
    TopTools_MapOfShape aMap;
    TopTools_IndexedDataMapOfShapeListOfShape M;
    GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M);
    for (; ind <= aLen; ind++)
    {
      TopoDS_Shape aShapeEdge;
      if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetEdge(ind), aShapeEdge))
      {
        TopoDS_Edge E = TopoDS::Edge(aShapeEdge);
        const TopTools_ListOfShape& aFacesList = M.FindFromKey(E);
        TopoDS_Face F = TopoDS::Face( aFacesList.First() );
        if (aType == CHAMFER_SHAPE_EDGES)
        {
          double aD1 = aCI.GetD1();
          double aD2 = aCI.GetD2();
          fill.Add(aD1, aD2, E, F);
        }
        else
        {
          double aD = aCI.GetD();
          double anAngle = aCI.GetAngle();
          if ( (anAngle > 0) && (anAngle < (M_PI/2.)) )
            fill.AddDA(aD, anAngle, E, F);
        }
      }
    }
  }
  else {
  }

  fill.Build();
  if (!fill.IsDone()) {
    StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters");
  }
  aShape = fill.Shape();

  if (aShape.IsNull()) return 0;

  // reduce tolerances
  ShapeFix_ShapeTolerance aSFT;
  aSFT.LimitTolerance(aShape, Precision::Confusion(),
                      Precision::Confusion(), TopAbs_SHAPE);
  Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape);
  aSfs->Perform();
  aShape = aSfs->Shape();

  // fix SameParameter flag
  BRepLib::SameParameter(aShape, 1.E-5, Standard_True);

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}
Exemplo n.º 29
0
bool NETGENPlugin_NETGEN_2D_ONLY::Evaluate(SMESH_Mesh& aMesh,
        const TopoDS_Shape& aShape,
        MapShapeNbElems& aResMap)
{
    TopoDS_Face F = TopoDS::Face(aShape);
    if(F.IsNull())
        return false;

    // collect info from edges
    int nb0d = 0, nb1d = 0;
    bool IsQuadratic = false;
    bool IsFirst = true;
    double fullLen = 0.0;
    TopTools_MapOfShape tmpMap;
    for (TopExp_Explorer exp(F, TopAbs_EDGE); exp.More(); exp.Next()) {
        TopoDS_Edge E = TopoDS::Edge(exp.Current());
        if( tmpMap.Contains(E) )
            continue;
        tmpMap.Add(E);
        SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
        MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
        if( anIt==aResMap.end() ) {
            SMESH_subMesh *sm = aMesh.GetSubMesh(F);
            SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
            smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this));
            return false;
        }
        std::vector<int> aVec = (*anIt).second;
        nb0d += aVec[SMDSEntity_Node];
        nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
        double aLen = SMESH_Algo::EdgeLength(E);
        fullLen += aLen;
        if(IsFirst) {
            IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]);
            IsFirst = false;
        }
    }
    tmpMap.Clear();

    // compute edge length
    double ELen = 0;
    if (_hypLengthFromEdges || (!_hypLengthFromEdges && !_hypMaxElementArea)) {
        if ( nb1d > 0 )
            ELen = fullLen / nb1d;
    }
    if ( _hypMaxElementArea ) {
        double maxArea = _hypMaxElementArea->GetMaxArea();
        ELen = sqrt(2. * maxArea/sqrt(3.0));
    }
    GProp_GProps G;
    BRepGProp::SurfaceProperties(F,G);
    double anArea = G.Mass();

    const int hugeNb = numeric_limits<int>::max()/10;
    if ( anArea / hugeNb > ELen*ELen )
    {
        SMESH_subMesh *sm = aMesh.GetSubMesh(F);
        SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
        smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated.\nToo small element length",this));
        return false;
    }
    int nbFaces = (int) ( anArea / ( ELen*ELen*sqrt(3.) / 4 ) );
    int nbNodes = (int) ( ( nbFaces*3 - (nb1d-1)*2 ) / 6 + 1 );
    std::vector<int> aVec(SMDSEntity_Last);
    for(int i=SMDSEntity_Node; i<SMDSEntity_Last; i++) aVec[i]=0;
    if( IsQuadratic ) {
        aVec[SMDSEntity_Node] = nbNodes;
        aVec[SMDSEntity_Quad_Triangle] = nbFaces;
    }
    else {
        aVec[SMDSEntity_Node] = nbNodes;
        aVec[SMDSEntity_Triangle] = nbFaces;
    }
    SMESH_subMesh *sm = aMesh.GetSubMesh(F);
    aResMap.insert(std::make_pair(sm,aVec));

    return true;
}
Exemplo n.º 30
0
//=======================================================================
//function : GetEdgeNearPoint
//purpose  :
//=======================================================================
TopoDS_Shape GEOMUtils::GetEdgeNearPoint (const TopoDS_Shape& theShape,
                                          const TopoDS_Vertex& thePoint)
{
  TopoDS_Shape aResult;

  // 1. Explode the shape on edges
  TopTools_MapOfShape mapShape;
  Standard_Integer nbEdges = 0;
  TopExp_Explorer exp (theShape, TopAbs_EDGE);
  for (; exp.More(); exp.Next()) {
    if (mapShape.Add(exp.Current())) {
      nbEdges++;
    }
  }

  if (nbEdges == 0)
    Standard_NullObject::Raise("Given shape contains no edges");

  mapShape.Clear();
  Standard_Integer ind = 1;
  TopTools_Array1OfShape anEdges (1, nbEdges);
  TColStd_Array1OfReal aDistances (1, nbEdges);
  for (exp.Init(theShape, TopAbs_EDGE); exp.More(); exp.Next()) {
    if (mapShape.Add(exp.Current())) {
      TopoDS_Shape anEdge = exp.Current();
      anEdges(ind) = anEdge;

      // 2. Classify the point relatively each edge
      BRepExtrema_DistShapeShape aDistTool (thePoint, anEdges(ind));
      if (!aDistTool.IsDone())
        Standard_ConstructionError::Raise("Cannot find a distance from the given point to one of edges");

      aDistances(ind) = aDistTool.Value();
      ind++;
    }
  }

  // 3. Define edge, having minimum distance to the point
  Standard_Real nearest = RealLast(), nbFound = 0;
  Standard_Real prec = Precision::Confusion();
  for (ind = 1; ind <= nbEdges; ind++) {
    if (Abs(aDistances(ind) - nearest) < prec) {
      nbFound++;
    }
    else if (aDistances(ind) < nearest) {
      nearest = aDistances(ind);
      aResult = anEdges(ind);
      nbFound = 1;
    }
    else {
    }
  }
  if (nbFound > 1) {
    Standard_ConstructionError::Raise("Multiple edges near the given point are found");
  }
  else if (nbFound == 0) {
    Standard_ConstructionError::Raise("There are no edges near the given point");
  }
  else {
  }

  return aResult;
}