]> OCCT Git - occt-copy.git/commitdiff
Implementation of the algorithm for replacing faces in shape with new faces based... CR0-winwerth_5
authorjgv <jgv@opencascade.com>
Mon, 14 Aug 2017 11:48:07 +0000 (14:48 +0300)
committeremv <emv@opencascade.com>
Thu, 17 Aug 2017 14:19:52 +0000 (17:19 +0300)
The algorithm runs the steps similar to 3d Offset algorithm for Join type Intersection (intersection of the faces with neighbors for trimming of the faces by the adjacent faces).

Test cases for new functionality.

48 files changed:
src/BRepOffset/BRepOffset_Tool.cxx
src/BRepOffset/BRepOffset_Tool.hxx
src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.cxx [new file with mode: 0644]
src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.hxx [new file with mode: 0644]
src/BRepOffsetAPI/FILES
src/BRepTest/BRepTest_FeatureCommands.cxx
src/TopExp/TopExp.cxx
src/TopExp/TopExp.hxx
tests/patchfaces/begin [new file with mode: 0644]
tests/patchfaces/end [new file with mode: 0644]
tests/patchfaces/grids.list [new file with mode: 0644]
tests/patchfaces/parse.rules [new file with mode: 0644]
tests/patchfaces/replace/end [new file with mode: 0644]
tests/patchfaces/replace/test_1 [new file with mode: 0644]
tests/patchfaces/replace/test_10 [new file with mode: 0644]
tests/patchfaces/replace/test_11 [new file with mode: 0644]
tests/patchfaces/replace/test_12 [new file with mode: 0644]
tests/patchfaces/replace/test_13 [new file with mode: 0644]
tests/patchfaces/replace/test_14 [new file with mode: 0644]
tests/patchfaces/replace/test_15 [new file with mode: 0644]
tests/patchfaces/replace/test_16 [new file with mode: 0644]
tests/patchfaces/replace/test_17 [new file with mode: 0644]
tests/patchfaces/replace/test_18 [new file with mode: 0644]
tests/patchfaces/replace/test_19 [new file with mode: 0644]
tests/patchfaces/replace/test_2 [new file with mode: 0644]
tests/patchfaces/replace/test_20 [new file with mode: 0644]
tests/patchfaces/replace/test_21 [new file with mode: 0644]
tests/patchfaces/replace/test_22 [new file with mode: 0644]
tests/patchfaces/replace/test_23 [new file with mode: 0644]
tests/patchfaces/replace/test_24 [new file with mode: 0644]
tests/patchfaces/replace/test_25 [new file with mode: 0644]
tests/patchfaces/replace/test_26 [new file with mode: 0644]
tests/patchfaces/replace/test_27 [new file with mode: 0644]
tests/patchfaces/replace/test_28 [new file with mode: 0644]
tests/patchfaces/replace/test_29 [new file with mode: 0644]
tests/patchfaces/replace/test_3 [new file with mode: 0644]
tests/patchfaces/replace/test_30 [new file with mode: 0644]
tests/patchfaces/replace/test_31 [new file with mode: 0644]
tests/patchfaces/replace/test_32 [new file with mode: 0644]
tests/patchfaces/replace/test_33 [new file with mode: 0644]
tests/patchfaces/replace/test_34 [new file with mode: 0644]
tests/patchfaces/replace/test_35 [new file with mode: 0644]
tests/patchfaces/replace/test_4 [new file with mode: 0644]
tests/patchfaces/replace/test_5 [new file with mode: 0644]
tests/patchfaces/replace/test_6 [new file with mode: 0644]
tests/patchfaces/replace/test_7 [new file with mode: 0644]
tests/patchfaces/replace/test_8 [new file with mode: 0644]
tests/patchfaces/replace/test_9 [new file with mode: 0644]

index 638b476ae6dba0c949e77a0cdd89223e6d1d145d..da2d9b0a11ad07c6b681d2c3a61cda3c3ff1d23b 100644 (file)
@@ -2817,7 +2817,7 @@ static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
                                        const Standard_Boolean GlobalEnlargeVfirst,
                                        const Standard_Boolean GlobalEnlargeVlast)
 {
-  const Standard_Real coeff = 4.;
+  const Standard_Real coeff = 2.;
   const Standard_Real TolApex = 1.e-5;
 
   Standard_Boolean SurfaceChange = Standard_False;
@@ -3200,7 +3200,8 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
  const Standard_Boolean   UpdatePCurve,
  const Standard_Boolean   enlargeU,
  const Standard_Boolean   enlargeVfirst,
- const Standard_Boolean   enlargeVlast)
+ const Standard_Boolean   enlargeVlast,
+ const Standard_Boolean   UseInfini)
 {
   //---------------------------
   // extension de la geometrie.
@@ -3223,8 +3224,20 @@ Standard_Boolean BRepOffset_Tool::EnLargeFace
   }
 
   S->Bounds            (US1,US2,VS1,VS2);
-  UU1 = VV1 = - infini;
-  UU2 = VV2 =   infini;
+  if (UseInfini)
+  {
+    UU1 = VV1 = - infini;
+    UU2 = VV2 =   infini;
+  }
+  else
+  {
+    Standard_Real FaceDU = UF2 - UF1;
+    Standard_Real FaceDV = VF2 - VF1;
+    UU1 = UF1 - FaceDU;
+    UU2 = UF2 + FaceDU;
+    VV1 = VF1 - FaceDV;
+    VV2 = VF2 + FaceDV;
+  }
   
   if (CanExtentSurface) {
     SurfaceChange = EnlargeGeometry( S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2,
index b0609d5506e055729c38865fe8954ee9a3aa592f..67e764a012377e18e5ebd00a6cca48025d37d32b 100644 (file)
@@ -92,8 +92,15 @@ public:
   //! if <UpdatePCurve>  is  TRUE, update the  pcurves of the
   //! edges of <F> on   the new surface.if the surface has  been changed,
   //! Returns  True if The Surface of  <NF> has changed.
-  Standard_EXPORT static Standard_Boolean EnLargeFace (const TopoDS_Face& F, TopoDS_Face& NF, const Standard_Boolean ChangeGeom, const Standard_Boolean UpDatePCurve = Standard_False, const Standard_Boolean enlargeU = Standard_True, const Standard_Boolean enlargeVfirst = Standard_True, const Standard_Boolean enlargeVlast = Standard_True);
-  
+  Standard_EXPORT static Standard_Boolean EnLargeFace (const TopoDS_Face& F,
+                                                       TopoDS_Face& NF,
+                                                       const Standard_Boolean ChangeGeom,
+                                                       const Standard_Boolean UpDatePCurve = Standard_False,
+                                                       const Standard_Boolean enlargeU = Standard_True,
+                                                       const Standard_Boolean enlargeVfirst = Standard_True,
+                                                       const Standard_Boolean enlargeVlast = Standard_True,
+                                                       const Standard_Boolean UseInfini = Standard_True);
+
   Standard_EXPORT static void ExtentFace (const TopoDS_Face& F, TopTools_DataMapOfShapeShape& ConstShapes, TopTools_DataMapOfShapeShape& ToBuild, const TopAbs_State Side, const Standard_Real TolConf, TopoDS_Face& NF);
   
   //! Via the wire explorer store in <NOnV1> for
diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.cxx b/src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.cxx
new file mode 100644 (file)
index 0000000..cf1be4c
--- /dev/null
@@ -0,0 +1,781 @@
+// Created on: 2012-08-06
+// Created by: jgv@ROLEX
+// Copyright (c) 2012-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+
+#include <BRepOffsetAPI_PatchFaces.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <BRepAdaptor_HSurface.hxx>
+#include <BRepTopAdaptor_TopolTool.hxx>
+#include <LocalAnalysis_SurfaceContinuity.hxx>
+#include <TopOpeBRepTool_TOOL.hxx>
+#include <BRepLib.hxx>
+#include <BRepLib_MakeVertex.hxx>
+#include <BRepLib_MakeEdge.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <IntTools_Context.hxx>
+#include <BOPTools_AlgoTools.hxx>
+#include <BRepOffset_Tool.hxx>
+#include <ShapeAnalysis_Surface.hxx>
+#include <ShapeConstruct_ProjectCurveOnSurface.hxx>
+#include <BRepAlgoAPI_Section.hxx>
+#include <Extrema_ExtPC.hxx>
+#include <BRepExtrema_ExtCC.hxx>
+#include <ShapeFix_Shape.hxx>
+
+
+static TopoDS_Edge MakeNewEdgeWithOldPcurvesOnNewSurfaces(const TopoDS_Edge& theEdge,
+                                                          const TopoDS_Face& theOldFace1,
+                                                          const TopoDS_Face& theNewFace1,
+                                                          const TopoDS_Face& theOldFace2,
+                                                          const TopoDS_Face& theNewFace2)
+{
+  TopoDS_Edge aNewEdge;
+  Standard_Real fpar, lpar;
+  BRep_Builder BB;
+  
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, fpar, lpar);
+  aNewEdge = BRepLib_MakeEdge(aCurve, aCurve->FirstParameter(), aCurve->LastParameter()); //???
+  TopoDS_Vertex V1, V2;
+  TopExp::Vertices(aNewEdge, V1, V2);
+  aNewEdge.Free(Standard_True);
+  BB.Remove(aNewEdge, V1);
+  BB.Remove(aNewEdge, V2);
+  
+  Standard_Real Etol = BRep_Tool::Tolerance(theEdge);
+  Handle(Geom2d_Curve) aPCurve1 = BRep_Tool::CurveOnSurface(theEdge, theOldFace1, fpar, lpar);
+  BB.UpdateEdge(aNewEdge, aPCurve1, theNewFace1, Etol);
+  Handle(Geom2d_Curve) aPCurve2 = BRep_Tool::CurveOnSurface(theEdge, theOldFace2, fpar, lpar);
+  BB.UpdateEdge(aNewEdge, aPCurve2, theNewFace2, Etol);
+
+  return aNewEdge;
+}
+
+static void UpdateEdgeByProjectionOfPCurve(TopoDS_Edge& anEdge,
+                                           const TopoDS_Face& aNewFace,
+                                           const TopoDS_Face& aBoundedNewFace)
+{
+  BRep_Builder BB;
+  Standard_Real fpar, lpar;
+  
+  Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge,fpar,lpar);
+  
+  Handle(Geom_Surface) NewSurf = BRep_Tool::Surface(aNewFace);
+  Handle(ShapeAnalysis_Surface) SAS = new ShapeAnalysis_Surface(NewSurf);
+  ShapeConstruct_ProjectCurveOnSurface aToolProj;
+  aToolProj.Init(SAS, Precision::Confusion());
+  Handle(Geom2d_Curve) NewPCurve;
+  aToolProj.Perform(aCurve,fpar,lpar,NewPCurve);
+  Standard_Real TolReached = SAS->Gap();
+  //BB.UpdateEdge(anEdge, NullPCurve, aFace, 0.);
+  BB.UpdateEdge(anEdge, NewPCurve, aBoundedNewFace, TolReached);
+  TopoDS_Vertex V1, V2;
+  TopExp::Vertices(anEdge, V1, V2);
+  BB.UpdateVertex(V1, TolReached);
+  BB.UpdateVertex(V2, TolReached);
+}
+
+static void ProjectVertexOnNewEdge(const TopoDS_Vertex& theVertex,
+                                   const TopoDS_Edge&   theEdge,
+                                   const TopoDS_Edge&   theNewEdge,
+                                   Standard_Real&       theParam,
+                                   gp_Pnt&              thePnt,
+                                   Standard_Real&       theTolReached)
+{
+  Standard_Real ParamOnEdge = BRep_Tool::Parameter(theVertex, theEdge);
+  BRepAdaptor_Curve BAcurve(theEdge);
+  BRepAdaptor_Curve BAnewcurve(theNewEdge);
+  gp_Pnt PointOnEdge = BAcurve.Value(ParamOnEdge);
+  Extrema_ExtPC Projector(PointOnEdge, BAnewcurve);
+  Standard_Real Param[4], dist[4];
+  gp_Pnt Pnt[4];
+  Param[1] = BAnewcurve.FirstParameter();
+  Param[2] = BAnewcurve.LastParameter();
+  Projector.TrimmedSquareDistances(dist[1], dist[2], Pnt[1], Pnt[2]);
+  dist[3] = RealLast();
+  if (Projector.IsDone() && Projector.NbExt() > 0)
+  {
+    Standard_Integer imin = 1;
+    for (Standard_Integer i = 2; i <= Projector.NbExt(); i++)
+      if (Projector.SquareDistance(i) < Projector.SquareDistance(imin))
+        imin = i;
+    Param[3] = Projector.Point(imin).Parameter();
+    dist[3]  = Projector.SquareDistance(imin);
+    Pnt[3]   = Projector.Point(imin).Value();
+  }
+
+  Standard_Integer imin = 1;
+  for (Standard_Integer i = 2; i <= 3; i++)
+    if (dist[i] < dist[imin])
+      imin = i;
+
+  theParam      = Param[imin];
+  thePnt        = Pnt[imin];
+  theTolReached = sqrt(dist[imin]);
+}
+
+static TopoDS_Edge GetGeneratedEdge(const TopoDS_Edge& anEdge,
+                                    const TopoDS_Face& aFace,
+                                    const TopoDS_Face& aNewFace)
+{
+  TopoDS_Edge aNewEdge;
+  
+  TopExp_Explorer Explo(aFace, TopAbs_EDGE);
+  TopExp_Explorer ExploNew(aNewFace, TopAbs_EDGE);
+  for (; Explo.More(); Explo.Next(),ExploNew.Next())
+  {
+    const TopoDS_Shape& EdgeInFace = Explo.Current();
+    //const TopoDS_Shape& EdgeInNewFace = ExploNew.Current();
+    if (anEdge == EdgeInFace)
+    {
+      aNewEdge = TopoDS::Edge(ExploNew.Current());
+      break;
+    }
+  }
+
+  TopoDS_Vertex V1, V2;
+  TopExp::Vertices(aNewEdge, V1, V2);
+  BRep_Builder BB;
+  aNewEdge.Free(Standard_True);
+  BB.Remove(aNewEdge, V1);
+  BB.Remove(aNewEdge, V2);
+  return aNewEdge;
+}
+
+static TopAbs_Orientation OrientationInEdge(const TopoDS_Vertex& theVertex,
+                                            const TopoDS_Edge& theEdge)
+{
+  TopoDS_Vertex V1, V2;
+  TopExp::Vertices(theEdge, V1, V2);
+  if (theVertex.IsSame(V1))
+    return TopAbs_FORWARD;
+  
+  return TopAbs_REVERSED;
+}
+
+static Standard_Boolean EdgeContains(const TopoDS_Edge& theEdge,
+                                     const TopoDS_Vertex& theVertex)
+{
+  TopoDS_Iterator ite(theEdge);
+  for (; ite.More(); ite.Next())
+    if (theVertex.IsSame(ite.Value()))
+      return Standard_True;
+  
+  return Standard_False;
+}
+
+
+static Standard_Boolean IsTangentFaces(const TopoDS_Edge& theEdge,
+                                       const TopoDS_Face& theFace1,
+                                       const TopoDS_Face& theFace2,
+                                       const GeomAbs_Shape Order)
+{
+  if (Order == GeomAbs_G1 &&
+      BRep_Tool::Continuity( theEdge, theFace1, theFace2 ) != GeomAbs_C0)
+    return Standard_True;
+
+  Standard_Real TolC0 = Max(0.001, 1.5*BRep_Tool::Tolerance(theEdge));
+
+  Standard_Real aFirst;
+  Standard_Real aLast;
+    
+// Obtaining of pcurves of edge on two faces.
+  const Handle(Geom2d_Curve) aC2d1 = BRep_Tool::CurveOnSurface
+                                                (theEdge, theFace1, aFirst, aLast);
+  const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface
+                                                (theEdge, theFace2, aFirst, aLast);
+  if (aC2d1.IsNull() || aC2d2.IsNull())
+    return Standard_False;
+
+// Obtaining of two surfaces from adjacent faces.
+  Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
+  Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
+
+  if (aSurf1.IsNull() || aSurf2.IsNull())
+    return Standard_False;
+
+// Computation of the number of samples on the edge.
+  BRepAdaptor_Surface              aBAS1(theFace1);
+  BRepAdaptor_Surface              aBAS2(theFace2);
+  Handle(BRepAdaptor_HSurface)     aBAHS1      = new BRepAdaptor_HSurface(aBAS1);
+  Handle(BRepAdaptor_HSurface)     aBAHS2      = new BRepAdaptor_HSurface(aBAS2);
+  Handle(BRepTopAdaptor_TopolTool) aTool1      = new BRepTopAdaptor_TopolTool(aBAHS1);
+  Handle(BRepTopAdaptor_TopolTool) aTool2      = new BRepTopAdaptor_TopolTool(aBAHS2);
+  Standard_Integer                 aNbSamples1 =     aTool1->NbSamples();
+  Standard_Integer                 aNbSamples2 =     aTool2->NbSamples();
+  const Standard_Integer           aNbSamplesMax =   23;
+  Standard_Integer                 aNbSamples  =     Min(aNbSamplesMax, Max(aNbSamples1, aNbSamples2));
+  const Standard_Real              aTolAngle   =     M_PI/18;
+
+
+// Computation of the continuity.
+  Standard_Real    aPar;
+  Standard_Real    aDelta = (aLast - aFirst)/(aNbSamples - 1);
+  Standard_Integer i, nbNotDone = 0;
+
+  for (i = 1, aPar = aFirst; i <= aNbSamples; i++, aPar += aDelta) {
+    if (i == aNbSamples) aPar = aLast;
+
+    LocalAnalysis_SurfaceContinuity aCont(aC2d1,  aC2d2,  aPar,
+                                          aSurf1, aSurf2, Order,
+                                          0.001, TolC0, aTolAngle, 0.1, 0.1);
+    if (!aCont.IsDone()) 
+    {
+      nbNotDone++;
+      continue;
+    }
+
+    if (Order == GeomAbs_G1)
+    {
+      if (!aCont.IsG1())
+        return Standard_False;
+    }
+    else if (!aCont.IsG2())
+      return Standard_False;
+  }
+
+  if (nbNotDone == aNbSamples)
+    return Standard_False;
+
+  return Standard_True;
+}
+
+//=======================================================================
+//function : BRepOffsetAPI_PatchFaces
+//purpose  : Constructor
+//=======================================================================
+
+BRepOffsetAPI_PatchFaces::BRepOffsetAPI_PatchFaces(const TopoDS_Shape& theShape)
+{
+  myInitialShape = theShape;
+}
+
+//=======================================================================
+//function : SetOffsetFace
+//purpose  : 
+//=======================================================================
+void BRepOffsetAPI_PatchFaces::AddPatchFace(const TopoDS_Face& theFace,
+                                            const TopoDS_Face& thePatchFace)
+{
+  // Check the orientation of the patch face and make
+  // it oriented the same way as original
+  TopoDS_Face aFace      = TopoDS::Face(theFace.Oriented(TopAbs_FORWARD));
+  TopoDS_Face aPatchFace = TopoDS::Face(thePatchFace.Oriented(TopAbs_FORWARD));
+  
+  Handle(IntTools_Context) aCtx = new IntTools_Context;
+  Standard_Boolean bToReverse = BOPTools_AlgoTools::IsSplitToReverse(aFace, aPatchFace, aCtx);
+  TopoDS_Face anOrientedPatchFace = bToReverse ? TopoDS::Face(aPatchFace.Reversed()) : aPatchFace;
+  myFacePatchFace.Add(aFace, anOrientedPatchFace);
+}
+
+//=======================================================================
+//function : Build
+//purpose  : 
+//=======================================================================
+
+void BRepOffsetAPI_PatchFaces::Build()
+{
+  TopExp::MapShapesAndUniqueAncestors(myInitialShape, TopAbs_EDGE, TopAbs_FACE, myEFmap);
+
+  //Draft filling of <myFaceNewFace>
+  for (Standard_Integer i = 1; i <= myFacePatchFace.Extent(); i++)
+  {
+    const TopoDS_Face& aFace = TopoDS::Face(myFacePatchFace.FindKey(i));
+    const TopoDS_Shape& aPatchFace = myFacePatchFace(i);
+    myFaceNewFace.Add(aFace, aPatchFace);
+    TopExp_Explorer Explo(aFace, TopAbs_EDGE);
+    for (; Explo.More(); Explo.Next())
+    {
+      const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
+      const TopTools_ListOfShape& Lfaces = myEFmap.FindFromKey(anEdge);
+      TopoDS_Face aNeighborFace = (aFace.IsSame(Lfaces.First()))?
+        TopoDS::Face(Lfaces.Last()) : TopoDS::Face(Lfaces.First());
+      if (myFacePatchFace.Contains(aNeighborFace))
+        continue;
+      if (myFaceNewFace.Contains(aNeighborFace))
+        continue;
+      Standard_Boolean IsTangentEdge = IsTangentFaces(anEdge, aFace, aNeighborFace, GeomAbs_G1);
+      if (IsTangentEdge)
+      {
+        myTangentEdges.Add(anEdge);
+        continue;
+      }
+                                                                          
+      aNeighborFace.Orientation(TopAbs_FORWARD);
+      TopoDS_Face aNewFace;
+      BRepOffset_Tool::EnLargeFace(aNeighborFace, aNewFace,
+                                   Standard_True,Standard_True,Standard_True,Standard_True,Standard_True,
+                                   Standard_False); //not too big
+      myFaceNewFace.Add(aNeighborFace, aNewFace);
+    }
+  }
+
+  //Make draft intersection edges: draft filling of <myEdgeNewEdge>
+  BRep_Builder BB;
+  TopTools_MapOfShape UpdatedConstEdges;
+  for (Standard_Integer i = 1; i <= myFaceNewFace.Extent(); i++)
+  {
+    TopoDS_Face aFace = TopoDS::Face(myFaceNewFace.FindKey(i));
+    TopoDS_Face aNewFace = TopoDS::Face(myFaceNewFace(i));
+    TopoDS_Face aBoundedNewFace;
+    if (myNewFaceBoundedFace.IsBound(aNewFace))
+      aBoundedNewFace = TopoDS::Face(myNewFaceBoundedFace(aNewFace));
+    else
+    {
+      aBoundedNewFace = TopoDS::Face(aNewFace.EmptyCopied());
+      myNewFaceBoundedFace.Bind(aNewFace, aBoundedNewFace);
+    }
+      
+    TopoDS_Iterator itf(aFace);
+    for (; itf.More(); itf.Next())
+    {
+      const TopoDS_Wire& aWire = TopoDS::Wire(itf.Value());
+      TopoDS_Wire F_Wire = TopoDS::Wire(aWire.Oriented(TopAbs_FORWARD));
+      BRepTools_WireExplorer wexp(F_Wire, aFace);
+      for (; wexp.More(); wexp.Next())
+      {
+        TopoDS_Edge anEdge = wexp.Current();
+        Standard_Boolean ToReverse = Standard_False;
+        TopoDS_Edge aNewEdge;
+        if (myEdgeNewEdge.IsBound(anEdge))
+          //aNewEdge = TopoDS::Edge(myEdgeNewEdge(anEdge));
+          continue;
+        
+        Handle(Geom2d_Curve) NullPCurve;
+        Standard_Real fpar, lpar;
+        
+        const TopTools_ListOfShape& Lfaces = myEFmap.FindFromKey(anEdge);
+        if (Lfaces.Extent() == 1) //seam edge
+        {
+          cout<<endl<<"Seam edge or degenerated edge !!!"<<endl;
+          TopoDS_Edge GeneratedEdge = GetGeneratedEdge(anEdge, aFace, aNewFace);
+          myOrientedEdgeNewEdge.Bind(anEdge, GeneratedEdge);
+          continue;
+        }
+        
+        TopoDS_Face aNeighborFace = (aFace.IsSame(Lfaces.First()))?
+          TopoDS::Face(Lfaces.Last()) : TopoDS::Face(Lfaces.First());
+        
+        if (myTangentEdges.Contains(anEdge)&&
+            !UpdatedConstEdges.Contains(anEdge)) //project onto patch
+        {
+          UpdateEdgeByProjectionOfPCurve(anEdge, aNewFace, aBoundedNewFace);
+          
+          //aNewEdge = anEdge;
+          UpdatedConstEdges.Add(anEdge);
+          continue;
+        }
+        
+        if (myFaceNewFace.Contains(aNeighborFace))//intersect
+        {
+          TopoDS_Face aNewNeighborFace = TopoDS::Face(myFaceNewFace.FindFromKey(aNeighborFace));
+          TopoDS_Face aBoundedNewNeighborFace;
+          if (myNewFaceBoundedFace.IsBound(aNewNeighborFace))
+            aBoundedNewNeighborFace = TopoDS::Face(myNewFaceBoundedFace(aNewNeighborFace));
+          else
+          {
+            aBoundedNewNeighborFace = TopoDS::Face(aNewNeighborFace.EmptyCopied());
+            myNewFaceBoundedFace.Bind(aNewNeighborFace, aBoundedNewNeighborFace);
+          }
+
+          if (!myFacePatchFace.Contains(aFace) &&
+              !myFacePatchFace.Contains(aNeighborFace) &&
+              IsTangentFaces(anEdge, aFace, aNeighborFace, GeomAbs_G1)) //smooth edge
+          {
+            //make new edge with pcurves on new surfaces
+            aNewEdge = MakeNewEdgeWithOldPcurvesOnNewSurfaces(anEdge,
+                                                              aFace, aBoundedNewFace,
+                                                              aNeighborFace, aBoundedNewNeighborFace);
+
+            myEdgeNewEdge.Bind(anEdge.Oriented(TopAbs_FORWARD), aNewEdge);
+            continue;
+          }
+          
+          BRepLib::BuildCurves3d(aNewFace);
+          BRepLib::BuildCurves3d(aNewNeighborFace);
+          
+          BRepAlgoAPI_Section SecBuilder(aNewFace, aNewNeighborFace, Standard_False);
+          SecBuilder.Approximation(Standard_True);
+          SecBuilder.ComputePCurveOn1(Standard_True);
+          SecBuilder.ComputePCurveOn2(Standard_True);
+          SecBuilder.Build();
+          TopoDS_Shape aSection = SecBuilder.Shape();
+          Standard_Boolean Success = Standard_True;
+          TopExp_Explorer ExpSec(aSection, TopAbs_EDGE);
+          if (ExpSec.More())
+            aNewEdge = TopoDS::Edge(ExpSec.Current());
+          else //no intersection
+          {
+            cout<<endl<<"No intersecion => smooth edge"<<endl;
+            Success = Standard_False;
+          }
+          ExpSec.Next();
+          if (ExpSec.More())
+          {
+            cout<<endl<<"More than one intersecion => smooth edge"<<endl;
+            Success = Standard_False;
+          }
+          if (!Success) //a smooth edge with bigger angle
+          {
+            if (myFacePatchFace.Contains(aFace)) //project onto patch
+            {
+              UpdateEdgeByProjectionOfPCurve(anEdge, aNewFace, aBoundedNewFace);
+
+              //Remove neighbor face from <myFaceNewFace>
+              myFaceNewFace.Swap(myFaceNewFace.FindIndex(aNeighborFace), myFaceNewFace.Extent());
+              myFaceNewFace.RemoveLast();
+
+              myTangentEdges.Add(anEdge);
+              UpdatedConstEdges.Add(anEdge);
+            }
+            else
+            {
+              aNewEdge = MakeNewEdgeWithOldPcurvesOnNewSurfaces(anEdge,
+                                                                aFace, aBoundedNewFace,
+                                                                aNeighborFace, aBoundedNewNeighborFace);
+              myEdgeNewEdge.Bind(anEdge.Oriented(TopAbs_FORWARD), aNewEdge);
+            }
+            continue;
+          }
+          TopoDS_Vertex V1, V2;
+          TopExp::Vertices(aNewEdge, V1, V2);
+          aNewEdge.Free(Standard_True);
+          BB.Remove(aNewEdge, V1);
+          BB.Remove(aNewEdge, V2);
+          aNewEdge.Orientation(TopAbs_FORWARD);
+          
+          //Make pcurves on new surfaces
+          Handle(Geom2d_Curve) PCurve1 = BRep_Tool::CurveOnSurface(aNewEdge, aNewFace, fpar, lpar);
+          BB.UpdateEdge(aNewEdge, NullPCurve, aNewFace, 0.);
+          BB.UpdateEdge(aNewEdge, PCurve1, aBoundedNewFace, 0.);
+          Handle(Geom2d_Curve) PCurve2 = BRep_Tool::CurveOnSurface(aNewEdge, aNewNeighborFace, fpar, lpar);
+          BB.UpdateEdge(aNewEdge, NullPCurve, aNewNeighborFace, 0.);
+          BB.UpdateEdge(aNewEdge, PCurve2, aBoundedNewNeighborFace, 0.);
+          
+          //Check orientation of new edge
+          BRepAdaptor_Curve BAcurve(anEdge);
+          BRepAdaptor_Curve BAnewcurve(aNewEdge);
+          gp_Pnt FirstPnt, FirstNewPnt;
+          gp_Vec DirOnCurve, DirOnNewCurve;
+          BAcurve.D1(BAcurve.FirstParameter(), FirstPnt, DirOnCurve);
+          Standard_Real ParamOnNewEdge = BAnewcurve.FirstParameter();
+          Extrema_ExtPC Projector(FirstPnt, BAnewcurve);
+          if (!Projector.IsDone() || Projector.NbExt() == 0)
+          {
+            cout<<endl<<"Define orientation of new edge: extrema point-curve is not done"<<endl;
+          }
+          if (Projector.IsDone() && Projector.NbExt() > 0)
+          {
+            Standard_Integer indmin = 1;
+            for (Standard_Integer ind = 2; ind <= Projector.NbExt(); ind++)
+              if (Projector.SquareDistance(ind) < Projector.SquareDistance(indmin))
+                indmin = ind;
+            ParamOnNewEdge = Projector.Point(indmin).Parameter();
+          }
+          BAnewcurve.D1(ParamOnNewEdge, FirstNewPnt, DirOnNewCurve);
+          Standard_Real ScalProd = DirOnCurve * DirOnNewCurve;
+          if (ScalProd < 0.)
+            ToReverse = Standard_True;
+          
+          myEdgeNewEdge.Bind(anEdge.Oriented(TopAbs_FORWARD),
+                             (ToReverse)? aNewEdge.Oriented(TopAbs_REVERSED) : aNewEdge);
+        } //intersect
+        else //borders on constant face: change surface of pcurve on existing edge
+        {
+          Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, aFace, fpar, lpar);
+          //BB.UpdateEdge(anEdge, NullPCurve, aFace, 0.);
+          BB.UpdateEdge(anEdge, aPCurve, aBoundedNewFace, 0.);
+          
+          aNewEdge = anEdge;
+        }
+      } //for (; wexp.More(); wexp.Next())
+    } //for (; itf.More(); itf.Next())
+  } //for (Standard_Integer i = 1; i <= myFaceNewFace.Extent(); i++)
+
+  //Intersect edges and make new wires
+  for (Standard_Integer i = 1; i <= myFaceNewFace.Extent(); i++)
+  {
+    TopoDS_Face aFace = TopoDS::Face(myFaceNewFace.FindKey(i));
+    TopoDS_Shape aNewFace = myFaceNewFace(i);
+    TopoDS_Face aBoundedNewFace = TopoDS::Face(myNewFaceBoundedFace(aNewFace));
+    
+    TopoDS_Iterator itf(aFace);
+    for (; itf.More(); itf.Next())
+    {
+      const TopoDS_Wire& aWire = TopoDS::Wire(itf.Value());
+      TopAbs_Orientation aWireOr = aWire.Orientation();
+      
+      TopoDS_Wire aNewWire;
+      BB.MakeWire(aNewWire);
+      
+      TopoDS_Wire F_Wire = TopoDS::Wire(aWire.Oriented(TopAbs_FORWARD));
+      BRepTools_WireExplorer wexp(F_Wire, aFace);
+      TopoDS_Vertex CurVertex = wexp.CurrentVertex();
+      TopoDS_Edge   FirstEdge = wexp.Current();
+      TopoDS_Edge   FirstNewEdge = FirstEdge;
+      if (myOrientedEdgeNewEdge.IsBound(FirstEdge))
+        FirstNewEdge = TopoDS::Edge(myOrientedEdgeNewEdge(FirstEdge));
+      else if (myEdgeNewEdge.IsBound(FirstEdge))
+        FirstNewEdge = TopoDS::Edge(myEdgeNewEdge(FirstEdge));
+      TopoDS_Edge CurEdge, PrevEdge = FirstEdge;
+      TopoDS_Edge CurNewEdge, PrevNewEdge = FirstNewEdge;
+      wexp.Next();
+      if (!wexp.More() && //only one edge in wire
+          !myVertexNewVertex.IsBound(CurVertex))
+      {
+        TopoDS_Vertex CurNewVertex;
+        if (myVertexNewVertex.IsBound(CurVertex))
+          CurNewVertex = TopoDS::Vertex(myVertexNewVertex(CurVertex));
+
+        if (myEdgeNewEdge.IsBound(FirstEdge))//new edge: update
+        {
+          Standard_Real fpar, lpar;
+          BRep_Tool::Range(FirstEdge, fpar, lpar);
+          BB.Range(FirstNewEdge, fpar, lpar);
+          BRepAdaptor_Curve BAcurve(FirstNewEdge);
+          gp_Pnt FirstPnt = BAcurve.Value(BAcurve.FirstParameter());
+          if (CurNewVertex.IsNull())
+            CurNewVertex = BRepLib_MakeVertex(FirstPnt);
+          BB.Add(FirstNewEdge, CurNewVertex);
+          BB.Add(FirstNewEdge, CurNewVertex.Oriented(TopAbs_REVERSED));
+          myVertexNewVertex.Bind(CurVertex, CurNewVertex);
+        }
+      }
+      for (; wexp.More(); wexp.Next())
+      {
+        CurEdge = wexp.Current();
+        if (myOrientedEdgeNewEdge.IsBound(CurEdge))
+          CurNewEdge = TopoDS::Edge(myOrientedEdgeNewEdge(CurEdge));
+        else if (myEdgeNewEdge.IsBound(CurEdge))
+          CurNewEdge = TopoDS::Edge(myEdgeNewEdge(CurEdge));
+        else
+          CurNewEdge = CurEdge;
+        CurVertex = wexp.CurrentVertex();
+        UpdateEdgesAndVertex(PrevEdge, PrevNewEdge,
+                             CurEdge, CurNewEdge,
+                             CurVertex);
+        if (!PrevEdge.IsSame(PrevNewEdge) &&
+            PrevEdge.Orientation() == TopAbs_REVERSED)
+          PrevNewEdge.Reverse();
+        BB.Add(aNewWire, PrevNewEdge);
+        
+        PrevEdge = CurEdge;
+        PrevNewEdge = CurNewEdge;
+      }
+      CurEdge = FirstEdge;
+      CurNewEdge = FirstNewEdge;
+      CurVertex = wexp.CurrentVertex();
+      UpdateEdgesAndVertex(PrevEdge, PrevNewEdge,
+                           CurEdge, CurNewEdge,
+                           CurVertex);
+      if (!PrevEdge.IsSame(PrevNewEdge) &&
+          PrevEdge.Orientation() == TopAbs_REVERSED)
+        PrevNewEdge.Reverse();
+      BB.Add(aNewWire, PrevNewEdge);
+
+      aNewWire.Orientation(aWireOr);
+      BB.Add(aBoundedNewFace, aNewWire);
+    } //for (; itf.More(); itf.Next()) (iterator on face)
+  }
+
+  //Assemble resulting shape
+  TopoDS_Solid aSolid;
+  BB.MakeSolid(aSolid);
+  TopoDS_Shell aShell;
+  BB.MakeShell(aShell);
+  TopExp_Explorer Explo(myInitialShape, TopAbs_FACE);
+  for (; Explo.More(); Explo.Next())
+  {
+    const TopoDS_Shape& aFace = Explo.Current();
+    TopoDS_Shape aBoundedNewFace;
+    if (myFaceNewFace.Contains(aFace))
+    {
+      const TopoDS_Shape& aNewFace = myFaceNewFace.FindFromKey(aFace);
+      aBoundedNewFace = myNewFaceBoundedFace(aNewFace);
+      if (aFace.Orientation() == TopAbs_REVERSED)
+        aBoundedNewFace.Reverse();
+    }
+    else
+      aBoundedNewFace = aFace;
+    BB.Add(aShell, aBoundedNewFace);
+  }
+  BB.Add(aSolid, aShell);
+
+  ShapeFix_Shape Fixer(aSolid);
+  Fixer.Perform();
+  
+  myShape = Fixer.Shape();
+  //myShape = aSolid;
+  
+  Done();
+}
+
+void BRepOffsetAPI_PatchFaces::UpdateEdgesAndVertex(const TopoDS_Edge& thePrevEdge,
+                                                    TopoDS_Edge&       thePrevNewEdge,
+                                                    const TopoDS_Edge& theCurEdge,
+                                                    TopoDS_Edge&       theCurNewEdge,
+                                                    TopoDS_Vertex&     theCurVertex)
+{
+  BRep_Builder BB;
+  
+  TopoDS_Vertex CurNewVertex;
+  if (myVertexNewVertex.IsBound(theCurVertex))
+    CurNewVertex = TopoDS::Vertex(myVertexNewVertex(theCurVertex));
+  else
+  {
+    Standard_Boolean IsConstVertex = (!(myEdgeNewEdge.IsBound(thePrevEdge) || myOrientedEdgeNewEdge.IsBound(thePrevEdge)) ||
+                                     !(myEdgeNewEdge.IsBound(theCurEdge)  || myOrientedEdgeNewEdge.IsBound(theCurEdge)));
+    if (IsConstVertex)
+      CurNewVertex = theCurVertex;
+  }
+
+  Standard_Boolean IsSeamPrev = (myOrientedEdgeNewEdge.IsBound(thePrevEdge));
+  Standard_Boolean IsSeamCur  = (myOrientedEdgeNewEdge.IsBound(theCurEdge));
+  
+  if ((myEdgeNewEdge.IsBound(thePrevEdge) || myOrientedEdgeNewEdge.IsBound(thePrevEdge)) &&
+      (myEdgeNewEdge.IsBound(theCurEdge)  || myOrientedEdgeNewEdge.IsBound(theCurEdge))) //two new edges: intersect
+  {
+    Standard_Real ParamOnPrev, ParamOnCur, TolProj;
+    gp_Pnt PntOnPrev, PntOnCur;
+    ProjectVertexOnNewEdge(theCurVertex, thePrevEdge, thePrevNewEdge,
+                           ParamOnPrev, PntOnPrev, TolProj);
+    ProjectVertexOnNewEdge(theCurVertex, theCurEdge, theCurNewEdge,
+                           ParamOnCur, PntOnCur, TolProj);
+
+    Standard_Real TolReached;
+    gp_Pnt PntVtx = (CurNewVertex.IsNull())?
+      BRep_Tool::Pnt(theCurVertex) : BRep_Tool::Pnt(CurNewVertex);
+    TolReached = PntOnPrev.Distance(PntOnCur);
+    Standard_Real DistVtoPrev = PntVtx.Distance(PntOnPrev);
+    Standard_Real DistVtoCur = PntVtx.Distance(PntOnCur);
+    TolReached = Max(TolReached, DistVtoPrev);
+    TolReached = Max(TolReached, DistVtoCur);
+    
+    BRepExtrema_ExtCC ExtrEE(thePrevNewEdge, theCurNewEdge);
+    if (!ExtrEE.IsDone() || ExtrEE.NbExt() == 0)
+    {
+      cout<<endl<<"Extrema EE is not done"<<endl;
+    }
+    else
+    {
+      Standard_Integer imin = 1;
+      for (Standard_Integer iext = 2; iext <= ExtrEE.NbExt(); iext++)
+        if (ExtrEE.SquareDistance(iext) < ExtrEE.SquareDistance(imin))
+          imin = iext;
+      Standard_Real TolEE  = sqrt(ExtrEE.SquareDistance(imin));
+      gp_Pnt PntOnE1 = ExtrEE.PointOnE1(imin);
+      gp_Pnt PntOnE2 = ExtrEE.PointOnE2(imin);
+      Standard_Real DistVtoE1 = PntVtx.Distance(PntOnE1);
+      Standard_Real DistVtoE2 = PntVtx.Distance(PntOnE2);
+      TolEE = Max(TolEE, DistVtoE1);
+      TolEE = Max(TolEE, DistVtoE2);
+      if (TolEE < TolReached)
+      {
+        TolReached = TolEE;
+        PntOnPrev = PntOnE1;
+        PntOnCur  = PntOnE2;
+        ParamOnPrev = ExtrEE.ParameterOnE1(imin);
+        ParamOnCur  = ExtrEE.ParameterOnE2(imin);
+      }
+    }
+    if (CurNewVertex.IsNull())
+    {
+      gp_Pnt NewPnt((PntOnPrev.XYZ() + PntOnCur.XYZ())/2);
+      CurNewVertex = BRepLib_MakeVertex(NewPnt);
+      myVertexNewVertex.Bind(theCurVertex, CurNewVertex);
+    }
+    BB.UpdateVertex(CurNewVertex, TolReached);
+    if (!EdgeContains(thePrevNewEdge, CurNewVertex))
+    {
+      if (IsSeamCur)
+        ParamOnPrev = RealLast();
+      PutVertexToEdge(CurNewVertex, theCurVertex, thePrevNewEdge, thePrevEdge, ParamOnPrev);
+    }
+    
+    if (!EdgeContains(theCurNewEdge, CurNewVertex))
+    {
+      if (IsSeamPrev)
+        ParamOnCur = RealLast();
+      PutVertexToEdge(CurNewVertex, theCurVertex, theCurNewEdge, theCurEdge, ParamOnCur);
+    }
+  } //two new edges: intersect
+  else if ((myEdgeNewEdge.IsBound(thePrevEdge) || myOrientedEdgeNewEdge.IsBound(thePrevEdge)) ||
+           (myEdgeNewEdge.IsBound(theCurEdge)  || myOrientedEdgeNewEdge.IsBound(theCurEdge))) //one constant edge: project point onto curve
+  {
+    TopoDS_Edge ConstantEdge, ModifiedEdge, NewEdge;
+    Standard_Boolean IsAdjacentSeam;
+    if (myEdgeNewEdge.IsBound(thePrevEdge) || myOrientedEdgeNewEdge.IsBound(thePrevEdge))
+    {
+      ConstantEdge = theCurEdge;
+      ModifiedEdge = thePrevEdge;
+      NewEdge = thePrevNewEdge;
+      IsAdjacentSeam = IsSeamCur;
+    }
+    else
+    {
+      ConstantEdge = thePrevEdge;
+      ModifiedEdge = theCurEdge;
+      NewEdge = theCurNewEdge;
+      IsAdjacentSeam = IsSeamPrev;
+    }
+
+    Standard_Real ParamOnNewEdge, TolReached;
+    gp_Pnt PntOnNewEdge;
+    ProjectVertexOnNewEdge(theCurVertex, ModifiedEdge, NewEdge,
+                           ParamOnNewEdge, PntOnNewEdge, TolReached);
+    BB.UpdateVertex(theCurVertex, TolReached);
+
+    if (!EdgeContains(NewEdge, theCurVertex))
+      PutVertexToEdge(theCurVertex, theCurVertex, NewEdge, ModifiedEdge, ParamOnNewEdge);
+  } //else (one constant edge: project point onto curve)
+  else //two constant edges
+  {
+    //nothing ?
+  }
+}
+
+
+void BRepOffsetAPI_PatchFaces::PutVertexToEdge(const TopoDS_Vertex& theVertex,
+                                               const TopoDS_Vertex& theProVertex,
+                                               TopoDS_Edge& theEdge,
+                                               const TopoDS_Edge& theProEdge,
+                                               const Standard_Real theParamOnEdge)
+{
+  BRep_Builder BB;
+  
+  TopAbs_Orientation anOr = OrientationInEdge(theProVertex, theProEdge);
+  if (myEdgeNewEdge.IsBound(theProEdge) &&
+      myEdgeNewEdge(theProEdge).Orientation() == TopAbs_REVERSED)
+    anOr = TopAbs::Reverse(anOr);
+
+  TopoDS_Shape F_Edge = theEdge.Oriented(TopAbs_FORWARD);
+  F_Edge.Free(Standard_True);
+  BB.Add(F_Edge, theVertex.Oriented(anOr));
+  if (!Precision::IsInfinite(theParamOnEdge))
+  {
+    Standard_Real fpar, lpar;
+    BRep_Tool::Range(theEdge, fpar, lpar);
+    if (anOr == TopAbs_FORWARD)
+      BB.Range(theEdge, theParamOnEdge, lpar);
+    else
+      BB.Range(theEdge, fpar, theParamOnEdge);
+  }
+}
diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.hxx b/src/BRepOffsetAPI/BRepOffsetAPI_PatchFaces.hxx
new file mode 100644 (file)
index 0000000..31d205b
--- /dev/null
@@ -0,0 +1,99 @@
+// Created on: 2012-08-06
+// Created by: jgv@ROLEX
+// Copyright (c) 2012-2014 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#ifndef _BRepOffsetAPI_PatchFaces_HeaderFile
+#define _BRepOffsetAPI_PatchFaces_HeaderFile
+
+#include <Standard.hxx>
+#include <Standard_DefineAlloc.hxx>
+#include <Standard_Handle.hxx>
+
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <Standard_Boolean.hxx>
+#include <TopTools_IndexedDataMapOfShapeShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_DataMapOfOrientedShapeShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <BRepBuilderAPI_MakeShape.hxx>
+class TopoDS_Shape;
+
+
+//! Describes functions to replace some faces in a shape
+//! by patches
+class BRepOffsetAPI_PatchFaces  : public BRepBuilderAPI_MakeShape
+{
+public:
+
+  DEFINE_STANDARD_ALLOC
+
+  
+  //! General constructor.
+  Standard_EXPORT BRepOffsetAPI_PatchFaces(const TopoDS_Shape& aShape);
+  
+  //! Adds the patch face for the face in the shape.
+  Standard_EXPORT void AddPatchFace (const TopoDS_Face& theFace, const TopoDS_Face& thePatchFace);
+  
+  Standard_EXPORT virtual void Build() Standard_OVERRIDE;
+
+
+
+
+protected:
+
+
+
+
+
+private:
+
+
+  Standard_EXPORT void UpdateEdgesAndVertex(const TopoDS_Edge& thePrevEdge,
+                                            TopoDS_Edge&       thePrevNewEdge,
+                                            const TopoDS_Edge& theCurEdge,
+                                            TopoDS_Edge&       theCurNewEdge,
+                                            TopoDS_Vertex&     theCurVertex);
+  
+  Standard_EXPORT void PutVertexToEdge(const TopoDS_Vertex& theVertex,
+                                       const TopoDS_Vertex& theProVertex,
+                                       TopoDS_Edge& theEdge,
+                                       const TopoDS_Edge& theProEdge,
+                                       const Standard_Real theParamOnEdge);
+  
+
+  TopoDS_Shape myInitialShape;
+  
+  TopTools_IndexedDataMapOfShapeShape myFacePatchFace;
+  TopTools_IndexedDataMapOfShapeShape myFaceNewFace;
+  TopTools_DataMapOfShapeShape myNewFaceBoundedFace;
+  TopTools_DataMapOfShapeShape myEdgeNewEdge;
+  TopTools_DataMapOfOrientedShapeShape myOrientedEdgeNewEdge;
+  TopTools_DataMapOfShapeShape myVertexNewVertex;
+  TopTools_MapOfShape myTangentEdges;
+
+  TopTools_IndexedDataMapOfShapeListOfShape myEFmap;
+
+};
+
+
+
+
+
+
+
+#endif // _BRepOffsetAPI_PatchFaces_HeaderFile
index 4680ffd1092c65249183a8269efbb8f608490b61..0d84a8f527c3c5d80d0b23b144d84bffe5cfb698 100644 (file)
@@ -27,3 +27,5 @@ BRepOffsetAPI_SequenceOfSequenceOfShape.hxx
 BRepOffsetAPI_Sewing.hxx
 BRepOffsetAPI_ThruSections.cxx
 BRepOffsetAPI_ThruSections.hxx
+BRepOffsetAPI_PatchFaces.cxx
+BRepOffsetAPI_PatchFaces.hxx
index a7431744c2ad8d72365fbf8de10029242ebf7d2e..d27354fe3908a8eca27a5ad1c0ef265a7efc6e49 100644 (file)
@@ -54,6 +54,8 @@
 #include <LocOpe_FindEdges.hxx>
 #include <LocOpe_FindEdgesInFace.hxx>
 
+#include <BRepOffsetAPI_PatchFaces.hxx>
+
 #include <BRepOffsetAPI_MakeOffsetShape.hxx>
 #include <BRepOffsetAPI_MakeThickSolid.hxx>
 #include <BRep_Tool.hxx>
@@ -2249,6 +2251,35 @@ static Standard_Integer BOSS(Draw_Interpretor& theCommands,
   return 1;
 }
 
+//=======================================================================
+//function : patchfaces
+//purpose  :
+//=======================================================================
+static Standard_Integer patchfaces(Draw_Interpretor& /*di*/,
+                                  Standard_Integer n, const char** a)
+{
+  if (n < 5) return 1;
+
+  TopoDS_Shape aShape = DBRep::Get(a[2]);
+  if (aShape.IsNull()) return 1;
+
+  TopoDS_Shape aLocalFace   = DBRep::Get(a[3], TopAbs_FACE);
+  if (aLocalFace.IsNull()) return 1;
+  TopoDS_Face aFace = TopoDS::Face(aLocalFace);
+  
+  TopoDS_Shape aLocalNewFace   = DBRep::Get(a[4], TopAbs_FACE);
+  if (aLocalNewFace.IsNull()) return 1;
+  TopoDS_Face aNewFace = TopoDS::Face(aLocalNewFace);
+
+  BRepOffsetAPI_PatchFaces Builder(aShape);
+  Builder.AddPatchFace(aFace, aNewFace);
+  Builder.Build();
+
+  TopoDS_Shape Result = Builder.Shape();
+  DBRep::Set(a[1], Result);
+
+  return 0;
+}
 
 //=======================================================================
 //function : FeatureCommands
@@ -2395,4 +2426,6 @@ void BRepTest::FeatureCommands (Draw_Interpretor& theCommands)
                  " Perform fillet on top and bottom edges of dprism :bossage dprism result radtop radbottom First/LastShape (1/2)",
                  __FILE__,BOSS);
 
+  theCommands.Add("patchfaces", "patchfaces res shape face newface",
+                 __FILE__,patchfaces,g);
 }
index ff63bbe973965cc24989ef86cd642fe008eeca47..b011b50c7c112d4084058f04124e392138ad9a59 100644 (file)
@@ -99,7 +99,55 @@ void  TopExp::MapShapesAndAncestors
   }
 }
 
+//=======================================================================
+//function : MapShapesAndUniqueAncestors
+//purpose  : 
+//=======================================================================
 
+void  TopExp::MapShapesAndUniqueAncestors
+  (const TopoDS_Shape& S, 
+   const TopAbs_ShapeEnum TS, 
+   const TopAbs_ShapeEnum TA, 
+   TopTools_IndexedDataMapOfShapeListOfShape& M,
+   const Standard_Boolean useOrientation)
+{
+  TopTools_ListOfShape empty;
+  
+  // visit ancestors
+  TopExp_Explorer exa(S,TA);
+  while (exa.More())
+  {
+    // visit shapes
+    const TopoDS_Shape& anc = exa.Current();
+    TopExp_Explorer exs(anc,TS);
+    while (exs.More())
+    {
+      Standard_Integer index = M.FindIndex(exs.Current());
+      if (index == 0)
+        index = M.Add(exs.Current(),empty);
+      TopTools_ListOfShape& aList = M(index);
+      // check if anc already exists in a list
+      TopTools_ListIteratorOfListOfShape it(aList);
+      for (; it.More(); it.Next())
+        if (useOrientation? anc.IsEqual(it.Value()) : anc.IsSame(it.Value()))
+          break;
+      if (!it.More())
+        aList.Append(anc);
+      exs.Next();
+    }
+    exa.Next();
+  }
+
+  // visit shapes not under ancestors
+  TopExp_Explorer ex(S,TS,TA);
+  while (ex.More())
+  {
+    Standard_Integer index = M.FindIndex(ex.Current());
+    if (index == 0) 
+      M.Add(ex.Current(),empty);
+    ex.Next();
+  }
+}
 
 //=======================================================================
 //function : FirstVertex
index 25ccde43b8a790e671185aaadc880610bb8cdab4..34e45eee4abae6857ef5e3b186c70f65c386c73a 100644 (file)
@@ -66,6 +66,18 @@ public:
   //! Warning: The map is not cleared at first.
   Standard_EXPORT static void MapShapesAndAncestors (const TopoDS_Shape& S, const TopAbs_ShapeEnum TS, const TopAbs_ShapeEnum TA, TopTools_IndexedDataMapOfShapeListOfShape& M);
   
+  //! Stores in the map <M> all the subshape of <S> of
+  //! type <TS> for each one append to the list all
+  //! unique ancestors of type <TA>.  For example map all
+  //! the edges and bind the list of faces.
+  //! useOrientation = True : taking account the ancestor orientation
+  //! Warning: The map is not cleared at first.
+  Standard_EXPORT static void MapShapesAndUniqueAncestors (const TopoDS_Shape& S,
+                                                           const TopAbs_ShapeEnum TS,
+                                                           const TopAbs_ShapeEnum TA,
+                                                           TopTools_IndexedDataMapOfShapeListOfShape& M,
+                                                           const Standard_Boolean useOrientation = Standard_False);
+
   //! Returns the Vertex of orientation FORWARD in E. If
   //! there is none returns a Null Shape.
   //! CumOri = True : taking account the edge orientation
diff --git a/tests/patchfaces/begin b/tests/patchfaces/begin
new file mode 100644 (file)
index 0000000..ed01a4a
--- /dev/null
@@ -0,0 +1,23 @@
+# To prevent loops limit to 10 minutes
+cpulimit 100
+if { [array get Draw_Groups "TOPOLOGY Feature commands"] == "" } {
+    pload TOPTEST
+}
+if { [array get Draw_Groups "Shape Healing"] == "" } {
+    pload XSDRAW
+}
+if { [info exists imagedir] == 0 } {
+   set imagedir .
+}
+if { [info exists test_image ] == 0 } {
+   set test_image photo
+}
+proc PATCHFACES {i} {
+  uplevel #0 binrestore [locate_data_file shape_3_$i.bin] s
+  uplevel #0 tclean s
+  uplevel #0 removeloc s s
+  uplevel #0 explode s
+  uplevel #0 tcopy s_1 InitShape
+  
+  uplevel #0 patchfaces result s_1 s_2 s_3
+}
diff --git a/tests/patchfaces/end b/tests/patchfaces/end
new file mode 100644 (file)
index 0000000..73b3acd
--- /dev/null
@@ -0,0 +1 @@
+puts "TEST COMPLETED"
diff --git a/tests/patchfaces/grids.list b/tests/patchfaces/grids.list
new file mode 100644 (file)
index 0000000..55dee65
--- /dev/null
@@ -0,0 +1 @@
+001 replace
diff --git a/tests/patchfaces/parse.rules b/tests/patchfaces/parse.rules
new file mode 100644 (file)
index 0000000..95a9392
--- /dev/null
@@ -0,0 +1,2 @@
+FAILED /\bFaulty\b/ bad shape
+OK /Relative error of mass computation/ message from vprops
\ No newline at end of file
diff --git a/tests/patchfaces/replace/end b/tests/patchfaces/replace/end
new file mode 100644 (file)
index 0000000..4e1132d
--- /dev/null
@@ -0,0 +1,2 @@
+checkshape result
+checkview -display result -2d -path ${imagedir}/${test_image}.png
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_1 b/tests/patchfaces/replace/test_1
new file mode 100644 (file)
index 0000000..9fc4b85
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 1
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_10 b/tests/patchfaces/replace/test_10
new file mode 100644 (file)
index 0000000..4089cf8
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 10
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_11 b/tests/patchfaces/replace/test_11
new file mode 100644 (file)
index 0000000..a40a9b3
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 11
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_12 b/tests/patchfaces/replace/test_12
new file mode 100644 (file)
index 0000000..0b094e3
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 12
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_13 b/tests/patchfaces/replace/test_13
new file mode 100644 (file)
index 0000000..8fcfcd3
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 13
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_14 b/tests/patchfaces/replace/test_14
new file mode 100644 (file)
index 0000000..247d491
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 14
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_15 b/tests/patchfaces/replace/test_15
new file mode 100644 (file)
index 0000000..75b75d0
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 15
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_16 b/tests/patchfaces/replace/test_16
new file mode 100644 (file)
index 0000000..2e9d2ae
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 16
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_17 b/tests/patchfaces/replace/test_17
new file mode 100644 (file)
index 0000000..5376273
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 17
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_18 b/tests/patchfaces/replace/test_18
new file mode 100644 (file)
index 0000000..d15b5ab
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 18
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_19 b/tests/patchfaces/replace/test_19
new file mode 100644 (file)
index 0000000..58b5d2c
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 19
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_2 b/tests/patchfaces/replace/test_2
new file mode 100644 (file)
index 0000000..7c6e6e6
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 2
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_20 b/tests/patchfaces/replace/test_20
new file mode 100644 (file)
index 0000000..4c8a8ba
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 20
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_21 b/tests/patchfaces/replace/test_21
new file mode 100644 (file)
index 0000000..31ff03b
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 21
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_22 b/tests/patchfaces/replace/test_22
new file mode 100644 (file)
index 0000000..1472cf0
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 22
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_23 b/tests/patchfaces/replace/test_23
new file mode 100644 (file)
index 0000000..43e9544
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 23
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_24 b/tests/patchfaces/replace/test_24
new file mode 100644 (file)
index 0000000..bab8108
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 24
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_25 b/tests/patchfaces/replace/test_25
new file mode 100644 (file)
index 0000000..d11d3b5
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 25
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_26 b/tests/patchfaces/replace/test_26
new file mode 100644 (file)
index 0000000..0af9759
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 26
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_27 b/tests/patchfaces/replace/test_27
new file mode 100644 (file)
index 0000000..defa2b0
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 27
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_28 b/tests/patchfaces/replace/test_28
new file mode 100644 (file)
index 0000000..7da11d2
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 28
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_29 b/tests/patchfaces/replace/test_29
new file mode 100644 (file)
index 0000000..f16ed03
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 29
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_3 b/tests/patchfaces/replace/test_3
new file mode 100644 (file)
index 0000000..2db0a20
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 3
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_30 b/tests/patchfaces/replace/test_30
new file mode 100644 (file)
index 0000000..d07f306
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 30
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_31 b/tests/patchfaces/replace/test_31
new file mode 100644 (file)
index 0000000..b8ef5b5
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 31
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_32 b/tests/patchfaces/replace/test_32
new file mode 100644 (file)
index 0000000..c531a68
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 32
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_33 b/tests/patchfaces/replace/test_33
new file mode 100644 (file)
index 0000000..5ddf951
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 33
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_34 b/tests/patchfaces/replace/test_34
new file mode 100644 (file)
index 0000000..8f81bc0
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 34
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_35 b/tests/patchfaces/replace/test_35
new file mode 100644 (file)
index 0000000..cc9e8b6
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 35
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_4 b/tests/patchfaces/replace/test_4
new file mode 100644 (file)
index 0000000..4cf50d2
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 4
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_5 b/tests/patchfaces/replace/test_5
new file mode 100644 (file)
index 0000000..9436e03
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 5
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_6 b/tests/patchfaces/replace/test_6
new file mode 100644 (file)
index 0000000..447f5d0
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 6
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_7 b/tests/patchfaces/replace/test_7
new file mode 100644 (file)
index 0000000..19d9434
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 7
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_8 b/tests/patchfaces/replace/test_8
new file mode 100644 (file)
index 0000000..8386ba1
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 8
\ No newline at end of file
diff --git a/tests/patchfaces/replace/test_9 b/tests/patchfaces/replace/test_9
new file mode 100644 (file)
index 0000000..75af863
--- /dev/null
@@ -0,0 +1 @@
+PATCHFACES 9
\ No newline at end of file