Example #1
0
void OCCRegion::replaceFacesInternal(std::list<GFace*> &new_faces)
{
  // we simply replace old faces by new faces in the structure
  TopExp_Explorer aExpS, aExpF;
  BRep_Builder aBB;
  TopoDS_Compound aCmp;
  aBB.MakeCompound(aCmp);
  TopoDS_Solid _s_replacement;
  aBB.MakeSolid(_s_replacement);
  _s_replacement.Orientation(s.Orientation());
  aExpS.Init(s, TopAbs_SHELL);
  for (; aExpS.More(); aExpS.Next()) {
    const TopoDS_Shell& _shell=TopoDS::Shell(aExpS.Current());
    TopoDS_Shell _shell_replacement;
    aBB.MakeShell(_shell_replacement);
    _shell_replacement.Orientation(_shell.Orientation());
    aExpF.Init(_shell, TopAbs_FACE);
    for (; aExpF.More(); aExpF.Next()) {
      const TopoDS_Face& _face=TopoDS::Face(aExpF.Current());
      TopoDS_Face _face_replacement;

      std::list<GFace*>::iterator it  = l_faces.begin();
      std::list<GFace*>::iterator it2 = new_faces.begin();

      for ( ; it != l_faces.end() ; ++it,++it2){
	OCCFace *occF = dynamic_cast<OCCFace*>(*it);
	if (occF){
	  TopoDS_Face oldf = occF->getTopoDS_Face();
	  if (oldf.IsSame(_face)){
	    _face_replacement = *((TopoDS_Face*)(*it2)->getNativePtr());
	  }
	  else {
	    oldf = occF->getTopoDS_FaceOld();
	    if (oldf.IsSame(_face)){
	      _face_replacement = *((TopoDS_Face*)(*it2)->getNativePtr());
	    }
	  }
	}
      }
      if (_face_replacement.IsNull()){
	Msg::Error("cannot find an face for gluing a region");
      }

      if (_face_replacement.IsSame(_face)) {
	aBB.Add(_shell_replacement, _face);
      }
      else {
	if(FaceHaveDifferentOrientations(_face, _face_replacement))
          _face_replacement.Reverse();
	aBB.Add(_shell_replacement, _face_replacement);
      }
    }
    aBB.Add(_s_replacement, _shell_replacement);
  }
  s = _s_replacement;
  setup();
}
Example #2
0
//=======================================================================
// function: MakeContainer
// purpose: 
//=======================================================================
  void GEOMAlgo_Tools3D::MakeContainer(const TopAbs_ShapeEnum theType,
                                      TopoDS_Shape& theC)
{
  BRep_Builder aBB;
  //
  switch(theType) {
    case TopAbs_COMPOUND:{
      TopoDS_Compound aC;
      aBB.MakeCompound(aC);
      theC=aC;
    }
      break;
      //
    case TopAbs_COMPSOLID:{
      TopoDS_CompSolid aCS;
      aBB.MakeCompSolid(aCS);
      theC=aCS;
    }
      break;
      //
    case TopAbs_SOLID:{
      TopoDS_Solid aSolid;
      aBB.MakeSolid(aSolid);
      theC=aSolid;
    }  
      break;
      //
      //
    case TopAbs_SHELL:{
      TopoDS_Shell aShell;
      aBB.MakeShell(aShell);
      theC=aShell;
    }  
      break;
      //
    case TopAbs_WIRE: {
      TopoDS_Wire aWire;
      aBB.MakeWire(aWire);
      theC=aWire;
    }
      break;
      //
    default:
      break;
  }
}
// constructor method
int TopoShapeShellPy::PyInit(PyObject* args, PyObject* /*kwd*/)
{
    PyObject *obj;
    if (!PyArg_ParseTuple(args, "O", &obj))
        return -1;

    BRep_Builder builder;
    TopoDS_Shape shape;
    TopoDS_Shell shell;
    //BRepOffsetAPI_Sewing mkShell;
    builder.MakeShell(shell);
    
    try {
        Py::Sequence list(obj);
        for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
            if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapeFacePy::Type))) {
                const TopoDS_Shape& sh = static_cast<TopoShapeFacePy*>((*it).ptr())->
                    getTopoShapePtr()->_Shape;
                if (!sh.IsNull())
                    builder.Add(shell, sh);
            }
        }

        shape = shell;
        BRepCheck_Analyzer check(shell);
        if (!check.IsValid()) {
            ShapeUpgrade_ShellSewing sewShell;
            shape = sewShell.ApplySewing(shell);
        }

        if (shape.IsNull())
            Standard_Failure::Raise("Shape is null");

        if (shape.ShapeType() != TopAbs_SHELL)
            Standard_Failure::Raise("Shape is not a shell");
    }
    catch (Standard_Failure) {
        Handle_Standard_Failure e = Standard_Failure::Caught();
        PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
        return -1;
    }

    getTopoShapePtr()->_Shape = shape;
    return 0;
}
Example #4
0
Standard_Boolean ShHealOper_Sewing::getShells(const TopoDS_Shape& theSewShape) const
{
  Standard_Boolean isDone = Standard_False;
  TopoDS_Shape aTmpShape = theSewShape;
  if(myNonManifoldMode) {
    TopoDS_Shell tempShell;
    BRep_Builder aB;
    aB.MakeShell(tempShell);
    
    for(TopExp_Explorer aExpf(theSewShape,TopAbs_FACE);aExpf.More(); aExpf.Next()) 
      aB.Add(tempShell,aExpf.Current());
    aTmpShape = tempShell;
    myContext->Replace(theSewShape,aTmpShape);
  }
  
  Handle(ShapeFix_Shell) asfs = new ShapeFix_Shell;
  asfs->SetContext(myContext);
  TopExp_Explorer aexpShell(aTmpShape,TopAbs_SHELL);
  for ( ; aexpShell.More(); aexpShell.Next()) 
    isDone = (asfs->FixFaceOrientation(TopoDS::Shell(aexpShell.Current()),
                                       Standard_True,myNonManifoldMode) || isDone);
  
  return isDone;
}
Example #5
0
////////////////////////////////////////////////////////////////////////////////
// Construct TopoDS from BRL-CAD data
////////////////////////////////////////////////////////////////////////////////
BRLTopo::BRLTopo(struct rt_arb_internal *arb)
{
    TopoDS_Vertex v[8];
    for(int i=0;i<8;i++)
        v[i]=BRepBuilderAPI_MakeVertex(
            gp_Pnt(
                scale*arb->pt[i][0],
                scale*arb->pt[i][1],
                scale*arb->pt[i][2]
            )
        );

    int arbn;
    if(!BRepTools::Compare(v[6],v[7]))
        arbn=8;
    else if(!BRepTools::Compare(v[4],v[5]))
        arbn=7;
    else if(!BRepTools::Compare(v[5],v[6]))
        arbn=6;
    else if(!BRepTools::Compare(v[0],v[3]))
        arbn=5;
    else
        arbn=4;

    switch(arbn) {
    case 8: {
        TopoDS_Edge e[12];
        for(int i=0;i<4;i++) { 
            e[i]=BRepBuilderAPI_MakeEdge(v[i],v[(i+1)%4]);
            e[i+4]=BRepBuilderAPI_MakeEdge(v[i+4],v[(i+1)%4+4]);
            e[i+8]=BRepBuilderAPI_MakeEdge(v[i],v[(i+4)%8]);
        }

        TopoDS_Wire w[6];
        w[0]=BRepBuilderAPI_MakeWire(e[0],e[1],e[2],e[3]);
        w[1]=BRepBuilderAPI_MakeWire(e[4],e[5],e[6],e[7]);
        w[2]=BRepBuilderAPI_MakeWire(e[0],e[9],e[4],e[8]);
        w[3]=BRepBuilderAPI_MakeWire(e[1],e[10],e[5],e[9]);
        w[4]=BRepBuilderAPI_MakeWire(e[2],e[11],e[6],e[10]);
        w[5]=BRepBuilderAPI_MakeWire(e[3],e[8],e[7],e[11]);

        BRep_Builder BB;
        TopoDS_Shell shell;
        BB.MakeShell(shell);
        for(int i=0;i<6;i++) {
            TopoDS_Face f=BRepBuilderAPI_MakeFace(w[i]);
            BB.Add(shell,i? f.Reversed():f);
        }
        TopoDS_Solid solid;
        BB.MakeSolid(solid);
        BB.Add(solid,shell);
        ShapeFix_Solid sf(solid);
        sf.Perform();
        shape=sf.Solid();
        } break;
    case 6: {
        TopoDS_Edge e[9];
        e[0]=BRepBuilderAPI_MakeEdge(v[0],v[1]);
        e[1]=BRepBuilderAPI_MakeEdge(v[1],v[2]);
        e[2]=BRepBuilderAPI_MakeEdge(v[2],v[3]);
        e[3]=BRepBuilderAPI_MakeEdge(v[3],v[0]);
        e[4]=BRepBuilderAPI_MakeEdge(v[0],v[4]);
        e[5]=BRepBuilderAPI_MakeEdge(v[1],v[4]);
        e[6]=BRepBuilderAPI_MakeEdge(v[2],v[6]);
        e[7]=BRepBuilderAPI_MakeEdge(v[3],v[6]);
        e[8]=BRepBuilderAPI_MakeEdge(v[4],v[6]);

        TopoDS_Wire w[5];
        w[0]=BRepBuilderAPI_MakeWire(e[0],e[1],e[2],e[3]);
        w[1]=BRepBuilderAPI_MakeWire(e[0],e[4],e[5]);
        w[2]=BRepBuilderAPI_MakeWire(e[2],e[6],e[7]);
        w[3]=BRepBuilderAPI_MakeWire(e[3],e[4],e[8],e[7]);
        w[4]=BRepBuilderAPI_MakeWire(e[1],e[5],e[8],e[6]);

        BRep_Builder BB;
#if 0
        TopoDS_Compound result;
        BB.MakeCompound(result);
        for(int i=0;i<5;i++) {
            BB.Add(result,BRepBuilderAPI_MakeFace(w[i]));
        }
        shape=result;
#else
        TopoDS_Shell shell;
        BB.MakeShell(shell);
        for(int i=0;i<5;i++) {
            TopoDS_Face f=BRepBuilderAPI_MakeFace(w[i]);
            BB.Add(shell,f); //i? f:f.Reversed());
        }
        TopoDS_Solid solid;
        BB.MakeSolid(solid);
        BB.Add(solid,shell);
        ShapeFix_Solid sf(solid);
        sf.Perform();
        shape=sf.Solid();
#endif
        } break;
    default:
        cerr << "Unhandled arb8 type n=" << arbn << '\n';
    }
}
Example #6
0
BRLTopo::BRLTopo(struct rt_ell_internal *ell)
{
#if 0
    gp_Pnt v(ell->v[0], ell->v[1], ell->v[2]);
    gp_Pnt a(v.Coord(1)+ell->a[0], v.Coord(2)+ell->a[1], v.Coord(3)+ell->a[2]);
    gp_Pnt b(v.Coord(1)+ell->b[0], v.Coord(2)+ell->b[1], v.Coord(3)+ell->b[2]);
    gp_Pnt c(v.Coord(1)+ell->c[0], v.Coord(2)+ell->c[1], v.Coord(3)+ell->c[2]);
    gp_Pnt aa(v.Coord(1)-ell->a[0], v.Coord(2)-ell->a[1], v.Coord(3)-ell->a[2]);
    gp_Pnt bb(v.Coord(1)-ell->b[0], v.Coord(2)-ell->b[1], v.Coord(3)-ell->b[2]);
    gp_Pnt cc(v.Coord(1)-ell->c[0], v.Coord(2)-ell->c[1], v.Coord(3)-ell->c[2]);

    Handle(Geom_Ellipse) sect1=GC_MakeEllipse(a, b, v); 
    Handle(Geom_Ellipse) sect2=GC_MakeEllipse(a, c, v); 
    Handle(Geom_Ellipse) sect3=GC_MakeEllipse(b, c, v); 

    TopoDS_Edge e_ab[4];
    e_ab[0]=BRepBuilderAPI_MakeEdge(sect1,a,b);
    e_ab[1]=BRepBuilderAPI_MakeEdge(sect1,b,aa);
    e_ab[2]=BRepBuilderAPI_MakeEdge(sect1,aa,bb);
    e_ab[3]=BRepBuilderAPI_MakeEdge(sect1,bb,a);

    TopoDS_Edge e_ac[4];
    e_ac[0]=BRepBuilderAPI_MakeEdge(sect2,c,aa);
    e_ac[1]=BRepBuilderAPI_MakeEdge(sect2,a,c);
    e_ac[2]=BRepBuilderAPI_MakeEdge(sect2,aa,cc);
    e_ac[3]=BRepBuilderAPI_MakeEdge(sect2,cc,a); 

    TopoDS_Edge e_bc[4];
    e_bc[0]=BRepBuilderAPI_MakeEdge(sect3,b,c);
    e_bc[1]=BRepBuilderAPI_MakeEdge(sect3,c,bb);
    e_bc[2]=BRepBuilderAPI_MakeEdge(sect3,bb,cc);
    e_bc[3]=BRepBuilderAPI_MakeEdge(sect3,cc,b); 

    // FIXME, BRepFill_Filling?
    TopoDS_Solid sph=BRepPrimAPI_MakeSphere(v,ell->a[0]);
    TopoDS_Face init;
    for(TopExp_Explorer p(sph,TopAbs_FACE); p.More(); p.Next())
        init=TopoDS::Face(p.Current());
    BRepFill_Filling face1;
    //face1.LoadInitSurface(init);
    face1.Add(e_ab[0],GeomAbs_C0);
    face1.Add(e_ab[1],GeomAbs_C0);
    face1.Add(e_ac[0],GeomAbs_C0);
    face1.Add(e_ac[1],GeomAbs_C0);
    face1.Add(e_bc[0],GeomAbs_C0,false);
    face1.Build();

    BRepFill_Filling face2;
    //face2.LoadInitSurface(init);
    face2.Add(e_ab[2],GeomAbs_C0);
    face2.Add(e_ab[3],GeomAbs_C0);
    face2.Add(e_ac[2],GeomAbs_C0);
    face2.Add(e_ac[3],GeomAbs_C0);
    face2.Add(e_bc[2],GeomAbs_C0,false);
    face2.Build();

    BRepFill_Filling face3;
    //face3.LoadInitSurface(init);
    face3.Add(e_ab[2],GeomAbs_C0);
    face3.Add(e_ab[3],GeomAbs_C0);
    face3.Add(e_ac[0],GeomAbs_C0);
    face3.Add(e_ac[1],GeomAbs_C0);
    face3.Add(e_bc[1],GeomAbs_C0,false);
    face3.Build();

    BRepFill_Filling face4;
    //face4.LoadInitSurface(init);
    face4.Add(e_ab[0],GeomAbs_C0);
    face4.Add(e_ab[1],GeomAbs_C0);
    face4.Add(e_ac[2],GeomAbs_C0);
    face4.Add(e_ac[3],GeomAbs_C0);
    face4.Add(e_bc[3],GeomAbs_C0,false);
    face4.Build();

    BRep_Builder BB;
    TopoDS_Shell result;
    BB.MakeShell(result);
    BB.Add(result,face1.Face());
    BB.Add(result,face2.Face().Reversed());
    BB.Add(result,face3.Face());
    BB.Add(result,face4.Face().Reversed());

    shape=BRepBuilderAPI_MakeSolid(result);
#else
    /* FIXME, we only support spheres at the moment. */
    gp_Pnt v(scale*ell->v[0], scale*ell->v[1], scale*ell->v[2]);
    TopoDS_Solid sph=BRepPrimAPI_MakeSphere(v,scale*ell->a[0]);
    shape=sph;
#endif
}
//=======================================================================
//function : MakeScaledPrism
//purpose  :
//=======================================================================
TopoDS_Shape GEOMImpl_PrismDriver::MakeScaledPrism (const TopoDS_Shape& theShapeBase,
                                                    const gp_Vec&       theVector,
                                                    const Standard_Real theScaleFactor,
                                                    const gp_Pnt&       theCDG,
                                                    bool                isCDG)
{
  TopoDS_Shape aShape;
  BRep_Builder B;

  // 1. aCDG = geompy.MakeCDG(theBase)
  gp_Pnt aCDG = theCDG;
  if (!isCDG) {
    gp_Ax3 aPos = GEOMImpl_IMeasureOperations::GetPosition(theShapeBase);
    aCDG = aPos.Location();
  }
  TopoDS_Shape aShapeCDG_1 = BRepBuilderAPI_MakeVertex(aCDG).Shape();

  // Process case of several given shapes
  if (theShapeBase.ShapeType() == TopAbs_COMPOUND ||
      theShapeBase.ShapeType() == TopAbs_SHELL) {
    int nbSub = 0;
    TopoDS_Shape aShapeI;
    TopoDS_Compound aCompound;
    B.MakeCompound(aCompound);
    TopoDS_Iterator It (theShapeBase, Standard_True, Standard_True);
    for (; It.More(); It.Next()) {
      nbSub++;
      aShapeI = MakeScaledPrism(It.Value(), theVector, theScaleFactor, aCDG, true);
      B.Add(aCompound, aShapeI);
    }
    if (nbSub == 1)
      aShape = aShapeI;
    else if (nbSub > 1)
      aShape = GEOMImpl_GlueDriver::GlueFaces(aCompound, Precision::Confusion(), Standard_True);
    return aShape;
  }

  // 2. Scale = geompy.MakeScaleTransform(theBase, aCDG, theScaleFactor)

  // Bug 6839: Check for standalone (not included in faces) degenerated edges
  TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
  TopExp::MapShapesAndAncestors(theShapeBase, TopAbs_EDGE, TopAbs_FACE, aEFMap);
  Standard_Integer i, nbE = aEFMap.Extent();
  for (i = 1; i <= nbE; i++) {
    TopoDS_Shape anEdgeSh = aEFMap.FindKey(i);
    if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeSh))) {
      const TopTools_ListOfShape& aFaces = aEFMap.FindFromIndex(i);
      if (aFaces.IsEmpty())
        Standard_ConstructionError::Raise
          ("Scaling aborted : cannot scale standalone degenerated edge");
    }
  }

  // Perform Scaling
  gp_Trsf aTrsf;
  aTrsf.SetScale(aCDG, theScaleFactor);
  BRepBuilderAPI_Transform aBRepTrsf (theShapeBase, aTrsf, Standard_False);
  TopoDS_Shape aScale = aBRepTrsf.Shape();

  // 3. aBase2 = geompy.MakeTranslationVectorDistance(Scale, theVec, theH)
  gp_Trsf aTrsf3;
  aTrsf3.SetTranslation(theVector);
  TopLoc_Location aLocOrig = aScale.Location();
  gp_Trsf aTrsfOrig = aLocOrig.Transformation();
  TopLoc_Location aLocRes (aTrsf3 * aTrsfOrig);
  TopoDS_Shape aBase2 = aScale.Located(aLocRes);

  // 4. aCDG_2 = geompy.MakeTranslationVectorDistance(aCDG, theVec, theH)
  gp_Pnt aCDG_2 = aCDG.Translated(theVector);
  TopoDS_Shape aShapeCDG_2 = BRepBuilderAPI_MakeVertex(aCDG_2).Shape();

  // 5. Vector = geompy.MakeVector(aCDG, aCDG_2)
  TopoDS_Shape aShapeVec = BRepBuilderAPI_MakeEdge(aCDG, aCDG_2).Shape();
  TopoDS_Edge anEdge = TopoDS::Edge(aShapeVec);
  TopoDS_Wire aWirePath = BRepBuilderAPI_MakeWire(anEdge);

  // 6. aPrism = geompy.MakePipeWithDifferentSections([theBase, aBase2], [aCDG, aCDG_2], Vector, False, False)
  Handle(TopTools_HSequenceOfShape) aBases = new TopTools_HSequenceOfShape;
  aBases->Append(theShapeBase);
  aBases->Append(aBase2);

  Handle(TopTools_HSequenceOfShape) aLocs = new TopTools_HSequenceOfShape;
  aLocs->Append(aShapeCDG_1);
  aLocs->Append(aShapeCDG_2);

  aShape = GEOMImpl_PipeDriver::CreatePipeWithDifferentSections(aWirePath, aBases, aLocs, false, false);

  // 7. Make a solid, if possible
  if (theShapeBase.ShapeType() == TopAbs_FACE) {
    BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0);
    TopExp_Explorer expF (aShape, TopAbs_FACE);
    Standard_Integer ifa = 0;
    for (; expF.More(); expF.Next()) {
      aSewing.Add(expF.Current());
      ifa++;
    }
    if (ifa > 0) {
      aSewing.Perform();
      TopoDS_Shape aShell;

      TopoDS_Shape sh = aSewing.SewedShape();
      if (sh.ShapeType() == TopAbs_FACE && ifa == 1) {
        // case for creation of shell from one face
        TopoDS_Shell ss;
        B.MakeShell(ss);
        B.Add(ss,sh);
        aShell = ss;
      }
      else {
        TopExp_Explorer exp (sh, TopAbs_SHELL);
        Standard_Integer ish = 0;
        for (; exp.More(); exp.Next()) {
          aShell = exp.Current();
          ish++;
        }
        if (ish != 1)
          aShell = sh;
      }
      BRepCheck_Shell chkShell (TopoDS::Shell(aShell));
      if (chkShell.Closed() == BRepCheck_NoError) {
        TopoDS_Solid Sol;
        B.MakeSolid(Sol);
        B.Add(Sol, aShell);
        BRepClass3d_SolidClassifier SC (Sol);
        SC.PerformInfinitePoint(Precision::Confusion());
        if (SC.State() == TopAbs_IN) {
          B.MakeSolid(Sol);
          B.Add(Sol, aShell.Reversed());
        }
        aShape = Sol;
      }
    }
  }

  return aShape;
}
Example #8
0
bool FaceUniter::process()
{
    if (workShell.IsNull())
        return false;
    modifiedShapes.clear();
    deletedShapes.clear();
    typeObjects.push_back(&getPlaneObject());
    typeObjects.push_back(&getCylinderObject());
    //add more face types.

    ModelRefine::FaceTypeSplitter splitter;
    splitter.addShell(workShell);
    std::vector<FaceTypedBase *>::iterator typeIt;
    for(typeIt = typeObjects.begin(); typeIt != typeObjects.end(); ++typeIt)
        splitter.registerType((*typeIt)->getType());
    splitter.split();

    ModelRefine::FaceVectorType facesToRemove;
    ModelRefine::FaceVectorType facesToSew;

    ModelRefine::FaceAdjacencySplitter adjacencySplitter(workShell);

    for(typeIt = typeObjects.begin(); typeIt != typeObjects.end(); ++typeIt)
    {
        ModelRefine::FaceVectorType typedFaces = splitter.getTypedFaceVector((*typeIt)->getType());
        ModelRefine::FaceEqualitySplitter equalitySplitter;
        equalitySplitter.split(typedFaces, *typeIt);
        for (std::size_t indexEquality(0); indexEquality < equalitySplitter.getGroupCount(); ++indexEquality)
        {
            adjacencySplitter.split(equalitySplitter.getGroup(indexEquality));
//            std::cout << "      adjacency group count: " << adjacencySplitter.getGroupCount() << std::endl;
            for (std::size_t adjacentIndex(0); adjacentIndex < adjacencySplitter.getGroupCount(); ++adjacentIndex)
            {
//                    std::cout << "         face count is: " << adjacencySplitter.getGroup(adjacentIndex).size() << std::endl;
                TopoDS_Face newFace = (*typeIt)->buildFace(adjacencySplitter.getGroup(adjacentIndex));
                if (!newFace.IsNull())
                {
                    facesToSew.push_back(newFace);
                    if (facesToRemove.capacity() <= facesToRemove.size() + adjacencySplitter.getGroup(adjacentIndex).size())
                        facesToRemove.reserve(facesToRemove.size() + adjacencySplitter.getGroup(adjacentIndex).size());
                    FaceVectorType temp = adjacencySplitter.getGroup(adjacentIndex);
                    facesToRemove.insert(facesToRemove.end(), temp.begin(), temp.end());
                    // the first shape will be marked as modified, i.e. replaced by newFace, all others are marked as deleted
                    if (!temp.empty())
                    {
                        modifiedShapes.push_back(std::make_pair(temp.front(), newFace));
                        deletedShapes.insert(deletedShapes.end(), temp.begin()+1, temp.end());
                    }
                }
            }
        }
    }
    if (facesToSew.size() > 0)
    {
        modifiedSignal = true;
        workShell = ModelRefine::removeFaces(workShell, facesToRemove);
        TopExp_Explorer xp;
        bool emptyShell = true;
        for (xp.Init(workShell, TopAbs_FACE); xp.More(); xp.Next())
        {
            emptyShell = false;
            break;
        }

        if (!emptyShell || facesToSew.size() > 1)
        {
            BRepBuilderAPI_Sewing sew;
            sew.Add(workShell);
            FaceVectorType::iterator sewIt;
            for(sewIt = facesToSew.begin(); sewIt != facesToSew.end(); ++sewIt)
                sew.Add(*sewIt);
            sew.Perform();
            workShell = TopoDS::Shell(sew.SewedShape());
            // update the list of modifications
            for (std::vector<ShapePairType>::iterator it = modifiedShapes.begin(); it != modifiedShapes.end(); ++it)
            {
                if (sew.IsModified(it->second))
                {
                    it->second = sew.Modified(it->second);
                    break;
                }
            }
        }
        else
        {
            // workShell has no more faces and we add exactly one face
            BRep_Builder builder;
            builder.MakeShell(workShell);
            FaceVectorType::iterator sewIt;
            for(sewIt = facesToSew.begin(); sewIt != facesToSew.end(); ++sewIt)
                builder.Add(workShell, *sewIt);
        }

        BRepLib_FuseEdges edgeFuse(workShell, Standard_True);
        TopTools_DataMapOfShapeShape affectedFaces;
        edgeFuse.Faces(affectedFaces);
        TopTools_DataMapIteratorOfDataMapOfShapeShape mapIt;
        for (mapIt.Initialize(affectedFaces); mapIt.More(); mapIt.Next())
        {
            ShapeFix_Face faceFixer(TopoDS::Face(mapIt.Value()));
            faceFixer.Perform();
        }
        workShell = TopoDS::Shell(edgeFuse.Shape());
        // update the list of modifications
        TopTools_DataMapOfShapeShape faceMap;
        edgeFuse.Faces(faceMap);
        for (std::vector<ShapePairType>::iterator it = modifiedShapes.begin(); it != modifiedShapes.end(); ++it)
        {
            if (faceMap.IsBound(it->second))
            {
                const TopoDS_Shape& value = faceMap.Find(it->second);
                if (!value.IsSame(it->second))
                    it->second = value;
            }
        }
    }
    return true;
}
bool FaceUniter::process()
{
    if (workShell.IsNull())
        return false;
    modifiedShapes.clear();
    deletedShapes.clear();
    typeObjects.push_back(&getPlaneObject());
    typeObjects.push_back(&getCylinderObject());
    //add more face types.

    ModelRefine::FaceTypeSplitter splitter;
    splitter.addShell(workShell);
    std::vector<FaceTypedBase *>::iterator typeIt;
    for(typeIt = typeObjects.begin(); typeIt != typeObjects.end(); ++typeIt)
        splitter.registerType((*typeIt)->getType());
    splitter.split();

    ModelRefine::FaceVectorType facesToRemove;
    ModelRefine::FaceVectorType facesToSew;

    ModelRefine::FaceAdjacencySplitter adjacencySplitter(workShell);

    for(typeIt = typeObjects.begin(); typeIt != typeObjects.end(); ++typeIt)
    {
        ModelRefine::FaceVectorType typedFaces = splitter.getTypedFaceVector((*typeIt)->getType());
        ModelRefine::FaceEqualitySplitter equalitySplitter;
        equalitySplitter.split(typedFaces, *typeIt);
        for (std::size_t indexEquality(0); indexEquality < equalitySplitter.getGroupCount(); ++indexEquality)
        {
            adjacencySplitter.split(equalitySplitter.getGroup(indexEquality));
//            std::cout << "      adjacency group count: " << adjacencySplitter.getGroupCount() << std::endl;
            for (std::size_t adjacentIndex(0); adjacentIndex < adjacencySplitter.getGroupCount(); ++adjacentIndex)
            {
//                    std::cout << "         face count is: " << adjacencySplitter.getGroup(adjacentIndex).size() << std::endl;
                TopoDS_Face newFace = (*typeIt)->buildFace(adjacencySplitter.getGroup(adjacentIndex));
                if (!newFace.IsNull())
                {
                    facesToSew.push_back(newFace);
                    if (facesToRemove.capacity() <= facesToRemove.size() + adjacencySplitter.getGroup(adjacentIndex).size())
                        facesToRemove.reserve(facesToRemove.size() + adjacencySplitter.getGroup(adjacentIndex).size());
                    FaceVectorType temp = adjacencySplitter.getGroup(adjacentIndex);
                    facesToRemove.insert(facesToRemove.end(), temp.begin(), temp.end());
                    // the first shape will be marked as modified, i.e. replaced by newFace, all others are marked as deleted
                    // jrheinlaender: IMHO this is not correct because references to the deleted faces will be broken, whereas they should
                    // be replaced by references to the new face. To achieve this all shapes should be marked as
                    // modified, producing one single new face. This is the inverse behaviour to faces that are split e.g.
                    // by a boolean cut, where one old shape is marked as modified, producing multiple new shapes
                    if (!temp.empty())
                    {
                        for (FaceVectorType::iterator f = temp.begin(); f != temp.end(); ++f)
                              modifiedShapes.push_back(std::make_pair(*f, newFace));
                    }
                }
            }
        }
    }
    if (facesToSew.size() > 0)
    {
        modifiedSignal = true;
        workShell = ModelRefine::removeFaces(workShell, facesToRemove);
        TopExp_Explorer xp;
        bool emptyShell = true;
        for (xp.Init(workShell, TopAbs_FACE); xp.More(); xp.Next())
        {
            emptyShell = false;
            break;
        }

        if (!emptyShell || facesToSew.size() > 1)
        {
            BRepBuilderAPI_Sewing sew;
            sew.Add(workShell);
            FaceVectorType::iterator sewIt;
            for(sewIt = facesToSew.begin(); sewIt != facesToSew.end(); ++sewIt)
                sew.Add(*sewIt);
            sew.Perform();
            try {
                workShell = TopoDS::Shell(sew.SewedShape());
            } catch (Standard_Failure) {
                return false;
            }
            // update the list of modifications
            for (std::vector<ShapePairType>::iterator it = modifiedShapes.begin(); it != modifiedShapes.end(); ++it)
            {
                if (sew.IsModified(it->second))
                {
                    it->second = sew.Modified(it->second);
                    break;
                }
            }
        }
        else
        {
            // workShell has no more faces and we add exactly one face
            BRep_Builder builder;
            builder.MakeShell(workShell);
            FaceVectorType::iterator sewIt;
            for(sewIt = facesToSew.begin(); sewIt != facesToSew.end(); ++sewIt)
                builder.Add(workShell, *sewIt);
        }
        
        BRepLib_FuseEdges edgeFuse(workShell);
// TODO: change this version after occ fix. Freecad Mantis 1450
#if OCC_VERSION_HEX <= 0x070000
        TopTools_IndexedMapOfShape map;
        collectConicEdges(workShell, map);
        edgeFuse.AvoidEdges(map);
#endif
        TopTools_DataMapOfShapeShape affectedFaces;
        edgeFuse.Faces(affectedFaces);
        TopTools_DataMapIteratorOfDataMapOfShapeShape mapIt;
        for (mapIt.Initialize(affectedFaces); mapIt.More(); mapIt.Next())
        {
            ShapeFix_Face faceFixer(TopoDS::Face(mapIt.Value()));
            faceFixer.Perform();
        }
        workShell = TopoDS::Shell(edgeFuse.Shape());
        // update the list of modifications
        TopTools_DataMapOfShapeShape faceMap;
        edgeFuse.Faces(faceMap);
        for (mapIt.Initialize(faceMap); mapIt.More(); mapIt.Next())
        {
            bool isModifiedFace = false;
            for (std::vector<ShapePairType>::iterator it = modifiedShapes.begin(); it != modifiedShapes.end(); ++it)
            {
                if (mapIt.Key().IsSame(it->second)) {
                    // Note: IsEqual() for some reason does not work
                    it->second = mapIt.Value();
                    isModifiedFace = true;
                }
            }
            if (!isModifiedFace)
            {
                // Catch faces that were not united but whose boundary was changed (probably because
                // several adjacent faces were united)
                // See https://sourceforge.net/apps/mantisbt/free-cad/view.php?id=873
                modifiedShapes.push_back(std::make_pair(mapIt.Key(), mapIt.Value()));
            }
        }
        // Handle edges that were fused. See https://sourceforge.net/apps/mantisbt/free-cad/view.php?id=873
        TopTools_DataMapOfIntegerListOfShape oldEdges;
        TopTools_DataMapOfIntegerShape newEdges;
        edgeFuse.Edges(oldEdges);
        edgeFuse.ResultEdges(newEdges);
        TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape edgeMapIt;
        for (edgeMapIt.Initialize(oldEdges); edgeMapIt.More(); edgeMapIt.Next())
        {
            const TopTools_ListOfShape& edges = edgeMapIt.Value();
            int idx = edgeMapIt.Key();
            TopTools_ListIteratorOfListOfShape edgeIt;
            for (edgeIt.Initialize(edges); edgeIt.More(); edgeIt.Next())
            {
                modifiedShapes.push_back(std::make_pair(edgeIt.Value(), newEdges(idx)));
            }
            // TODO: Handle vertices that have disappeared in the fusion of the edges
        }
    }
    return true;
}
//=======================================================================
//function : BuildDraftSolid
//purpose  :
//=======================================================================
void GEOMAlgo_Builder::BuildDraftSolid (const TopoDS_Shape& theSolid,
                                        TopoDS_Shape& theDraftSolid,
                                        TopTools_ListOfShape& theLIF)
{
  myErrorStatus=0;
  //
  NMTTools_PaveFiller* pPF=myPaveFiller;
  const Handle(IntTools_Context)& aCtx= pPF->Context();
  //
  Standard_Boolean bToReverse;
  Standard_Integer  iFlag;
  TopAbs_Orientation aOrF, aOrSh, aOrSd;
  TopoDS_Iterator aIt1, aIt2;
  TopTools_ListIteratorOfListOfShape aItS;
  BRep_Builder aBB;
  TopoDS_Shell aShD;
  TopoDS_Shape aFSDx, aFx;
  //
  aOrSd=theSolid.Orientation();
  theDraftSolid.Orientation(aOrSd);
  //
  aIt1.Initialize(theSolid);
  for (; aIt1.More(); aIt1.Next()) {
    const TopoDS_Shape& aSh=aIt1.Value();
    if(aSh.ShapeType()!=TopAbs_SHELL) {
      continue; // mb internal edges,vertices
    }
    //
    aOrSh=aSh.Orientation();
    aBB.MakeShell(aShD);
    aShD.Orientation(aOrSh);
    iFlag=0;
    //
    aIt2.Initialize(aSh);
    for (; aIt2.More(); aIt2.Next()) {
      const TopoDS_Shape& aF=aIt2.Value();
      aOrF=aF.Orientation();
      //
      if (myImages.HasImage(aF)) {
        const TopTools_ListOfShape& aLSp=myImages.Image(aF);
        aItS.Initialize(aLSp);
        for (; aItS.More(); aItS.Next()) {
          aFx=aItS.Value();
          //
          if (mySameDomainShapes.Contains(aFx)) {
            aFSDx=mySameDomainShapes.FindFromKey(aFx);
            //
            if (aOrF==TopAbs_INTERNAL) {
              aFSDx.Orientation(aOrF);
              theLIF.Append(aFSDx);
            }
            else {
              bToReverse=GEOMAlgo_Tools3D::IsSplitToReverse(aFSDx, aF, aCtx);
              if (bToReverse) {
                aFSDx.Reverse();
              }
              //
              iFlag=1;
              aBB.Add(aShD, aFSDx);
            }
          }// if (mySameDomainShapes.Contains(aFx)) {
          else {
            aFx.Orientation(aOrF);
            if (aOrF==TopAbs_INTERNAL) {
              theLIF.Append(aFx);
            }
            else{
              iFlag=1;
              aBB.Add(aShD, aFx);
            }
          }
        }
      } //if (myImages.HasImage(aF)) {
      //
      else {
        if (aOrF==TopAbs_INTERNAL) {
          theLIF.Append(aF);
        }
        else{
          iFlag=1;
          aBB.Add(aShD, aF);
        }
      }
    } //for (; aIt2.More(); aIt2.Next()) {
    //
    if (iFlag) {
      aBB.Add(theDraftSolid, aShD);
    }
  } //for (; aIt1.More(); aIt1.Next()) {
}
App::DocumentObjectExecReturn *Fractal::execute(void)
{
	faces.clear();
	//Appel de la fonction de generation avec des valeurs prereglees(taille) et la valeur de l'utilisateur
	//sierpin([-7, -4, 0], [0, 8, 0], [7, -4, 0], [0, 0, 11], 6)
	//sierpin(Base::Vector3d(-5, -5, -5), Base::Vector3d(5, 5, -5), Base::Vector3d(-5, 5, 5), Base::Vector3d(5, -5, 5), 1, Nodes.getValues());
	
	sierpin(Base::Vector3d(-Length.getValue(), -Width.getValue(), -Height.getValue()), Base::Vector3d(Length.getValue(), Width.getValue(), -Height.getValue()), Base::Vector3d(-Length.getValue(), Width.getValue(), Height.getValue()), Base::Vector3d(Length.getValue(), -Width.getValue(), Height.getValue()), Depth.getValue(), Nodes.getValues());
	//Sponge();

		/*//Creation du shell avec la liste des faces
		myShell = Part.makeShell(partFaces);
		// Creation du polygon avec le shell
		mySolid = Part.makeSolid(myShell);
		// Mise a jour de l'orientation des faces
		mySolidRev = mySolid.copy();
		mySolidRev.reverse();

		//Affichage du solide
		Part.show(mySolidRev);*/

	BRepBuilderAPI_MakePolygon poly;
	//const std::vector<Base::Vector3d> nodes = Nodes;
	/*_nodes.push_back(Base::Vector3d(0, 0, 0));
	_nodes.push_back(Base::Vector3d(0, 0, 1));
	_nodes.push_back(Base::Vector3d(0, 0, 3));
	_nodes.push_back(Base::Vector3d(0, 0, 5));
	_nodes.push_back(Base::Vector3d(0, 5, 0));
	_nodes.push_back(Base::Vector3d(0, 0, 8));*/

	/*std::string s = std::to_string(_nodes.size());
	char const *pchar = s.c_str();
	Base::Console().Message(pchar);
	Base::Console().Log(pchar);*/

	for (std::vector<Base::Vector3d>::const_iterator it = _nodes.begin(); it != _nodes.end(); ++it) {
		gp_Pnt pnt(it->x, it->y, it->z);
		poly.Add(pnt);
	}

	if (!poly.IsDone())
		throw Base::Exception("Cannot create polygon because less than two vetices are given");
	//TopoDS_Wire wire = poly.Wire();
	//BRepBuilderAPI_MakeFace makeFace(poly.Wire());

	/*gp_Pnt point1 = gp_Pnt(1,0,0);
	gp_Pnt point2 = gp_Pnt(1,1,0);
	gp_Pnt point3 = gp_Pnt(1,0,1);*/
	//TopoDS_Wire wire = BRepBuilderAPI_MakePolygon(, Standard_True);
	//TopoDS_Face face = BRepBuilderAPI_MakeFace(wire, Standard_True);
	//TopoDS_Shape s;

	/*if (makeFace.Error() == BRepBuilderAPI_FaceDone)
	{
		TopoDS_Face faceCurrent = makeFace.Face();
	}
	BRepBuilderAPI_MakeFace makeFace(faceCurrent);
	makeFace.Add(MP.Wire());
	if (makeFace.Error() == BRepBuilderAPI_FaceDone)
	{
		faceCurrent = makeFace.Face();
	}*/

	//this->Shape.setValue();



	//TopoDS_Face tf;

	//BRepBuilderAPI_MakeFace mkFace(TopoDS::Wire(sh));

	//Handle_Geom_Surface gs;
	//Handle<Geom_Surface> dd;
	//gs.Access = 0;

	/*RepOffsetAPI_MakeOffsetShape mkOffset(this->_Shape, offset, tol, BRepOffset_Mode(offsetMode),
        intersection ? Standard_True : Standard_False,
        selfInter ? Standard_True : Standard_False,
        GeomAbs_JoinType(join));
   
    if (!fill)
        return res;
#if 1
    //s=Part.makePlane(10,10)
    //s.makeOffsetShape(1.0,0.01,False,False,0,0,True)*/

	//BRepOffsetAPI_MakeOffsetShape myOffsetShape;
	//TopoShape ts;
	//myOffsetShape = ts.makeOffsetShape(1.0, 0.01, False, False, 0, 0, True);
	//const TopoDS_Shape& res = myOffsetShape.Shape();

	BRep_Builder builder;
	TopoDS_Shell shell;
	builder.MakeShell(shell);
	/*s = std::to_string(faces.size());
	pchar = s.c_str();
	Base::Console().Message(pchar);
	Base::Console().Log(pchar);*/
	for (int i = 0; i < faces.size(); i++) {
		builder.Add(shell, faces[i]);
		//this->Shape.setValue(shell);
	}
	//this->Shape.setValue(builder.sh);

	//BRepBuilderAPI_MakeShell myShell(gs);
	//const TopoDS_Shell& td = gs.sh;

	/*TopoDS_Solid mysolid;
	builder.MakeSolid(mysolid);
	builder.Add(mysolid, shell);*/

	BRepBuilderAPI_MakeSolid mySolid(shell);
	this->Shape.setValue(mySolid.Shape());


	return App::DocumentObject::StdReturn;
	}